npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@tsonic/tsbindgen

v0.7.27

Published

Generate TypeScript declarations from .NET assemblies

Readme

tsbindgen

TypeScript type declaration generator for .NET assemblies

tsbindgen generates TypeScript declaration files (.d.ts) from .NET assemblies using reflection. It creates fully-typed, IDE-friendly TypeScript definitions that map the entire .NET Base Class Library (BCL) to TypeScript.

Features

  • Complete BCL coverage - Generates declarations for all 130 BCL namespaces, 4,047 types
  • Zero TypeScript errors - Output validates cleanly with tsc --strict
  • Nullable reference types - NRT support for output positions (returns, properties, fields)
  • CLR primitives - Numeric type aliases (int, long, decimal, etc.) via @tsonic/core
  • CLR-faithful names - No casing transforms; member names match the CLR surface
  • Generic type preservation - Full generic type parameter support with constraints
  • Unified bindings manifest - CLR-specific information lives in <Namespace>/bindings.json (no metadata sidecars)
  • Library mode - Generate only your assembly's types, importing BCL types from pre-existing packages
  • Namespace mapping - Customize output directory names with --namespace-map
  • Class flattening - Export static class methods as top-level functions with --flatten-class

Installation

Via npm (recommended)

npm install tsbindgen
# or
npm install @tsonic/tsbindgen

Requires .NET 10 runtime installed.

From source

git clone https://github.com/tsoniclang/tsbindgen
cd tsbindgen
dotnet build src/tsbindgen/tsbindgen.csproj

Quick Start

Generate BCL declarations

# Via npm
npx tsbindgen generate -d ~/.dotnet/shared/Microsoft.NETCore.App/10.0.0 -o ./output

# Via dotnet (from source)
dotnet run --project src/tsbindgen/tsbindgen.csproj -- \
  generate -d ~/.dotnet/shared/Microsoft.NETCore.App/10.0.0 -o ./output

Generate for a custom assembly

# Via npm
npx tsbindgen generate -a ./MyLibrary.dll -d $DOTNET_RUNTIME -o ./output

# Via dotnet (from source)
dotnet run --project src/tsbindgen/tsbindgen.csproj -- \
  generate -a ./MyLibrary.dll -d $DOTNET_RUNTIME -o ./output

Library mode (exclude BCL types)

# First, generate BCL types
npx tsbindgen generate -d $DOTNET_RUNTIME -o ./bcl-types

# Then generate your library, importing BCL from the pre-existing package
npx tsbindgen generate -a ./MyLibrary.dll -d $DOTNET_RUNTIME -o ./my-lib --lib ./bcl-types

CLI Reference

Commands

| Command | Description | |---------|-------------| | generate | Generate TypeScript declarations from .NET assemblies | | resolve-closure | Resolve transitive assembly dependency closure (JSON) |

Generate Options

| Option | Short | Description | Default | |--------|-------|-------------|---------| | --assembly | -a | Path to assembly file(s) to process | - | | --assembly-dir | -d | Directory containing .NET runtime assemblies | - | | --ref-dir | - | Additional directory to search for referenced assemblies (repeatable) | - | | --out-dir | -o | Output directory for generated files | out | | --namespaces | -n | Namespace filter (reserved; currently ignored) | (all) | | --lib | - | Path to pre-existing tsbindgen package (repeatable) | - | | --namespace-map | - | Map CLR namespace to output name (repeatable) | - | | --flatten-class | - | Flatten static class to top-level exports (repeatable) | - | | --verbose | -v | Enable detailed progress output | false | | --logs | - | Enable specific log categories (repeatable; space-separated values) | - | | --strict | - | Enable strict mode validation | false |

resolve-closure

Machine-readable dependency resolution for one or more seed assemblies. Useful for:

  • Debugging missing dependencies before generation
  • Tooling integrations (e.g. build systems) that need deterministic closure resolution
npx tsbindgen resolve-closure \
  -a ./MyLibrary.dll \
  --ref-dir $DOTNET_RUNTIME \
  --ref-dir ./libs

Examples

# Generate a custom assembly when dependencies live outside the runtime directory
npx tsbindgen generate -a ./MyLibrary.dll -d $DOTNET_RUNTIME -o ./out \
  --ref-dir ./libs

# Verbose output with specific log categories
npx tsbindgen generate -d $DOTNET_RUNTIME -o ./out -v --logs ImportPlanner FacadeEmitter

# Strict mode (additional validation)
npx tsbindgen generate -d $DOTNET_RUNTIME -o ./out --strict

Output Structure

tsbindgen emits a flat ESM facade per namespace plus a per-namespace directory for internals:

output/
├── families.json                      # Multi-arity family index
├── __internal/extensions/index.d.ts   # Extension method buckets
├── System.d.ts                        # Facade (public API)
├── System.js                          # Runtime stub (throws)
├── System/
│   ├── bindings.json
│   └── internal/index.d.ts            # Full declarations
├── System.Collections.Generic.d.ts
├── System.Collections.Generic.js
└── System.Collections.Generic/
    ├── bindings.json
    └── internal/index.d.ts

