v1.8 · MIT · zero dependencies

Serialize whatJSON can't.

seroval turns any JavaScript value into a string and back: cyclic references, Date, Map, Set, BigInt, Promise, ReadableStream. Output as a JS expression, a JSON tree, or a stream.

Read the docs →
graph0 B
serialize(user)
Scroll
Date·Map·Set·BigInt·RegExp·Error·AggregateError·Promise·ArrayBuffer·Uint8Array·DataView·AsyncIterable·NaN·−0·Infinity·undefined·Temporal·URL·Headers·FormData·Blob·File·Request·Response·ReadableStream·Date·Map·Set·BigInt·RegExp·Error·AggregateError·Promise·ArrayBuffer·Uint8Array·DataView·AsyncIterable·NaN·−0·Infinity·undefined·Temporal·URL·Headers·FormData·Blob·File·Request·Response·ReadableStream·
x.self = x // new Map([[k, v]]) // Object.create(null) // [ , , 1] // Symbol.asyncIterator // await fetch() // new Uint8Array(8) // /ab+c/gi // 9007199254740993n // x.self = x // new Map([[k, v]]) // Object.create(null) // [ , , 1] // Symbol.asyncIterator // await fetch() // new Uint8Array(8) // /ab+c/gi // 9007199254740993n //
01 LOSSLESS

JSON.stringify drops data. serialize keeps it.

Each row below runs live in your browser: the left column is JSON.stringify, the right is serialize, both from the real libraries.

ValueJSON.stringifyseroval
new Date(0)"1970-01-01T00:00:00.000Z"becomes a stringnew Date("1970-01-01T00:00:00.000Z")
new Map([["a", 1]]){}entries droppednew Map([["a",1]])
new Set([1, 2]){}items droppednew Set([1,2])
{ x: undefined }{}key dropped({x:void 0})
[NaN, -0, Infinity][null,0,null]numbers changed[0/0,-0,1/0]
/ab+c/gi{}pattern lost/ab+c/gi
9007199254740993nTypeErrorDo not know how to serialize a BigInt9007199254740993n
new Error("boom"){}message lostnew Error("boom")
[, , 1][null,null,1]holes filled[,,1]
x.self = xTypeErrorConverting circular structure to JSON(h=>(h={name:"x"},h.self=h,h))()
02 STREAMING

Stream values as they resolve.

The synchronous part ships first. Promises follow the moment they settle. The page renders now and fills in later. Below, real chunks from crossSerializeStream.

Sserver
Cbrowser
user
posts — 1.2 s
recommended — 2.4 s
03 OUTPUT

Three output formats. Same references.

Pick the format that fits the wire. Same graph, same references, every time.

SizeNeeds evalRound-trip
04 USED BY
SolidJS/TanStack Start

Send more than JSON.