Skip to content
Effect Days 2026 Early bird tickets

SchemaBinary

A compact binary codec derived from the encoded side of a Schema.

The default wire format supports compatible schema evolution. An array of structs is written as a row run: rows declare their shape once and back-reference repeated strings, so both stay off the wire on later rows. Fingerprint mode uses positional layouts and rejects mismatches for smaller frames; its row shapes are presence masks instead of field id lists. Encoded results are arena-backed views; see toCodec for ownership details.

12 exports Added in v4.0.0 Source

Annotations

fieldId

Added in v4.0.0 Source

Assigns an explicit wire field id to a struct property.

Use this to preserve the wire id across a rename or resolve a hash collision. Valid ids are integers from 1 through 4294967295.

Signature

declare function fieldId(id: number): <S extends Top>(self: S) => S["Rebuild"]

Example

import { Schema } from "effect"
import { SchemaBinary } from "effect/unstable/encoding"
const Person = Schema.Struct({
id: Schema.String.pipe(SchemaBinary.fieldId(1))
})

Channels

decode

Added in v4.0.0 Source

Creates a channel that decodes chunks of binary frames into schema values.

Details

The channel keeps one frame parser for its lifetime: frames may be fragmented across chunks or concatenated within one, values completed before a failure remain observable, and a leftover incomplete frame fails when the upstream is done. Schemas with transformations run the schema pass per framed value, which supports async transformations and decoding services. Failures are Schema.SchemaError, matching toCodec.

Signature

declare function decode<S extends Constraint>(schema: S, options?: ParseOptions & Options & {
readonly maxFrameSize?: number;
}): <IE = never, Done = unknown>() => Channel<readonly [S["Type"], S["Type"]], SchemaError | IE, Done, readonly [Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>], IE, Done, S["DecodingServices"]>

duplex

Added in v4.0.0 Source

Wraps a bidirectional byte channel with schema-driven binary encoding and decoding.

Details

Values sent to the wrapped channel are encoded with inputSchema as binary frames; bytes received from it are decoded with outputSchema.

Signature

declare const duplex: {
<In extends Constraint, Out extends Constraint>(options: ParseOptions & Options & {
readonly inputSchema: In;
readonly maxFrameSize?: number;
readonly outputSchema: Out;
}): <OutErr, OutDone, InErr, InDone, R>(self: Channel<readonly [Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>], OutErr, OutDone, readonly [Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>], SchemaError | InErr, InDone, R>) => Channel<readonly [Out["Type"], Out["Type"]], SchemaError | OutErr, OutDone, readonly [In["Type"], In["Type"]], InErr, InDone, R | In["EncodingServices"] | Out["DecodingServices"]>;
<Out extends Constraint, In extends Constraint, OutErr, OutDone, InErr, InDone, R>(self: Channel<readonly [Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>], OutErr, OutDone, readonly [Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>], SchemaError | InErr, InDone, R>, options: ParseOptions & Options & {
readonly inputSchema: In;
readonly maxFrameSize?: number;
readonly outputSchema: Out;
}): Channel<readonly [Out["Type"], Out["Type"]], SchemaError | OutErr, OutDone, readonly [In["Type"], In["Type"]], InErr, InDone, R | In["EncodingServices"] | Out["DecodingServices"]>;
}

encode

Added in v4.0.0 Source

Creates a channel that encodes chunks of schema values into binary frames.

Details

Each input chunk is emitted as one byte element holding concatenated frames written in one writer pass, so a batch costs no more allocations than a single frame. Schemas with transformations first run one schema pass per chunk to the binary-adjusted encoded side — supporting async transformations and encoding services — before that writer pass. Failures are Schema.SchemaError, matching toCodec. maxFrameSize only applies to decode and is ignored here.

Signature

declare function encode<S extends Constraint>(schema: S, options?: ParseOptions & Options & {
readonly maxFrameSize?: number;
}): <IE = never, Done = unknown>() => Channel<readonly [Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>], SchemaError | IE, Done, readonly [S["Type"], S["Type"]], IE, Done, S["EncodingServices"]>

Constructors

encoder

Added in v4.0.0 Source

A writer for one connection. Every frame it produces shares the string dictionary that the matching parser rebuilds as it reads them, so the two have to be created from the same schema and the same options.

Signature

declare function encoder<S extends Constraint>(schema: S, options?: ParseOptions & Options & StreamOptions): Encoder

parser

Added in v4.0.0 Source

Creates a stateful parser for a stream of concatenated frames.

Values completed before a failure remain observable. After a failure, the parser rejects further calls. Use maxFrameSize to limit buffered frames.

Signature

declare function parser<S extends Constraint>(schema: S, options?: ParseOptions & Options & StreamOptions & {
readonly maxFrameSize?: number;
}): Parser<S["Type"]>

toCodec

Added in v4.0.0 Source

Derives a compact binary codec from a schema.

The wire layout is compiled from the encoded side of the schema. Each encode/decode handles exactly one frame; use parser for streams.

Encoded results are arena-backed views and may share a larger buffer. Use bytes.slice() when independent ownership is required.

Signature

declare function toCodec<S extends Constraint>(schema: S, options?: Options): toCodec<S>

Example

import { Schema } from "effect"
import { SchemaBinary } from "effect/unstable/encoding"
const Person = Schema.Struct({ name: Schema.String, age: Schema.Number })
const codec = SchemaBinary.toCodec(Person)
const bytes = Schema.encodeUnknownSync(codec)({ name: "Ada", age: 36 })
const person = Schema.decodeUnknownSync(codec)(bytes)

Models

Encoder interface

Added in v4.0.0 Source

The writer returned by encoder.

Signature

interface Encoder {
encode(value: unknown): Uint8Array<ArrayBuffer>;
encodeMany(values: readonly Array<unknown>): Uint8Array<ArrayBuffer>;
}

Options interface

Added in v4.0.0 Source

Selects the wire mode.

The default mode supports compatible schema evolution. fingerprint: true uses positional layouts and an 8-byte layout hash for smaller frames, but requires peers to use the same schema definition.

Signature

interface Options {
readonly fingerprint?: boolean;
}

Parser interface

Added in v4.0.0 Source

A stateful frame parser for concatenated toCodec outputs.

Signature

interface Parser<T> {
end: Effect<void, SchemaError>;
endSync(): void;
feed(chunk: Uint8Array): Effect<readonly Array<T>, SchemaError>;
feedSync(chunk: Uint8Array): readonly Array<T>;
}

StreamOptions interface

Added in v4.0.0 Source

Options for the connection-scoped pair, encoder and parser.

Signature

interface StreamOptions {
readonly dictionary?: boolean;
}

toCodec interface

Added in v4.0.0 Source

The codec type returned by toCodec.

Signature

interface toCodec<S extends Schema.Constraint> extends Codec<S["Type"], Uint8Array<ArrayBuffer>, S["DecodingServices"], S["EncodingServices"]> {
constructor(_: never);
}