Publishing Bindings Packages (dist/ + npm exports)

When you publish bindings for your own assemblies (or generate them inside an npm workspace), you can keep generated artifacts out of git by writing them under dist/ and exposing the facades via npm exports:

dist/tsonic/bindings/
  Acme.Domain.js
  Acme.Domain.d.ts
  Acme.Domain/
    bindings.json
    internal/index.d.ts

package.json:

{
  "type": "module",
  "exports": {
    "./package.json": "./package.json",
    "./*.js": {
      "types": "./dist/tsonic/bindings/*.d.ts",
      "default": "./dist/tsonic/bindings/*.js"
    }
  }
}

Consumers can then import CLR namespaces ergonomically:

import { TodoItem } from "@acme/domain/Acme.Domain.js";

Tsonic resolves the import using Node’s module resolution (including exports) and locates the nearest bindings.json for CLR discovery.

Output Files

| File | Description | |------|-------------| | <Namespace>.d.ts | Public facade with curated exports and friendly aliases | | <Namespace>.js | Module stub that throws if executed in Node | | <Namespace>/internal/index.d.ts | Full type declarations ($instance + __views) | | <Namespace>/bindings.json | CLR bindings manifest for the Tsonic compiler (names + CLR semantics) |

Extension Methods (C# using Semantics)

tsbindgen collects C# extension methods into bucket helper types under __internal/extensions/index.d.ts and re-exports a per-namespace helper from each facade:

// System.Linq.d.ts
export type { ExtensionMethods_System_Linq as ExtensionMethods } from "./__internal/extensions/index.js";

Use the helper as a type-level “using” wrapper:

import type { ExtensionMethods as Linq } from "@tsonic/dotnet/System.Linq.js";
import type { IEnumerable } from "@tsonic/dotnet/System.Collections.Generic.js";

type LinqSeq<T> = Linq<IEnumerable<T>>;

declare const xs: LinqSeq<number>;
xs.Where((x) => x > 0).Select((x) => x * 2);

Type Mapping

Primitive Types

CLR primitive types map to type aliases from @tsonic/core:

| CLR Type | TypeScript Type | |----------|----------------| | System.Int32 | int (alias for number) | | System.Int64 | long (alias for number) | | System.Single | float (alias for number) | | System.Double | double (alias for number) | | System.Decimal | decimal (alias for number) | | System.Byte | byte (alias for number) | | System.Boolean | bool (branded) | | System.String | string | | System.Char | char (branded) |

Generic Types

Generic types use underscore suffix for arity:

| CLR Type | TypeScript Type | |----------|----------------| | List<T> | List_1<T> | | Dictionary<TKey, TValue> | Dictionary_2<TKey, TValue> | | Func<T, TResult> | Func_2<T, TResult> |

Friendly aliases are also exported:

// Both work:
import { List_1 } from "@tsonic/dotnet/System.Collections.Generic.js";
import { List } from "@tsonic/dotnet/System.Collections.Generic.js";  // Friendly alias

Type Kind Mapping

| CLR Kind | TypeScript Pattern | |----------|-------------------| | Class | interface + const (instance + static sides) | | Struct | interface + const | | Interface | interface | | Enum | const enum | | Delegate | type (function signature + CLR type intersection) | | Static class | abstract class (static methods only) |

Naming

tsbindgen emits CLR-faithful names (no casing transforms).

Testing

# Run all regression tests
bash test/scripts/run-all.sh

# Run validation (TypeScript compilation check)
node test/validate/validate.js

# Individual tests
bash test/scripts/test-strict-mode.sh
bash test/scripts/test-determinism.sh
bash test/scripts/test-surface-manifest.sh
bash test/scripts/test-lib.sh

Development

Project Structure

tsbindgen/
├── src/tsbindgen/
│   ├── Cli/                 # Command-line interface
│   ├── Load/                # Assembly loading and reflection
│   ├── Model/               # Symbol graph data structures
│   ├── Shape/               # Type transformation passes
│   ├── Normalize/           # Name reservation
│   ├── Plan/                # Import/export planning
│   ├── Emit/                # TypeScript file generation
│   └── Renaming/            # Name conflict resolution
├── test/
│   ├── scripts/             # Test scripts
│   ├── validate/            # Validation scripts
│   ├── baselines/           # Surface manifest baseline
│   └── fixtures/            # Test fixtures
└── docs/                    # Documentation

Build Commands

# Build
dotnet build src/tsbindgen/tsbindgen.csproj

# Build release
dotnet build src/tsbindgen/tsbindgen.csproj -c Release

# Run
dotnet run --project src/tsbindgen/tsbindgen.csproj -- <args>

Documentation

Related Projects

License

MIT