BigInt Mapping

By default all integer types map to number. Use bigint_types to map large integer types to bigint instead.

toml
# metaxy.config.toml
[codegen]
bigint_types = ["i64", "u64", "i128", "u128"]

or via CLI

sh
metaxy generate --bigint-type i64 --bigint-type u64

Before / After

ts
// Default: all integer types map to number
export interface Stats {
  total_users: number;   // u64 → number
  total_bytes: number;   // i64 → number
}
ts
// 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:

ts
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.

JSON.parse vs lossless-json

visit GitHub to learn more about metaxy