Open-source project
halildurmus/win32 avatar
halildurmus/win32

win32: calling Windows APIs from Dart without writing C++

Call Windows APIs from Dart.

848 stars136 forksDartBSD-3-Clause

At a glance

What is it?
The halildurmus/win32 monorepo bundles eight Dart packages that expose Win32 and COM APIs to Dart and Flutter programs, from raw FFI bindings up to type-safe wrappers for the Registry, Clipboard, gamepads, and file dialogs. It is the practical choice for Windows-only Dart work, and the wrong tool the moment your build has to run anywhere else.
Who is it for?
Adopt win32 when your Dart or Flutter code must reach Windows features that the platform layer does not cover, and pick the specific package that matches the API surface you need rather than the umbrella binding. Skip it for cross-platform products, and before committing check the exact package version you depend on, since win32 and winmd ship separately and their release dates differ by a day in the current set.
Can I use it commercially?
Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly Dart, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Eight packages in one monorepo, split by level of abstraction

The halildurmus/win32 repository is a monorepo, and the package table at its root is the fastest way to understand the design. The family runs from the raw edge to a friendly API. The win32 package is described as letting you call common Windows APIs directly from Dart using FFI. The winmd package deals with Windows Metadata files based on the ECMA-335 standard, which is how the lower level of the family stays tied to what Windows actually ships. Above that sit deliberately narrow packages: win32_registry for the Windows Registry, win32_clipboard for clipboard access, win32_gamepad for connected gamepads, and filepicker_windows, which uses common dialog controls rather than a bespoke picker. Two packages serve the build rather than the API: ffi_leak_tracker handles allocation tracking and leak detection for Dart FFI code, and win32_runner is a Dart runner for Flutter Windows apps. That layering is the core idea. A team that needs the Registry can adopt one small package and inherit nothing else, and the leak tracker can be pulled into an existing FFI codebase without dragging in a full API surface.

Why FFI bindings exist alongside the friendlier wrappers

Two access styles sit in the same repository, and the difference matters for review effort. Raw FFI bindings expose the Windows ABI to Dart, which means the calling convention, handle lifetime, and error semantics are yours to manage. The type-safe packages sit on top of that and present Registry keys, clipboard formats, and gamepad state as ordinary Dart values. The practical effect is that the low level package gives you coverage, and the wrappers give you a smaller chance of a memory mistake in the common case. The existence of ffi_leak_tracker is a telling detail. It exists because allocation tracking and leak detection are a real problem for Dart FFI code, not a hypothetical one, and the fact that the family ships a package for it tells you the maintainers expect people to use the raw bindings directly. A wrapper package is not a safe harbour if your own code also opens handles through the low level API, and you would want the leak tracker active in that case.

winmd ties the binding surface to Windows Metadata

The winmd package inspects and generates Windows Metadata files based on the ECMA-335 standard. This is the mechanism that keeps the family from drifting away from the operating system. Win32 is not a frozen header set; functions appear, get deprecated, and shift between versions of Windows, and hand maintained Dart bindings would track those changes slowly. Generating from metadata means the surface a Dart developer can call comes from a machine readable description of what Windows exposes. The trade-off is that the API you get is bounded by what the metadata describes. If a capability is not in the metadata for your target Windows version, no amount of wrapping produces it. The example files listed in the repository reflect that breadth and the variety of entry points: bluetooth.dart, bluetoothle.dart, com_context.dart, com_demo.dart, commdlg.dart, credentials.dart, customtitlebar.dart, dialogbox.dart, devices.dart, dispatcher.dart, dump.dart, dynamic_load.dart, events.dart, fileinfo.dart, filever.dart, fonts.dart, gamepad.dart, and guid.dart. Each is a distinct area of the Windows API being exercised from Dart, which is a fair indication of how much surface is reachable.

Where to get the packages, and what a first use looks like

The repository does not spell out a copy-and-paste install snippet, so the honest path is the distribution channel the project itself points at. Every package in the table links to its own pub.dev listing under the same name, so win32, win32_registry, win32_clipboard, win32_gamepad, filepicker_windows, ffi_leak_tracker, win32_runner, and winmd are added through pub the way any other Dart dependency is added. The project also maintains its own site at win32.pub, and the README links it for documentation, for examples, and for a packages listing, so that is where to read the API reference before you write a line of code against it. The example files sit in the examples directory of the repository itself, which means the fastest first use is to open the example closest to your task, read what it calls, and adapt it. A developer wanting clipboard access would read the win32_clipboard documentation first and then look for a clipboard-shaped example. A developer doing device discovery would start from devices.dart. The order matters: the API names in these bindings are long and Windows specific, and guessing them from memory is slower than reading the reference.

