Tsonic
Tsonic compiles a strict, deterministic subset of TypeScript into C#, then builds native binaries or .NET outputs from that generated project.
Stack
tsonicis the compiler and CLI.@tsonic/coreprovides primitive intent types and compiler intrinsics.@tsonic/jsis the JavaScript ambient surface.@tsonic/nodejsis a first-party TypeScript source package for Node-style modules.@tsonic/expressis a first-party TypeScript source package for Express-style routing and middleware.tsbindgengenerates CLR binding packages such as@tsonic/dotnet,@tsonic/aspnetcore,@tsonic/microsoft-extensions, and@tsonic/efcore*.- Release quality is verified across compiler tests, package selftests, generated binding packages, and downstream applications.
Documentation model
This site mounts product documentation from the owning repositories instead of duplicating it locally.
tsonic.orgowns cross-repo synthesis pages.tsonic/docsowns compiler, CLI, workspace, and architecture docs.tsbindgen/docsowns generated binding pipeline docs.js/docsowns@tsonic/jsdocs.nodejs/docsowns@tsonic/nodejsdocs.express/docsowns@tsonic/expressdocs.
Start here
- /architecture/ — architecture and package model
- /ecosystem/ — repo, package, and ownership map
- /testing-and-releases/ — release gates and wave flow
- /tsonic/ — compiler, CLI, workspaces, build modes, examples
- /js/ —
@tsonic/js - /nodejs/ —
@tsonic/nodejs - /express/ —
@tsonic/express - /tsbindgen/ — generated CLR binding packages
Quick starts
CLR-first workspace
mkdir hello-clr
cd hello-clr
tsonic init
tsonic run
import { Console } from "@tsonic/dotnet/System.js";
export function main(): void {
Console.WriteLine("Hello from Tsonic.");
}
JS-surface workspace
mkdir hello-js
cd hello-js
tsonic init --surface @tsonic/js
tsonic run
export function main(): void {
const message = " hello from tsonic ".trim().toUpperCase();
console.log(message);
}
JS + Node modules
mkdir hello-node
cd hello-node
tsonic init --surface @tsonic/js
tsonic add npm @tsonic/nodejs
tsonic run
import * as fs from "node:fs";
import * as path from "node:path";
export function main(): void {
const file = path.join("src", "App.ts");
console.log(file, fs.existsSync(file));
}
ASP.NET Core workspace
tsonic init
tsonic add framework Microsoft.AspNetCore.App @tsonic/aspnetcore
tsonic restore
import { WebApplication } from "@tsonic/aspnetcore/Microsoft.AspNetCore.Builder.js";
import type { ExtensionMethods } from "@tsonic/aspnetcore/Microsoft.AspNetCore.Builder.js";
export function main(): void {
const builder = WebApplication.CreateBuilder();
const app = builder.Build() as ExtensionMethods<WebApplication>;
app.MapGet("/", () => "Hello from ASP.NET Core");
app.Run("http://localhost:8080");
}
EF Core + SQLite workspace
tsonic init
tsonic add nuget Microsoft.EntityFrameworkCore.Sqlite 10.0.0 @tsonic/efcore-sqlite
tsonic restore
import { DbContext, DbContextOptionsBuilder } from "@tsonic/efcore/Microsoft.EntityFrameworkCore.js";
import { SqliteDbContextOptionsBuilderExtensions } from "@tsonic/efcore-sqlite/Microsoft.EntityFrameworkCore.js";
export class AppDbContext extends DbContext {
}
export function configure(builder: DbContextOptionsBuilder): void {
SqliteDbContextOptionsBuilderExtensions.UseSqlite(builder, "Data Source=app.db");
}