@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-apiaddon — needsnode-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, acsprojbuild step, and a hand-maintained C# wrapper for every API surface. - Wait for an official projection — Windows ships
.winmdmetadata 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
| Flag | Description |
|---|---|
--winmd PATH[;PATH...] | Path to .winmd file(s) (auto-detects Windows SDK if omitted) |
--folder PATH | Directory containing .winmd files |
--namespace NAMESPACE | Metadata namespace to generate (omit for all non-Windows.* namespaces) |
--class-name CLASS | Specific classes, interfaces, or native Apis containers (comma-separated; transitively pulls in dependencies) |
--ref PATH | Additional .winmd files for type resolution only (no code emitted) |
--lang LANG | js (default, emits .js + .d.ts) or py (Python) |
--output DIR | Output directory (default ./generated) |
--dry-run | Validate 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 andIVector<T>mutation helpers - Structs with
pack/unpackhelpers - Enums (
Object.freeze'd in JS,enumin.d.ts) - Delegate types (IID + parameter signatures) for event handlers
- An
index.js+index.d.tsre-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/dynwinrtat runtime
Links
- 📦
@microsoft/dynwinrt— the runtime the generated code targets - 🐛 Source on GitHub — issues, contributions, internal design docs