CLI
The tsbindgen CLI is used to generate binding packages from CLR inputs.
Main commands
generate— generate TypeScript bindingsresolve-closure— inspect transitive assembly closure
Typical usage
dotnet run --project src/tsbindgen/tsbindgen.csproj -- \
generate -d /path/to/assemblies -o ./output
Common options
--assembly <path>--assembly-dir <path>--ref-dir <path>--out-dir <path>--namespaces <list>--lib <path>--lib-type-override <ClrType=package>--namespace-map <mapping>--flatten-class <fullname>--strict--verbose
Generated type boundaries
The CLI emits strict TypeScript declarations:
- CLR
System.Objectpositions becomeunknown - value-type constraints become
NonNullable<unknown> - generic parameters carry explicit
extends ...constraints - output is ESM-only with namespace facades and per-namespace metadata
resolve-closure
npx tsbindgen resolve-closure -a ./MyLibrary.dll
Use this to inspect the resolved assembly closure without generating output.
Runtime discovery
The CLI works with any installed .NET runtime path. For framework generation,
use dotnet --list-runtimes to locate Microsoft.NETCore.App:
DOTNET_RUNTIME=$(dirname "$(dotnet --list-runtimes | awk '/Microsoft.NETCore.App 10\\./ { print $3; exit }')")
npx tsbindgen generate -d "$DOTNET_RUNTIME" -o ./output
Repo-local test scripts perform the same discovery and accept DOTNET_RUNTIME
as an explicit override.
When --lib matters
Use --lib when you are generating a library package that should import
existing BCL or framework types from a pre-existing generated package instead of
re-emitting them.
That is how the stack keeps repos like aspnetcore, efcore, and
microsoft-extensions composable instead of duplicating the entire BCL surface.
When to use repo scripts instead
For the first-party binding repos, prefer the repo-local generation and wave publish scripts so versioning and package layout stay consistent.