The platform boundary is the real limitation

Every package in the family is Windows specific, and this is the constraint that decides whether the project fits your product. The win32 package binds to Windows APIs. win32_runner exists to run Flutter Windows apps, with no C++ compiler required. filepicker_windows is named for Windows and uses common dialog controls, which have no meaning on macOS or Linux. A Dart application that must ship on more than one operating system cannot put a hard dependency on these packages in shared code, because the native symbol resolution is not available elsewhere. The usual pattern, and the one implied by the split into separate packages, is to keep platform-specific code behind an interface and let each platform implement it, with the win32 family serving the Windows implementation. The trade-off is that the Windows path now has a rich, typed vocabulary while the other platforms may have something thinner, and the abstraction layer that hides that difference is work you have to write and test. There is also no mention in the repository of a fallback or a cross-platform substitute for the Windows calls, so the abstraction cannot be a thin pass-through.

Leak tracking and the cost of unmanaged handles

Windows APIs love handles, and Dart FFI code that opens them has to close them. The ffi_leak_tracker package exists to give that work a measurement: it provides allocation tracking and leak detection for Dart FFI code. The sensible reading is that this package is aimed at the low level binding usage, where a missed release shows up as a handle leak rather than a Dart error. Once a project uses win32, win32_registry, or any of the other wrappers that ultimately call into native code, the question of who releases what becomes a review item, and a leak tracker turns a vague worry into a report. The counterpoint is that the tracker is a separate package, which means it is opt-in, and the project documents no policy for running it in a shipped build. If you add it, you are adding a dependency and a development workflow step that the upstream project has not tied to a release checklist.

Licence, releases, and the shape of maintenance

The family is released under BSD-3-Clause, the licence named in the repository metadata and in the badge set at the top of the README, with the full text in the LICENSE file at the root. That is a permissive licence with a retain-notice condition, and it is the kind of licence that usually causes no friction in commercial Dart and Flutter products. No legal advice is implied here, only the note that the licence travels with each package rather than being a separate grant. On the release side, the recorded versions are win32 v6.4.0 on 2026-08-05, winmd v7.1.1 on 2026-08-04, and win32 v6.3.0 on 2026-05-22. The last push was on 2026-10-21, and the repository is not archived. Note the shape of that: win32 and winmd version independently, so a project that depends on both is not moving through a single coordinated release, and a version constraint on one says nothing about the other. The upgrade cost is therefore per package, and the win32 line moved from 6.3.0 to 6.4.0 in under three months while winmd sat at 7.1.1.

Editorial conclusion

Adopt win32 when your Dart or Flutter code must reach Windows features that the platform layer does not cover, and pick the specific package that matches the API surface you need rather than the umbrella binding. Skip it for cross-platform products, and before committing check the exact package version you depend on, since win32 and winmd ship separately and their release dates differ by a day in the current set. Confirm the API you plan to call is present in the bindings for your target Windows build, because the family is generated against Windows Metadata and gaps follow the metadata, not the popularity of a function.

Frequently asked questions

What does the win32 Dart package let me do?

It lets you call common Windows APIs directly from Dart using FFI. The monorepo also ships type-safe APIs for the Registry, Clipboard, gamepads, and a Windows file picker built on common dialog controls.

Does win32 work on macOS and Linux?

Nothing in the repository describes cross-platform support. The packages are Win32 and COM bindings, and win32_runner is described as a runner for Flutter Windows apps, so the family is Windows specific.

Which packages live in the halildurmus/win32 monorepo?

Eight of them: win32, winmd, win32_registry, win32_clipboard, win32_gamepad, filepicker_windows, ffi_leak_tracker, and win32_runner. Each is published separately to pub.dev under its own name.

Do I need a C++ compiler to run a Flutter Windows app with win32?

The package table describes win32_runner as a Dart runner for Flutter Windows apps with no C++ compiler required. That removes one build step, though the apps are still Windows only.

Which licence does the win32 package family use?

BSD-3-Clause. The licence is identified in the repository metadata and the licence badge in the README, with the full text in the LICENSE file at the root of the repository.

Official sources

  1. halildurmus/win32 on GitHub
  2. License: BSD-3-Clause
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/halildurmus-win32.svg)](https://hysenlabs.com/projects/halildurmus-win32)

Was this useful?