A fast, tiny, trim/AOT-compatible UI toolkit with a Windows Forms-shaped API. Windows, buttons, labels and text boxes are real platform widgets (Win32, GTK) driven via P/Invoke; every other control is owner-drawn in the host platform's own visual style.
WinForms is a good API trapped on one operating system. NativeForms keeps the API — Form, Button,
a Controls collection, Click — and replaces what is underneath: real native widgets where the
platform has one worth using, owner-drawn controls in the host's own visual style where it does not.
The target is that a WinForms program should port by changing its using directives, and then look
like it belongs on whatever it is running on. docs/PRD.md tracks the distance still to go,
box by box, rather than leaving the gap to be discovered.
- The
System.Windows.FormsAPI surface — forms, controls, events, layout containers, docking - Real native widgets for windows and text-bearing primitives; owner-drawn controls elsewhere, in the host's visual style
- Windows and Linux/GTK backends today, with a macOS backend tracked in the PRD
- A large control inventory:
DataGridView, ribbon, scheduler, property grid, code editor, pickers, toasts - A demo gallery with a headless autopilot, which is what generates the screenshots below
dotnet add package Hawkynt.NativeForms # controls, layout, binding, theming
dotnet add package Hawkynt.NativeForms.Backends.Windows # add the platforms you ship on
dotnet add package Hawkynt.NativeForms.Backends.GtkEach backend is its own package, so an app carries only the platforms it targets — and a backend it
references but never registers is dropped again by the trimmer. The core package brings the
[GridEditable] source generator with it as a compile-time analyzer; nothing to reference, and no
reflection reaches the running app. Hawkynt.NativeForms.Backends.MacOS is published for the same
completeness, but every entry point still throws (see Status).
using Hawkynt.NativeForms;
using Hawkynt.NativeForms.Backends;
using Hawkynt.NativeForms.Backends.Gtk;
using Hawkynt.NativeForms.Backends.Windows;
BackendRegistry.Register(new Win32Backend());
BackendRegistry.Register(new GtkBackend());
var form = new Form { Text = "Hello", Bounds = new(0, 0, 320, 160) };
var button = new Button { Text = "Click me", Bounds = new(20, 20, 140, 36) };
button.Click += (_, _) => button.Text = "Clicked!";
form.Controls.Add(button);
Application.Run(form);MVVM, MVC and MVP are all first-class: ObservableObject, RelayCommand/RelayCommand<T> and a
reflection-free two-way PropertyBinding<T> live in Hawkynt.NativeForms.ComponentModel. See
NativeForms.Demo for a bound counter.
The bundled NativeForms.Demo is a tabbed gallery of every control. These are captured on Linux/GTK
by the demo's headless autopilot (--autopilot), which drives the whole gallery with synthesized
input and photographs it in-process:
More: docking drag overlays · the month scheduler · a modal MessageBox · a context menu. The full set lives in docs/screenshots/.
NativeForms lets you write desktop UI with the ergonomics of System.Windows.Forms — Form,
Button, Label, a Controls collection, Click events — on top of two rendering strategies:
- Real native widgets for the window and the text-bearing primitives:
Form,Button,Label,TextBox,MaskedTextBoxandRichTextBox. These are genuineHWNDs /GtkWidget*s, so caret, IME, selection and accessibility come from the OS. The platform's ownMessageBoxand common dialogs are used directly too, andTimer(a native timer source) andNotifyIcon(Windows tray only) are non-visual native resources. - Owner-drawn, native-themed for everything else — the lists, grids, trees, containers, menus and
the modern extras. They render through
IGraphicsusing anIThemepopulated from live OS colors, fonts and metrics, so they match the desktop without being OS widgets.
That split is deliberate: one owner-drawn implementation behaves identically on every backend, which
is what makes a DataGridView or a CalendarView possible at all. It is also why the toolkit is not
a drop-in for platform accessibility on the drawn controls yet. Promoting the controls that do have
a faithful native counterpart (check boxes, combo boxes, progress bars, …) onto real peers when their
properties stay inside what the platform widget supports is a tracked workstream — see
PRD §12.
It is built to be small and quick: reflection-free, IsAotCompatible, buffered peer state,
value-type geometry, and no per-frame allocation — kilobytes of managed overhead, not megabytes.
WinForms compatibility, honestly. The API is WinForms-shaped, not WinForms-cloned: porting is
mostly a namespace swap, but reflection-bound surfaces (DataBindings, DisplayMember) become
delegates, a few defaults differ, and legacy corners like MDI are deliberate non-goals. The
deviations are documented per control — start with the base-class list in
docs/controls/control.md;
every page whose control diverges carries its own "Differences from WinForms" section.
The full reference lives under docs/ — an architecture
overview, an MVVM & data-binding guide, a custom-control
authoring guide, an images, animation & custom cursors
guide, and one reference page per control (usage example, API tables, behavior
notes). What ships today:
Families are listed alphabetically, and so are the controls inside each one.
| Family | Controls (each links to its reference page) |
|---|---|
| App shell & notifications | InfoBar (inline banner) · NavigationView (collapsible side rail) · SegmentedControl · Toast (transient corner notification) |
| Buttons & toggles | Button · CheckBox · ColorPicker (SV/wheel mixer, RGB·HSL·HSV·CMYK tabs, eyedropper) · GridPicker (Office table-size chooser) · LinkLabel · RadioButton · SplitButton / DropDownButton · ToggleSwitch |
| Containers & layout | Accordion · DockPanel · Expander · FlowLayoutPanel · GroupBox · Panel (AutoScroll) · Ribbon · SplitContainer · TabControl · TableLayoutPanel · ZoomPanel (wheel-zoom / drag-pan canvas) |
| Data grid | DataGridView — virtualized, 15 column kinds, editing, sorting, frozen columns, reorder, merged rows, clipboard copy/paste |
| Editors & inspectors | CodeTextBox (gutter, tokenizer, completion) · PropertyGrid (typed rows, attribute-driven via source generator) |
| Labels & media | IconLabel (image and text) · ImageList (icons + badges) · Label · PictureBox |
| Lists & trees | CheckedListBox · ComboBox · ListBox · ListView (5 views, groups, virtual mode) · TreeListView · TreeView |
| Menus, toolbars, status | Breadcrumb (Explorer navigation bar) · ContextMenuStrip · MenuStrip · NotifyIcon · StatusStrip · ToolStrip · ToolTip |
| Non-visual | Application & backends · Control base class · Timer |
| Paths | FilePicker (open/save, filters, multi-select) · FolderPicker |
| Ranges & dates | DateTimePicker · HScrollBar / VScrollBar · MonthCalendar · ProgressBar (incl. marquee) · ProgressTile (Explorer-style drive tile) · RangeSlider (two-thumb) · TimePicker (double-click for the analog ClockFace) · TrackBar |
| Scheduling | CalendarView — Outlook-style Day/Work Week/Week/Month scheduler, virtualized, side-by-side overlap packing, all-day band, "now" line |
| Text & input | DomainUpDown · MaskedTextBox · NumericUpDown · RichTextBox · SearchBox · TextBox · TokenBox (tag/chip input) |
| Windows & dialogs | Form (modal, border styles, window state, icon, topmost, opacity) · MessageBox + file/folder/color/font dialogs |
NativeForms.Demo doubles as a tabbed gallery showing every one of these controls with
representative property settings, plus the MVVM counter wiring.
docs/PRD.md is the authoritative checklist of every control and feature — per-control
acceptance criteria (§7), the milestone roadmap (§10), and the tested/demo-ed/documented coverage
matrix (§11). The control inventory above is implemented and tested on Windows and Linux; the PRD
tracks the rest box-by-box: the focus model, DPI/dark-mode live switching, accessibility, the macOS
backend, native-peer promotion (§12), and the items it explicitly marks later/optional.
Hawkynt.NativeForms Core: controls, layout, events, data-binding (no native code)
Hawkynt.NativeForms.Backends.Windows Win32 via [LibraryImport] — shipping
Hawkynt.NativeForms.Backends.Gtk GTK 3 via [LibraryImport] — shipping
Hawkynt.NativeForms.Backends.MacOS Cocoa — NOT IMPLEMENTED (stub)
Core never calls a native API; it drives platform peers through IPlatformBackend. An app
registers the backends it ships — both for "one binary, every platform", or just one to shrink a
single-platform build.
Platform support today: Windows and Linux. macOS is a future vision, not a shipped feature —
NativeForms.Backends.MacOS is a stub whose every member throws PlatformNotSupportedException with
an actionable message. Nothing renders on macOS yet. The Cocoa/AppKit implementation (NSApplication,
NSWindow, NSButton, NSTextField over objc_msgSend) is planned in
PRD §10, milestone M9.
dotnet build NativeForms.sln -c Release
dotnet test NativeForms.sln -c Release
dotnet run --project NativeForms.Demo # needs GTK 3 on Linux; native on WindowsIf this project saves you time or money, consider supporting its development:
Licensed under LGPL-3.0-or-later — see LICENSE.














