BigInt Mapping
By default all integer types map to number. Use bigint_types to map large integer types to bigint instead.
# metaxy.config.toml
[codegen]
bigint_types = ["i64", "u64", "i128", "u128"]or via CLI
metaxy generate --bigint-type i64 --bigint-type u64Before / After
// Default: all integer types map to number
export interface Stats {
total_users: number; // u64 → number
total_bytes: number; // i64 → number
}// With bigint_types = ["i64", "u64"]
export interface Stats {
total_users: bigint; // u64 → bigint
total_bytes: bigint; // i64 → bigint
}Custom deserializer
The generated client accepts a deserialize option. Plug in a BigInt-aware JSON parser so large numbers arrive as native BigInt at runtime:
import { parse, parseNumberAndBigInt } from 'lossless-json';
const client = createRpcClient({
baseUrl: '/api',
deserialize: (text) =>
parse(text, undefined, parseNumberAndBigInt),
});
// Safe integers stay as number, large ones become BigInt
const res = await client.query('bigint_demo');
typeof res.values[0].as_number; // "number" (42)
typeof res.values[3].as_number; // "bigint" (u64::MAX)Why BigInt?
JavaScript number is a 64-bit float (IEEE 754), which can only safely represent integers
up to 253 − 1 (Number.MAX_SAFE_INTEGER = 9,007,199,254,740,991). Rust's i64/u64 can exceed this range, causing silent precision loss. Using bigint avoids this entirely.
Commonly mapped types: i64, u64, i128, u128. Smaller types like i32 and u32 are safe as number and rarely need mapping.
Try it
Both clients call the same endpoint. The default client uses JSON.parse which silently loses precision on large integers. The lossless client plugs lossless-json into the deserialize option — large numbers arrive as native BigInt.