Skip to Content

typia.json.*Stringify — JSON.stringify, but much faster (and type-safe)

JSON.stringify(value) is general-purpose: it walks the value at runtime, asking each property “are you a number? a string? an array?”. typia replaces that runtime walk with a hand-written stringifier generated from the TypeScript type at compile time. The result is up to ~10× faster than JSON.stringify — and, because the stringifier only knows how to serialize T, you can also opt into validating T before serialization.

signatures
namespace json { function stringify<T>(input: T): string; // dedicated stringifier function isStringify<T>(input: T | unknown): string | null; // is + stringify function assertStringify<T>(input: T | unknown): string; // assert + stringify function validateStringify<T>(input: T | unknown): IValidation<string>; // validate + stringify }

First example

hello-stringify.ts
import typia from "typia"; interface User { id: string; age: number; hobbies: string[]; } const text: string = typia.json.stringify<User>({ id: "1", age: 25, hobbies: ["reading"], }); // → '{"id":"1","age":25,"hobbies":["reading"]}'

The output is identical to JSON.stringify({ id, age, hobbies }). The speed comes from the compiled code: instead of “for each property, dispatch to the right encoder,” the emitted JS just concatenates strings in the order your type declares.

Variants

FunctionValidates input?On failure
json.stringify<T>Noundefined behavior (don’t pass wrong-typed values)
json.isStringify<T>Yes (is)returns null
json.assertStringify<T>Yes (assert)throws TypeGuardError
json.validateStringify<T>Yes (validate)returns IValidation<string>
Caution

json.stringify<T> skips validation by design.

The generated code assumes its input already matches T. If you hand it a wrong-typed value, the output will be garbage (missing fields, fields with the wrong contents). Use it only when the type of the input is statically guaranteed — for example, you just built the object inside the same function. Otherwise, pick isStringify / assertStringify / validateStringify.

examples/src/json/isStringify.ts
import typia, { tags } from "typia"; const department: IDepartment = typia.random<IDepartment>(); const json: string | null = typia.json.isStringify(department); console.log(json); // not null, but string interface IDepartment { id: string & tags.Format<"uuid">; name: string & tags.MinLength<3>; limit: number & tags.Type<"int32">; clerks: IClerk[]; } interface IClerk { name: string; age: number & tags.Type<"uint32"> & tags.ExclusiveMinimum<19> & tags.Maximum<100>; authority: number; joined_at: string & tags.Format<"date">; }

undefined

export namespace json { export function stringify<T>(input: T): string; export function isStringify<T>(input: T | unknown): string | null; export function assertStringify<T>(input: T | unknown): string; export function validateStringify<T>(input: T | unknown): IValidation<string>; }

Reusable factories

Same shape as the parsers — hoist the per-type code once if you stringify the same T from many places:

const stringifyUser = typia.json.createStringify<User>(); const safeStringifyUser = typia.json.createAssertStringify<User>();
examples/src/json/createAssertStringify.ts
import typia, { tags } from "typia"; export const assertDepartment = typia.json.createAssertStringify<IDepartment>(); interface IDepartment { id: string & tags.Format<"uuid">; name: string & tags.MinLength<3>; limit: number & tags.Type<"int32">; clerks: IClerk[]; } interface IClerk { name: string; age: number & tags.Type<"uint32"> & tags.ExclusiveMinimum<19> & tags.Maximum<100>; authority: number; joined_at: string & tags.Format<"date">; }

Performance

Up to ~200× faster than class-transformer, ~10× faster than native JSON.stringify:

Stringify Function Benchmark

Measured on AMD Ryzen 9 7940HS, Rog Flow x13 

Server impact

A common reaction: “isn’t JSON serialization a tiny fraction of request time?”

It’s not. Node.js handles most I/O asynchronously, but JSON.stringify is synchronous and runs on the main thread. While it’s running, no other request is being routed, no socket is being read, nothing else happens. On a busy server, that synchronous time is the cost you actually pay.

typia.json.stringify cuts that time substantially. The end-to-end request benchmark below shows the difference at server scope (not just the serializer in isolation):

Server Benchmark

Measured on AMD Ryzen 9 7940HS, Rog Flow x13 

Where to go next

Last updated on