jit
Runtime

Binary rowsets

Scan million-row flat datasets through compact packed, aligned or columnar memory.

const binary = JIT.array(User).binary({
  strategy: "exact",
  memoryLayout: "columnar",
});
const rowset = binary.load(users);

const count = JIT.query(rowset)
  .filter((q) => q.eq("role", "admin"))
  .count()
  .compile();

packed minimizes bytes, aligned enables typed views and columnar stores each field contiguously for repeated analytical scans. auto chooses between packed and naturally aligned rows.

Optional/null values use two mask bits. Strings use dictionaries; filter constants are resolved once and hot loops compare integer codes. Projection-only high-cardinality strings can use identity codes and skip a large map.

Tagged unions

Discriminated object unions receive dense numeric tags. Plain unions are supported when the compiler can infer one shared field with distinct literal values. Hydration switches on the integer tag and rebuilds only that variant's fields.

Compatible object intersections are flattened before offsets are assigned. Conflicting physical fields fail at compilation.

One-million-variant benchmark: tagged count 0.78 ms, native string discriminator 2.64 ms.

Strategies

StrategyAllocationLifetimeChoose it for
exactexact bytes per loadindependent rowsetsconcurrent HTTP/queue batches
dynamicreusable growing buffernext load overwrites scratchsequential long-lived worker
staticfixed/caller memorycontrolledlow-jitter capacity-bounded service

Static overflow throws. Dynamic rowsets should be consumed before loading the next batch through the same loader. Call rowset.release() and binary.clear() when long-lived references should be dropped.

Layout choice

packed minimizes bytes and can win mixed one-pass rows. aligned removes DataView access at the cost of padding. columnar wins repeated scans that touch a small field subset. auto cannot know reuse count, so it chooses only between compact packed and already naturally aligned layouts.

Supported shapes

Flat scalar object fields, optionals/nullables, literal unions, enums, Date, bigint and typed numbers are supported. Discriminated object unions and compatible intersections are normalized. Nested arbitrary objects/arrays are rejected: flatten a DTO or use regular JIT.query.

Query generation

Only touched columns/views/dictionaries are bound. Filtered string constants become integer IDs outside the loop. Rows that fail never hydrate back into JS objects. AOT queries are import-free and retain only selected low-level helpers.

On this page