Tsonic
Tsonic compiles a strict, deterministic subset of TypeScript into C#, then into native binaries or .NET libraries.
The current V1 model is:
- one compiler-owned noLib core
- one active ambient surface per workspace
- explicit package-based CLR and module interop
- strict-AOT rejection for anything that cannot be lowered deterministically
Why Tsonic
- TypeScript authoring with explicit numeric/value semantics when needed
- NativeAOT and regular .NET outputs from the same compiler
- Direct CLR interop through
@tsonic/dotnetand generated bindings - JS-surface authoring through
@tsonic/js - Node module support through
@tsonic/nodejs - First-party source-package consumption for Tsonic-authored npm packages
Surfaces
Tsonic separates the language prelude from the ambient runtime personality.
- compiler core: always-on noLib baseline (
Promise, iterators, utility types, array shape) clrsurface: default ambient CLR-first world@tsonic/jssurface: JS-style globals and receiver methods@tsonic/nodejs: normal package, not a surface
That means:
- CLR workspace:
"abc"exposes CLR-shaped ambient members- import CLR APIs explicitly from
@tsonic/dotnet/...
- JS workspace:
"abc".trim(),[1, 2, 3].map(...),console.log(...),JSON,Datework as ambient JS APIs
- Node usage:
- keep JS surface active
- add
@tsonic/nodejs - import
node:*modules normally
Installation
npm install -g tsonic
Requirements:
- Node.js 22+
- .NET 10 SDK
Quick Start
Default CLR workspace
mkdir hello-clr
cd hello-clr
tsonic init
tsonic run
Generated sample:
import { Console } from "@tsonic/dotnet/System.js";
export function main(): void {
Console.WriteLine("Hello from Tsonic!");
}
JS workspace
mkdir hello-js
cd hello-js
tsonic init --surface @tsonic/js
tsonic run
Generated sample:
export function main(): void {
const message = " Hello from Tsonic JS surface! ".trim();
console.log(message);
}
JS + Node modules
mkdir hello-node
cd hello-node
tsonic init --surface @tsonic/js
tsonic add npm @tsonic/nodejs
Then author normal Node-style imports:
import * as path from "node:path";
import * as fs from "node:fs";
export function main(): void {
const file = path.join("src", "App.ts");
console.log(file, fs.existsSync(file));
}
Run it:
tsonic run
Core Imports
Use @tsonic/core/types.js for CLR-specific numeric/value intent:
import type { int, long, bool } from "@tsonic/core/types.js";
Use @tsonic/core/lang.js for language intrinsics:
import {
defaultof,
nameof,
sizeof,
stackalloc,
out,
} from "@tsonic/core/lang.js";
CLR Interop
Import CLR APIs explicitly:
import { Console } from "@tsonic/dotnet/System.js";
import { Enumerable } from "@tsonic/dotnet/System.Linq.js";
export function main(): void {
const xs = [1, 2, 3];
const filtered = Enumerable.Where(xs, (x: number): boolean => x > 1);
Console.WriteLine(filtered.Count().ToString());
}
For external CLR dependencies:
tsonic add nuget Microsoft.Extensions.Logging 10.0.0
tsonic add package ./libs/MyCompany.MyLib.dll
tsonic restore
First-Party Source Packages
tsonic init now creates npm-publish-ready source packages by default. Each project gets a source manifest at:
packages/<project>/tsonic/package-manifest.json
Example:
{
"schemaVersion": 1,
"kind": "tsonic-source-package",
"surfaces": ["@tsonic/js"],
"source": {
"exports": {
".": "./src/App.ts"
}
}
}
Installed source packages with that manifest are compiled transitively as part of the same Tsonic program.
Build Modes
tsonic generate
tsonic build
tsonic run
tsonic test
tsonic pack
Supported output shapes include:
- NativeAOT executable
- managed executable
- managed library
- NativeAOT shared/static library
Current V1 Highlights
- AST-only emitter pipeline
- Promise constructor +
then/catch/finallylowering - deterministic closed-world
import()support - supported
import.metasubset:url,filename,dirname, and bareimport.meta - broader object-literal support:
- accessors
- computed constant keys
- shorthand methods
- supported
arguments.length/arguments[index]cases
nameof(...)andsizeof<T>()- deterministic generic function values in supported monomorphic contexts
Documentation
- User guide:
/tsonic/ - Site:
https://tsonic.org/tsonic/ - Architecture:
/tsonic/architecture/
License
MIT