A high-performance TypeScript .d.ts emitter written in Zig. Native companion to the TypeScript-based @stacksjs/dtsx — same output, significantly faster.
zig-dtsx reimplements the dtsx declaration-generation pipeline in Zig for maximum performance. Output is byte-identical to the TS implementation, so it slots in as a drop-in replacement wherever the compiled binary is available.
Two surfaces ship in one repo:
- CLI (
zig-dtsx) — standalone binary, distributable via pantry. - TS FFI bridge (
@stacksjs/zig-dtsx) — a Bun FFI wrapper that loads the shared library and exposesprocessSource(),processBatch(), etc. for in-process use from JS/TS tooling such asbun-plugin-dtsx.
pantry add zig-dtsxbun add @stacksjs/zig-dtsx -dimport { processSource, ZIG_AVAILABLE } from '@stacksjs/zig-dtsx'
if (ZIG_AVAILABLE) {
const dtsOutput = processSource(typescriptSource, true)
console.log(dtsOutput)
}Requires Zig to be installed.
# Build optimized release binary
bun run build:zig
# Build debug binary
bun run build:zig-debug
# Run Zig-native tests
bun run test:zigThe Zig implementation mirrors the TypeScript dtsx pipeline:
- Scanner - Tokenizes TypeScript source into a stream of tokens
- Extractor - Parses tokens and extracts declaration-relevant constructs (exports, types, interfaces, classes, functions, variables)
- Emitter - Produces
.d.tsoutput from the extracted declarations
The Zig binary communicates with the Bun runtime via FFI, allowing seamless integration with the existing dtsx ecosystem.
src/
scanner.zig tokenizer
extractors.zig declaration extraction
type_inference.zig type-mapping + isolated-declarations rules
emitter.zig .d.ts output
scan_loop.zig parser driver
char_utils.zig character classification helpers
types.zig shared AST/declaration types
lib.zig FFI surface (shared library)
main.zig CLI entrypoint
index.ts Bun FFI wrapper (consumed by JS/TS)
test/
zig-dtsx.test.ts bun:test suite against the FFI wrapper
benchmark.ts cross-tool perf harness
build.zig builds both shared lib + CLI
Benchmarked on Apple M3 Pro, macOS (bun 1.3.11, arm64-darwin).
| Tool | Small (~50 lines) | Medium (~100 lines) | Large (~330 lines) | XLarge (~1050 lines) |
|---|---|---|---|---|
| zig-dtsx | 3.37 µs | 7.05 µs | 21.89 µs | 144.89 µs |
| oxc-transform | 7.36 µs (2.2x) | 21.91 µs (3.1x) | 89.66 µs (4.1x) | 560.86 µs (3.9x) |
| tsc | 169.69 µs (50.4x) | 410.31 µs (58.2x) | 1.03 ms (47.1x) | 4.02 ms (27.7x) |
| Tool | Small (~50 lines) | Medium (~100 lines) | Large (~330 lines) | XLarge (~1050 lines) |
|---|---|---|---|---|
| zig-dtsx | 2.69 ms | 2.35 ms | 2.28 ms | 3.14 ms |
| oxc | 17.08 ms (6.3x) | 17.12 ms (7.3x) | 17.95 ms (7.9x) | 17.69 ms (5.6x) |
| tsgo | 40.53 ms (15.1x) | 44.10 ms (18.8x) | 44.39 ms (19.5x) | 57.77 ms (18.4x) |
| tsc | 384.25 ms (142.8x) | 407.51 ms (173.4x) | 418.81 ms (183.7x) | 454.74 ms (144.8x) |
| Tool | 50 files | 100 files | 500 files |
|---|---|---|---|
| zig-dtsx | 18.10 ms | 31.46 ms | ~140 ms |
| oxc | 48.27 ms (2.7x) | 79.00 ms (2.5x) | ~365 ms (2.6x) |
| tsgo | 244.68 ms (13.5x) | 419.65 ms (13.3x) | - |
| tsc | 871.48 ms (48.1x) | - | - |
bun run benchmarkTests validate that the Zig emitter produces identical output to the TypeScript implementation across all shared test fixtures.
# Run via Bun test runner
bun test
# Run Zig-native tests
zig build teststacksjs/dtsx— the reference TS implementationstacksjs/bun-plugin-dtsx— Bun bundler plugin that will consume thiszig-utils/zig-regex— sibling project; same release pattern (zig-bump + zig-changelog + pantry publish)
MIT — see LICENSE.md.