Transpile
Basic Usage
Section titled “Basic Usage”zntc input.ts # Output to stdoutzntc input.ts -o output.js # Output to filezntc src/ --outdir dist/ # Recursive directory transpileecho "const x: number = 1" | zntc - # stdin inputSupported Transforms
Section titled “Supported Transforms”TypeScript
Section titled “TypeScript”- Type annotation removal
- Interface/type declaration removal
- Enum to object + IIFE conversion
- Namespace conversion
as/satisfiesexpressions
# Classic (React.createElement)zntc --jsx=classic app.tsx
# Automatic (react/jsx-runtime)zntc --jsx=automatic app.tsx
# Development mode (jsxDEV + source info)zntc --jsx=automatic-dev app.tsx
# Custom factoryzntc --jsx-factory=h --jsx-fragment=Fragment app.tsxDecorators
Section titled “Decorators”# Legacy (experimentalDecorators)zntc --experimental-decorators app.ts
# Move class fields to constructorzntc --use-define-for-class-fields=false app.ts# Automatic @flow pragma detectionzntc --flow app.jsImport attributes (ES2024)
Section titled “Import attributes (ES2024)”with { type: "json" } is preserved as a round-trip across every import/export form.
Legacy assert on static imports is auto-migrated to with (Node 20+ deprecates assert).
// staticimport data from "./data.json" with { type: "json" };
// dynamic — the second argument is preserved tooconst mod = await import("./data.json", { with: { type: "json" } });
// re-exportexport { default as data } from "./data.json" with { type: "json" };export * from "./data.json" with { type: "json" };export * as ns from "./data.json" with { type: "json" };Local JSON imports are already inlined during bundling based on extension.
with { type }matters when the bundle output runs on Node as ESM, or when emitting sources that require spec-compliant JSON module syntax.Behavior:
with { type }is round-trip metadata. Loader selection is purely extension-based — attrs will not force a loader (.txt→ JSON) nor error on unknown type values.
Output Options
Section titled “Output Options”Module Format
Section titled “Module Format”zntc --format=esm app.ts # ESM (default)zntc --format=cjs app.ts # CommonJSzntc --format=iife app.ts # Immediately Invoked Function Expressionzntc --format=umd app.ts # UMD (browser + Node)zntc --format=amd app.ts # AMD (RequireJS)ES Target / Engine Target
Section titled “ES Target / Engine Target”# ES version target — es2015 ~ esnextzntc --target=es2020 app.ts
# Engine version target — feature-level downlevelingzntc --target=chrome80,safari14 app.tszntc --target=node18 app.tszntc --target=hermes0.70 app.ts # React Native (Hermes)Engine targets only emit the transformations required by each engine’s compatibility table.
Minify
Section titled “Minify”zntc --minify app.ts # All three
# Granular (esbuild-compatible)zntc --minify-whitespace app.ts # Whitespace/semicolons/newlines (debuggable)zntc --minify-syntax app.ts # true→!0, paren removal, constant folding, drop unreferenced class expression nameszntc --minify-identifiers app.ts # Shorten local identifiersCombine flags freely — e.g. enable only --minify-whitespace for dev builds to get a debuggable, smaller output.
Source Maps
Section titled “Source Maps”zntc --sourcemap app.ts -o app.js# Generates app.js + app.js.mapQuote Style
Section titled “Quote Style”zntc --quotes=single app.ts # Single quoteszntc --quotes=double app.ts # Double quotes (default)zntc --quotes=preserve app.ts # Preserve originalASCII Only
Section titled “ASCII Only”zntc --ascii-only app.ts # Escape non-ASCII to \uXXXXDefine
Section titled “Define”zntc --define:DEBUG=false --define:VERSION='"1.0.0"' app.tsValues must be JavaScript literals. Watch out for missing quotes.
# ✗ Wrong — admin becomes an identifier, producing unintended codezntc --define:USERNAME=admin app.ts
# ✓ Right — quote it so it becomes a string literalzntc --define:USERNAME='"admin"' app.ts
# ✓ Numbers / booleans / null are literals as-iszntc --define:DEBUG=false --define:MAX=100 --define:USER=null app.ts
# ✓ Object / array work too if they're valid JSON literalszntc --define:ENV='{"mode":"prod"}' app.tsShell quoting gotcha: in bash/zsh you need to wrap the double quotes in single quotes to keep them.
Three independent removal options that can be combined.
# Remove console.* callszntc --drop=console app.ts
# Remove debugger statementszntc --drop=debugger app.ts
# Remove labeled blocks entirely — comma-separated labelszntc --drop-labels=DEV,TEST app.ts
# All three at oncezntc --drop=console --drop=debugger --drop-labels=DEV,TEST app.ts--drop-labels example:
// SourceDEV: { console.log("debug only"); attachDevtools();}
// --drop-labels=DEV → the whole block disappears in the outputWrap dev-only debug code in a label and you can strip it all in one switch for production builds.