Tsonic GitHub
Edit on GitHub

Configuration Reference

Tsonic uses two config files:

  • tsonic.workspace.json (workspace root) — shared settings and all external dependencies
  • packages/<project>/tsonic.json — per-project compilation settings

Workspace Config: tsonic.workspace.json

Minimal example:

{
  "$schema": "https://tsonic.org/schema/workspace/v1.json",
  "dotnetVersion": "net10.0",
  "dotnet": {
    "typeRoots": ["node_modules/@tsonic/globals"],
    "libraries": [],
    "frameworkReferences": [],
    "packageReferences": []
  }
}

Fields

  • dotnetVersion (required): target framework moniker for the workspace (e.g. "net10.0").
  • rid (optional): default RID for native builds (e.g. "linux-x64").
  • optimize (optional): "speed" or "size".
  • buildOptions.stripSymbols / buildOptions.invariantGlobalization (optional): defaults for builds.

dotnet.* (workspace-scoped deps)

  • dotnet.typeRoots: ambient TypeScript typeRoots used for compilation.
    • Default when omitted: ["node_modules/@tsonic/globals"]
  • dotnet.libraries: workspace DLL references (recommended location: libs/*.dll).
    • Each entry can be either a string path, or an object with an explicit bindings package:
      • "libs/MyLib.dll"
      • { "path": "libs/MyLib.dll", "types": "@acme/mylib-types" } (bindings supplied externally; no auto-generation)
      • { "path": "libs/MyLib.dll", "types": false } (no bindings; csproj-only dependency)
  • dotnet.frameworkReferences: additional shared frameworks (e.g. Microsoft.AspNetCore.App).
  • dotnet.packageReferences: NuGet packages (pinned exact versions).
    • Optional types:
      • string: bindings supplied externally (no auto-generation)
      • false: no bindings; csproj-only dependency
  • dotnet.msbuildProperties (optional): explicit MSBuild properties injected into the generated tsonic.csproj.
    • Use this when you need to enable a compiler/runtime feature that would normally be set in a .csproj.
    • Example (EF Core dotnet ef dbcontext optimize --nativeaot interceptors):
      {
        "dotnet": {
          "msbuildProperties": {
            "InterceptorsNamespaces": "$(InterceptorsNamespaces);Microsoft.EntityFrameworkCore.GeneratedInterceptors"
          }
        }
      }
      

Most users should manage these via the CLI:

tsonic add package ./some.dll
tsonic add nuget Microsoft.Extensions.Logging 10.0.0
tsonic add framework Microsoft.AspNetCore.App
tsonic restore

testDotnet.* (test-only deps)

testDotnet.* declares test-only .NET dependencies. These are:

  • restored/generated by tsonic restore
  • included by tsonic test
  • not injected into production builds (tsonic build/run)

Example:

{
  "testDotnet": {
    "packageReferences": [
      { "id": "Microsoft.NET.Test.Sdk", "version": "17.11.1", "types": false },
      { "id": "xunit", "version": "2.9.2" },
      { "id": "xunit.runner.visualstudio", "version": "2.5.6", "types": false }
    ]
  }
}

Fields:

  • testDotnet.frameworkReferences: test-only FrameworkReferences.
  • testDotnet.packageReferences: test-only PackageReferences.
  • testDotnet.msbuildProperties: MSBuild properties injected into the generated test csproj.

Project Config: packages/<project>/tsonic.json

Minimal executable project:

{
  "$schema": "https://tsonic.org/schema/v1.json",
  "rootNamespace": "MyApp",
  "entryPoint": "src/App.ts",
  "sourceRoot": "src",
  "outputDirectory": "generated",
  "outputName": "my-app",
  "output": { "type": "executable" }
}

Fields

  • rootNamespace (required): root C# namespace for generated code.
  • entryPoint (optional for libraries): TypeScript entry file.
  • sourceRoot (optional): root directory containing source files.
  • outputDirectory (optional): generated C# output directory (default: "generated").
  • outputName (optional): assembly/binary name (default: "app").
  • optimize (optional): "speed" or "size" (overrides workspace default).
  • buildOptions.* (optional): per-project build defaults.

tests (unit test build)

When present, tsonic test uses this configuration to build a non-NativeAOT test assembly and run dotnet test.

Minimal example:

{
  "tests": {
    "entryPoint": "src/tests/index.ts"
  }
}

Fields:

  • tests.entryPoint (required): entry module that imports/includes all test files.
  • tests.outputDirectory (optional): separate output directory for test generation (default: <outputDirectory>-test).
  • tests.outputName (optional): assembly name for the test project (default: <outputName>.tests).

output (per-project)

output.type:

  • "executable" (default when entryPoint is provided)
    • Uses NativeAOT by default (output.nativeAot: true).
  • "library" (default when entryPoint is omitted)
    • Copies artifacts to dist/ and emits dist/tsonic/bindings/.
    • Can also publish as a NativeAOT native library when output.nativeAot: true.
  • "console-app" (non-NativeAOT executable)

Common output.* fields:

Field Applies To Default Notes
nativeAot executable true NativeAOT publish
nativeAot library false When true, runs dotnet publish -r <rid> and copies output to dist/<tfm>/<rid>/publish/
nativeLib library shared Only when nativeAot: true (shared or static)
targetFrameworks library [dotnetVersion] Multi-target supported

references.libraries (workspace-internal)

Use references.libraries to reference DLL outputs of other projects in the same workspace. Paths are resolved relative to the project root.

Example (CLI project referencing a sibling library output):

{
  "references": {
    "libraries": ["../engine/dist/net10.0/MyLib.dll"]
  }
}

Naming Rules (No Naming Transforms)

Tsonic does not apply casing transforms. Names are preserved as written in TypeScript.

The only deterministic normalization is for path-derived names:

  • Directory segments and file basenames have hyphens (-) removed when generating namespaces / module container class names.
    • src/todo-list.ts → class todolist
    • src/my-feature/x.ts → namespace segment myfeature