Conversation
- CLAUDE.md: development guide, build commands, architecture overview - docs/: architecture, testing, benchmarks, vision, team workflow, packages - .claude/: agent instructions, handover system, commit plan - .github/: CI workflows and issue templates - scripts/: development utilities and hooks - lefthook.yml: pre-commit hooks for typecheck and lint - README.md: updated project description
- Core benchmarks: serialization, validation, BSON, ORM, HTTP, RPC, injector - Comparison benchmarks: vs Zod, class-transformer, bson-js, Typia - V8 optimization pattern microbenchmarks - JSON/markdown/SVG reporters for CI integration - Pre-refactor baseline for regression detection (--compare-baseline)
- docker-compose.yml: PostgreSQL, MySQL, MongoDB, Redis, S3, SFTP, FTP, GCS - tsconfig.base.json: add useDefineForClassFields: false (ES2022 compat) - package.json: update dependencies and scripts
BREAKING CHANGE: Internal JIT compilation API changed for serializer extensions. - Builder API: expression tree model replacing CompilerContext - Closure-based executors (CSP-compatible, no new Function()) - Tiered execution: interpret first, JIT-compile hot paths - Builder operations: forRange, forOf, arithmetic/bitwise, throw_, cond, concat - Unified debugging with setJitDebug() for all JIT functions - DeepkitError base class with DK-XXX error code system
… issues - Emit 'any' bytecode for external types instead of invalid JS (#352) - Escape Windows backslash path delimiters (#356) - Resolve optional chaining SyntaxError (#612) - Hoist function __types declarations (#664) - Auto re-export __Ω symbols with named re-exports (#634, #318) - Exclude declare statements from type emission (#601) - Graceful degradation for external library types (#555) - Replace entire TypeReferenceNode for infer types (#509) - Support tsconfig extends as array (#600) - Improved DeepkitLoader API for bundler integrations (#456) - Migrate tests from Jest to node:test
- packages/run/expect.ts: shared assertion shim (toBe, toEqual, toThrow, etc.) - packages/bench: BenchSuite class with warmup, statistical analysis - Enables Jest → node:test migration for core packages
…n speedup BREAKING CHANGE: Internal serializer API changed. Reference serialization is now type-driven with Inline annotation. Serializer rewrite: - Complete serializer/validator rewrite with expression-tree JIT compilation - Union validation: O(1) discriminator dispatch (was O(n) runtime) - ReceiveType overhead reduced by 12x (325ns → 28ns) - Index signature handling inlined at JIT time Performance (pre-resolved fn() API, vs master): - Small model: serialize +587%, deserialize +88%, validate +213%, is +1649% - Medium model: serialize +51%, deserialize +124%, validate +317%, is +960% - Union: serialize +1342%, deserialize +637%, validate +1605%, is +1679% New features: - NanoId type support with validation and serialization (#419) - Union constraint errors — show field-level errors (#577) - isStrict<T>() — strict type guard without coercion - isWeak<T>() — maximum-performance type guard (minimal checks) - Inline annotation — control Reference serialization per-serializer Bug fixes: - Improve NoTypeReceived error messages (#562) - Correct tuple inference with rest before infer (#524) - Improve error "No valid runtime type" (#508) - Prevent stack overflow for large literal unions (#478) - Handle circular references in ValidationErrorItem (#505) - Skip serializing superClass when parent has no __type (#241) - Replace plain Error with proper DeepkitError subclasses Test migration: 1,975 tests migrated from Jest to node:test (4 pre-existing skips)
BREAKING CHANGE: Removed Writer, BaseParser, getBSONSizer, BSONBinarySerializer. getBSONSerializer() now returns [Uint8Array, number] tuple (zero-copy). Architecture: - Shape-learning JIT deserializer with specialized code per document shape - Buffer reuse with shared buffer and zero-copy tuple return - Circular reference detection with depth-based extraction - Security hardening: prototype pollution protection, bounds checking Performance (vs bson-js): - Single-doc serialize: 8-313x faster (sensor 194x, int32 313x) - Single-doc deserialize: 6-31x faster (sensor 12x, int32 31x) - Array serialize (cursor response): 5-46x faster at all sizes - Array deserialize (cursor response): 3-11x faster at all sizes Optimizations: - Tiered UTF-8 decoder: unrolled ≤12B, singlepass 13-64B, TextDecoder >64B - hexTable2: 65536-entry lookup for UUID/MongoId hex encoding - BinaryBigInt: native BSON binary representation for BigInt values - Primitive array inline: string[], number[], boolean[] in shape JIT - forIndex() preserves depth (prevents extraction at MAX_DEPTH=3) Bug fixes: - Serialize NaN as 0 instead of skipping (#573) - Improve union error messages (#676) Test migration: 549 tests migrated from Jest to node:test
- Adapt to new jit.ts Builder API - Update error handling to use DeepkitError (DK-I codes) - Fix type resolution edge cases
Features: - Built-in CORS middleware with configurable origins/methods/headers (#441) - Express-compatible req.get() and req.header() methods (#285) Bug fixes: - Improve middleware error handling and propagation (#439) - Fix HttpBody parameter injection across file boundaries (#458) - Make HttpHeader matching case-insensitive (#653) - Ensure onResponse fires on early middleware response (#590) - Propagate HttpError from middleware with correct status code (#589) Performance: - Pre-compiled request-scoped middleware resolvers
- Prevent FinalizationRegistry from firing during active subscriptions - Track active subscriptions with strong references during await - Fix TypeScript types for subscribe.apply arguments - Improve error messages with controller/method context - Update to DeepkitError (DK-R codes)
…alizer - Adapt to new type serializer and BSON API changes - Add shebang to CLI bin files (#598) - Update to DeepkitError (DK-PG, DK-MY, DK-SQ codes)
- Adapt to new getBSONSerializer() tuple return type - Update MongoBinarySerializer for new BSONBinarySerializer removal - Update wire protocol message construction - Update to DeepkitError (DK-MG codes)
- Adapt to new jit.ts Builder API - Update CLI and config handling
- Adapt to getBSONSerializer() tuple return type - Fix getBsonEncoder → getBSONEncoder case - Remove AutoBuffer dependency
Updated packages: topsort, event, template, workflow, stopwatch, vite, bun, desktop-ui, orm-browser, orm-integration, api-console, filesystem adapters (local, S3, database, FTP, Google, SFTP). - Adapt to new type serializer API - Replace plain Error with DeepkitError subclasses - filesystem-aws-s3: add forcePathStyle option for S3-compatible services - desktop-ui: add shebang to CLI bin (#598)
- Update serialization docs for new type-driven Reference behavior - Update validation docs for union constraint errors - Update type docs for NanoId, isStrict, isWeak
…ding Next steps: - Prove performance is optimal (update bson-js to latest, re-run all benchmarks) - Fix broken consumer BSON imports (rpc, mongo, broker, framework-debug-api) - Full test suite verification after consumer migrations Handover document: .claude/handover.md
Next steps: - Investigate BSON deserialize perf ceiling (only 5-13x vs bson-js v7) - Fix consumer BSON imports (rpc, mongo, broker, framework-debug-api) - Commit as proper semantic commits when ready Handover document: .claude/handover.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Deepkit v2
Performance at a Glance
is()Summary
Deepkit v2 is a ground-up rewrite of the framework's core JIT, serialization, and BSON layers — delivering order-of-magnitude performance improvements while adding CSP compliance, security hardening, and a cleaner public API.
JIT Architecture Rewrite — New expression-tree based
jit.tsin@deepkit/core. Zeronew Function()calls, CSP-compliant, tiered execution (interpret first, JIT-compile hot paths).BSON Package Rewrite — Complete rewrite of
@deepkit/bsonwith shape-learning JIT deserializer, zero-copy serialization, and security hardening. 3–63x faster than v1, 2–224x faster than bson-js 7.x.Type Serializer Rewrite —
@deepkit/typeserializer migrated tojit.fn()API. Union validation 1000x faster via O(1) discriminator dispatch. ReceiveType overhead reduced 90%. All 12 benchmarks beat v1.Fixes: #241, #285, #318, #352, #356, #439, #458, #478, #505, #508, #509, #524, #555, #562, #573, #589, #590, #598, #601, #612, #614, #634, #636, #653, #664, #668, #676
Features: #395, #419, #441, #456, #577, #582, #600
Breaking Changes
1.
feat(type,bson)!: Type-driven Reference serialization withInlineannotation& Referencenow always serializes as FK (primary key only), regardless of runtime object state. Previously, serialization depended onisReferenceInstance()which was unpredictable.New API:
Inlinecontrols serialization for JSON and RPC BSON output. MongoDB communication always serializes references as FK —Inlinehas no effect on MongoDB storage.Migration: If your code relied on
joinWith()affecting serialization output, use& Reference & Inlineon the type definition instead.2.
feat(bson)!: BSON API overhaulRemoved exports:
WriterclassBaseParserclassBSONBinarySerializerclassValueWithBSONSerializertypeAutoBufferutilitygetBSONSizer()functionstringByteLength()utilitygetBsonEncoder()(renamed togetBSONEncoder())Changed return types:
getBSONSerializer<T>()now returns(data: T) => [Uint8Array, number](buffer + size tuple, zero-copy)(data: T) => Uint8ArrayNew exports:
getBSONEncoder<T>()— high-level encode/decode pairdeserializeBSONWithoutOptimiser()— public slow-path deserializerSerializeResulttype alias for[Uint8Array, number]3.
feat(core)!: New jit.ts — expression tree JIT/Exec architectureThe old
CompilerContext-based JIT in@deepkit/coreis replaced with a new Builder API (jit.ts). This is an internal API used by@deepkit/typeand@deepkit/bson— not directly user-facing, but affects anyone extending the serializer.Key changes:
CompilerContext→Builderwith expression tree modelnew Function()→ closure-based executors (CSP-compatible)New Features
@deepkit/type
NanoIdtype with validation and serializationisStrict<T>()isWeak<T>()Inlineannotation@deepkit/http
req.get()andreq.header()for Express middleware compat@deepkit/type-compiler
extendsas array@deepkit/filesystem-aws-s3
forcePathStyleoptionforcePathStylefor S3-compatible services (MinIO, etc.)@deepkit/framework
@deepkit/core
DeepkitErrorbase class withDK-T###,DK-B###, etc. codesforRange,forOf, arithmetic/bitwise ops,throw_,cond,concat@deepkit/bson
Bug Fixes
@deepkit/type-compiler
__typesdeclarations__Ωsymbols with named re-exportsdeclarestatements@deepkit/type
NoTypeReceivederror messages for better DXValidationErrorItem.toString()__typePartial<T>shadowPartial<T>that shadowed TypeScript built-inhasDefaultFunctionExpression@deepkit/http
onResponsefires when middleware ends response early@deepkit/orm
count()ignores pagination to return total countwithChangeDetectionclonewithChangeDetectioninDatabaseQueryModel.clone()deleteResult.modifieddeleteResult.modifiedinMemoryDatabaseAdapter@deepkit/bson
@deepkit/rpc
subscribe.applyargumentsOther
Errorwith properDeepkitError/BSONErrorsubclassesPerformance Improvements
@deepkit/type
deserialize<T>()with ReceiveTypevalidate<T>()with ReceiveTypeis<T>()with ReceiveTypex==nullinstead ofx===undefined||x===nullReceiveType overhead breakdown (was 325ns → now ~32ns):
NamingStrategy(101ns allocation)Union validation fix: Added
detectDiscriminator()toguardUnionFast— uses O(1) switch dispatch instead of linear member iteration. Error collection viavalidateDiscriminatedUnionWithErrorsruntime.Index signature optimization: Inline index signature validation/serialization directly in
b.forInloops usingstate.forKey(key).build(). Pre-build serializer/deserializer/type-guard functions at JIT time instead of rebuilding per-key per-call. Cache extracted nested functions inbuildExtractedCall.vs v1 performance (pre-resolved
fn()API):is()is()is()All 12 benchmarks beat v1. Fastest improvements: small
is()+1674%, union serialize +1317%, union validate +1580%.@deepkit/bson
Single document performance (pre-resolved API):
All single-document benchmarks beat v1. Serialize 3–63x faster (buffer reuse + zero-copy tuple return), deserialize 1.8–7x faster (shape-learning JIT + tiered UTF-8 decoder + hexTable2 optimization). All benchmarks 5–224x faster than bson-js 7.x.
Array performance (MongoDB cursor response
{ cursor: { firstBatch: T[] } }):Array performance tested in the standard MongoDB response pattern at depth 3 — the most common real-world access pattern. Deepkit maintains 2–39x advantage over bson-js 7.x at all array sizes and element types.
Shape-learning JIT: Documents are profiled at runtime. After learning the shape (field order, types), a specialized JIT reader is generated that skips field name parsing. Falls back to interpreted path for unknown shapes. Provides 21x improvement for union types.
hexTable2 optimization: 65,536-entry lookup table maps byte-pairs to 4-char hex strings. Eliminates per-byte hex conversion for UUID/MongoId.
@deepkit/http
Test Migration: Jest → node:test
Migrated three core packages from Jest to
node:testwith a shared@deepkit/run/expectassertion shim.Changes:
packages/run/expect.ts— shared expect() shim with matchers:toBe,toEqual,toStrictEqual,toBeInstanceOf,toContain,toMatch,toThrow,toBeGreaterThan,toBeTruthy,toBeFalsy,toBeNull,toBeUndefined,toBeDefined,toHaveProperty,toHaveLength,toMatchObject,resolves,rejectstest:nodescripts to package.json filesimport { expect } from '@deepkit/run/expect'useDefineForClassFields: falsetotsconfig.base.json(ES2022 defaults it totrue, which changes class field initialization semantics)Infrastructure
Benchmark Suite (new)
Comprehensive benchmark infrastructure at
benchmarks/:npm run benchmark -- --compare-baselinefails on >20% regressionDocker Compose Test Environment
Full test stack at
docker-compose.yml:Error Code System
All packages now use
DeepkitErrorbase class with coded errors:DK-T###(@deepkit/type),DK-B###(@deepkit/bson),DK-O###(@deepkit/orm)DK-I###(@deepkit/injector),DK-H###(@deepkit/http),DK-R###(@deepkit/rpc)Pre-commit Hooks (lefthook)
npm run typecheck)Open TODOs (Post-Merge)
CRITICAL: Consumer Package Migration
5 packages have broken imports due to the BSON API overhaul and need updating before the full framework compiles:
@deepkit/rpcWriter,getBSONSizer— protocol binary serialization@deepkit/mongoBSONBinarySerializer,ValueWithBSONSerializer,Writer,getBSONSizer@deepkit/brokergetBSONSerializerreturn type changed to[buffer, size]tuple@deepkit/broker-redisAutoBufferremoved,getBsonEncoder→getBSONEncodercase fix@deepkit/framework-debug-apiWriter,BaseParser,getBSONSizer,stringByteLengthDetailed migration notes: See
.claude/handover.mdSuppressed Issues section.RPC Protocol Rewrite
The RPC protocol (
packages/rpc/src/protocol.ts) uses low-level binary operations (Writer,getBSONSizer) to construct message envelopes with precise size control. This needs either:getBSONSerializer()tuple API (serialize first, then build envelope)Writer/sizer utilities from@deepkit/bsonfor low-level consumersMongoDB Client Rewrite
The MongoDB client (
packages/mongo/src/client/connection.ts) has similar needs — constructs MongoDB wire protocol messages usingWriterand pre-calculated sizes. TheMongoBinarySerializerclass (extends removedBSONBinarySerializer) needs architectural replacement.Additional Package Migrations to node:test
Remaining packages still use Jest:
4 Skipped Tests
packages/type/tests/serializer.spec.tshas 4test.skip(pre-existing from Jest):onLoad call(×3) — lines 1153, 1180, 1204extend with custom type— line 1363