@microsoft/dynwinrt-codegen

September 15, 2026 · View on GitHub

Generate typed JavaScript + TypeScript bindings for Windows Runtime (WinRT) APIs from .winmd metadata.

Pair this with the @microsoft/dynwinrt runtime to call modern Windows APIs (WinAppSDK, Windows AI, notifications, storage, networking, …) directly from JavaScript / TypeScript — full IntelliSense, no native build step, no C# projection, no per-Windows-version recompile.

Why use this?

Until now, the choices for calling a Windows API from Node.js or Electron were:

  • Write a C++ node-addon-api addon — needs node-gyp, MSVC, Python, the right Windows SDK, and a CI matrix per Electron version.
  • Write a C# addon via node-api-dotnet — needs the .NET SDK, a csproj build step, and a hand-maintained C# wrapper for every API surface.
  • Wait for an official projection — Windows ships .winmd metadata months before a JavaScript-friendly projection appears.

dynwinrt-codegen reads the same .winmd metadata the Windows SDK already ships and emits typed JavaScript + .d.ts wrappers that call WinRT through @microsoft/dynwinrt at runtime. There is no native build in your Electron / Node project. You generate the bindings once, commit them (or regenerate on demand), and import them like any other module:

import { LanguageModel, LanguageModelOptions } from './bindings/winrt';
const model = await LanguageModel.createAsync();

You get IntelliSense in your IDE, type errors at tsc time, and the underlying COM call dispatched dynamically at runtime — no MSBuild involved.

dynwinrt-codegen primarily targets data-style WinRT APIs (AI, storage, notifications, networking, globalization, …). It also generates WinUI Application + Window helpers and public composable classes; the application must provide an STA UI thread, Windows App SDK bootstrap or package identity, and lifecycle management.

CLI usage

npm install -D @microsoft/dynwinrt-codegen @microsoft/dynwinrt

# A single class (auto-detects the Windows SDK winmd)
npx dynwinrt-codegen generate \
  --namespace Windows.Foundation \
  --class-name Uri \
  --output ./generated

# An entire namespace
npx dynwinrt-codegen generate \
  --namespace Windows.Web.Http \
  --output ./generated

# A custom .winmd (e.g., a WinAppSDK NuGet package or your own SDK)
npx dynwinrt-codegen generate \
  --winmd "C:\path\to\Microsoft.WindowsAppSDK.AI.winmd" \
  --output ./generated

Flags

FlagDescription
--winmd PATH[;PATH...]Path to .winmd file(s) (auto-detects Windows SDK if omitted)
--folder PATHDirectory containing .winmd files
--namespace NAMESPACEMetadata namespace to generate (omit for all non-Windows.* namespaces)
--class-name CLASSSpecific classes, interfaces, or native Apis containers (comma-separated; transitively pulls in dependencies)
--ref PATHAdditional .winmd files for type resolution only (no code emitted)
--lang LANGjs (default, emits .js + .d.ts) or py (Python)
--output DIROutput directory (default ./generated)
--dry-runValidate input, don't write files

What gets generated

For each WinRT class, the codegen emits:

  • A typed wrapper class with properties and methods using camelCase JS conventions
  • JavaScript constructors for unambiguous public default, factory, and composable activations
  • The original factory methods (.create(...), .createInstance(...)) for compatibility
  • An interface registration (DynWinRtType.registerInterface()) wired to the COM vtable
  • A JavaScript-backed IElementFactory.create() helper for WinUI ItemsRepeater realization and recycling
  • Promise-based async operations, with .progress(cb) on operations that expose WinRT progress
  • Generic collections (IVector<T>, IMap<K,V>, IIterable<T>)
  • Creatable observable vectors that expose both IObservableVector<T> events and IVector<T> mutation helpers
  • Structs with pack/unpack helpers
  • Enums (Object.freeze'd in JS, enum in .d.ts)
  • Delegate types (IID + parameter signatures) for event handlers
  • An index.js + index.d.ts re-exporting every emitted symbol from one place

Classic COM generation from Windows.Win32.winmd is available as a preview. Only interfaces with complete validated ABI, layout, ownership, and cleanup contracts are emitted under the generated com/ subpackage; unsupported interfaces fail closed. See the Classic COM usage guide.

Flat Win32 DLL exports

Generate namespace-organized JavaScript modules and TypeScript declarations from Windows.Win32.winmd by selecting an Apis container:

npx dynwinrt-codegen generate `
  --winmd $env:DYNWINRT_WIN32_WINMD `
  --class-name Windows.Win32.System.Registry.Apis `
  --output .\generated

Generated modules live under win32/ and use @microsoft/dynwinrt/win32, separately from WinRT and Classic COM. Metadata and explicit contracts validate native layout, buffers, ownership, and lifecycle requirements; unsupported exports produce diagnostics. Supported wrappers include managed resource cleanup and IOCP-backed asynchronous file I/O. Subsystem initialization remains explicit, with lifecycle DLLs loaded on demand. See the Win32 capabilities and contract boundary and JavaScript samples.

Platform

  • Windows only (x64 / arm64) — the binary is built per architecture and selected automatically by the npm install
  • The generated bindings depend on @microsoft/dynwinrt at runtime

License

MIT