PanGui - The Core Systems Are Ready
It's been almost three months since our last blog post, and in that time, PanGui has moved forward fast: 700+ commits, a long list of core systems brought into place, and a rapidly growing amount of applications and demos built with it.
The short version: the core systems are ready to be used. We now spend as much time building with PanGui as we do building PanGui - both at a scale and pace we haven't done before, and it finally feels like the right time to start showing what that actually looks like.
For the past several months, a huge amount of our energy has gone into foundational systems: layout, controls, text, rendering, and memory management. That work has now reached a point where the library feels solid, capable, and ready to be pushed much harder in practice - which also means we have started expanding access to the closed Alpha and are putting PanGui into the hands of more people.
This post is about where things are, what's been built, and how we're preparing for a bigger alpha.
Dev Update
Controls
Controls are a hard design problem. When trying to build a universal set of default controls for PanGui, we've been stuck between two conflicting priorities: first, the core of PanGui must be as simple and minimalist as possible and only solve the truly universal problems; and second, trying to build a truly universal set of controls quickly ends up in a very complicated and over-engineered place of trying to anticipate and plan for every possible use case across all industries. Even when we made them extendable, maximally overridable and stylable, it did not feel like the right solution. It felt like we were committing to something sub-par that tried to do everything, but wasn't great at anything.
So, we've chosen a third option: PanGui's core library will not ship with built-in controls at all. Instead, we will ship different default control packages specialized for different situations, to use as-is or to use as templates to work off of for your own custom variants. This lets us design a really amazing set of controls for each intended context: a game will have different needs than editor tooling, which has different needs than a mobile application, and so on.
It also creates an even stronger structural incentive for us to make PanGui's core as easy to build great controls with as possible, since we literally cannot take any lazy shortcuts this way. PanGui is already built to be open, and for every layer to build on top of the polished public API of the layer beneath it - but when all of our shipped controls are external to the core library, this reinforces these design principles and makes sure both that these core capabilities are very capable indeed, and that end-users have exactly the same access to them as we do.
New layout features
We added two new layout features that work well individually and are especially powerful together.
The Add syntax
You can now additively contribute size to a node:
1container.AddHeight(Size.Pixels(20), 0.9f);2container.AddHeight(Size.Percentage(1), 0.5f);3container.AddHeight(Size.Ratio(1), 0.2f);4container.AddHeight(Size.Expand(1), 0.5f);5container.AddHeight(Size.Fit, 0.5f);
Negative values subtract. The difference between LerpWidth and AddWidth is that lerp scales the current values down, while add stacks on top.
Size.PercentOf
Previously we had a hardcoded HeightPercentOf method. Now it's a first-class Size type, which means it composes with everything else - MinHeight, MaxHeight, lerping, and so on.
Together, these solve a category of problems that previously required passing layout results back into the layout system. A sliding tab group where the container height blends between the heights of different tabs, for example:
1using (gui.Node().ExpandWidth().FlowX().Height(0).Enter())2{3 foreach (var tab in tabs)4 {5 float tSelected = gui.SmoothLerp(tab == selectedTab ? 1 : 0);67 if (tSelected > 0)8 {9 LayoutNode tabLayoutNode = DrawTabContent(tab, tSelected);10 Size heightContribution = Size.PercentOf(tabLayoutNode, tSelected);11 gui.CurrentNode.AddHeight(heightContribution);12 }13 }14}
Scroll views
Scroll views were iterated on a lot during this period. The result is a system built around a tree of scroll views - each scroll view knows its parent, and operations like scrolling a focused element into view propagate recursively up the tree, even across different transform matrices. When an element gains focus through keyboard navigation, the scroll view it lives in scrolls to make it visible, and if that scroll view's container isn't visible in its parent scroll view, the parent scrolls too - all the way up. The current scroll view can always be accessed from anywhere through gui.State.CurrentScrollView.
Scroll views also track ScrollSource - a flag that tells you what caused the last scroll. Whether it was a mouse wheel, a scrollbar drag, a Space key press, an API call like ScrollToRect, or a child scroll view propagating up. This makes it straightforward to react differently to user-initiated scrolling versus programmatic scrolling.
Other scroll view additions include configurable scrollbar visibility (auto / always / never) per axis, Shift+Scroll for horizontal scrolling, Space and Shift+Space for page-at-a-time scrolling, IsContentOverflowing for knowing when a scrollbar should appear, and smooth animated scrolling with configurable speed.
Text
We replaced the old STB TrueType dependency with an optimized SDF rasterization pipeline and our own font parser. Baseline font hinting is now a smooth float instead of a boolean, so scrolling doesn't snap between hinted and unhinted states.
We also added a CreateRichText builder API. It lets you construct multi-styled text spans - different colors, fonts, and sizes within a single text block - using a simple builder pattern. You set properties, add sections referencing ranges of a source string, and then draw the result. It handles layout, word wrap, and cross-frame caching automatically. This makes it straightforward to build things like syntax-highlighted code views efficiently, or to lay the groundwork for a fully featured rich text editor. More on that in the future as well.
Drag and drop
We added a gui.DragAndDrop API. It's simple and payload-based: a source interactable detects a drag via IsDragging(), sets a typed payload with SetPayload, and a target accepts it with AcceptPayload. Payloads are type-safe and tag-identified, so different drag sources can coexist without conflict. You can also peek at payload data without consuming it, which is useful for showing drop previews. It integrates naturally with interactables - IsDragging() gives you a DragArgs struct with drag delta, accumulated distance, start position, and the mouse button used. It's a small API that gets the job done. We're hoping to get more feedback on it as more people start using it.
Onboarding, documentation, and AI skills
Documentation is well underway, and we've arrived at an onboarding workflow we're excited about.
We've been through many loops of putting an AI agent on building something with PanGui, reviewing its output, and then improving the documentation based on what it got wrong. As a result, the documentation is shaping into a tool for using PanGui - not just an API reference.
PanGui will ship with local documentation - a manual that lives alongside the library. You can browse it as HTML, and it's also crafted with metadata that distinguishes between content meant for human readers, content meant for AI agents, and content meant for both. This metadata is used to generate AI skills - structured knowledge files that AI coding environments can load automatically.
We can currently generate skills for OpenCode, GitHub Copilot, Claude Code, Cursor, and Codex. These are auto-discoverable: open PanGui in a supported environment and the AI can help you write layouts, build controls, set up tests, and navigate the API from day one.
Alongside the manual and a readme, we also built runme.cs - a single C# script file that serves as PanGui's project hub. You run it with dotnet run, and it gives you a full GUI for creating new projects from templates, installing the dotnet new pangui template, adding PanGui to existing projects, building standalone DLLs, generating AI skills for your environment, installing git hooks for test automation and skill regeneration, running the test suite, and browsing and launching demo applications. It's built entirely with PanGui itself.
And more to come
Not everything we've been working on is ready to be shown just yet. In particular, there are some things underway around accessibility and AI that we believe are going to be huge. We're not ready to go into detail on those yet, but we're excited to share more in a future update.
Beyond that, there is of course plenty of ongoing development that will continue alongside the alpha:
- A proper input command system.
- More work on text support - including better text shaping and emoji support.
- Finalizing the platform layer design.
- First-class support for effects and shaders - the goal is that you should be able to write any sort of fancy UI effect you want and build things like Shadertoy in PanGui. This one is tricky as it involves shader compilation and has requirements on the platform layer, but we'll get there.
- More work on retained mode and the styling system.
Things built with PanGui
As mentioned earlier in the post, PanGui's core systems are now in place. That has shifted a large part of our development from building PanGui itself to actively building with it, and it has been incredibly rewarding - and a lot of fun - to see all sorts of applications come to life.
We've been using PanGui to create a growing range of applications, demos, and internal tools. Some are hand-coded, some are designed to push specific parts of the library, and many were vibe-coded by AI agents as part of an ongoing iterative feedback loop: build something in PanGui, review the result, identify friction points, improve the documentation or the library, and then repeat.
That process has become an important way for us to validate the foundation, refine workflows, and uncover where PanGui still needs work. It has also made PanGui's strengths much easier to see in practice, which makes this feel like the right time to start showing more of it publicly.
Here are some of the things that have come out of that process.
Docking engine
Build style: Vibe coded
We vibe coded a docking system inspired by Raddbg's approach. Tab bars, resizable splits, drag-to-dock with drop zone previews. It demonstrates that this kind of complex layout interaction is very doable in PanGui.
Custom controls demo
Build style: Hand coded
As part of building an onboarding flow for new users, we wanted a demo that would let people jump straight in, explore PanGui, and interact with it hands-on. The result is a showcase of over 20 custom controls, each with a different aesthetic and interaction model: an Airbnb-style circular slider, eurorack synth knobs, a liquid progress bar, a compass widget, a radial cookie menu, game inventory grids, an ECG health monitor, neumorphic toggles, and more. Each control is rendered entirely with PanGui's drawing and layout APIs. The demo includes a code viewer sidebar so you can see exactly how each one is built.
PanGit - a git client
Build style: Vibe coded
PanGit was a small AI experiment by one of our developers, who wanted a quick way to keep track of commits and easily review changes. It was built almost entirely in a single AI prompt, and it's projects like this that have helped us improve the documentation that AI relies on as we turn it into skills.
Layout demo
Build style: Hand coded
An interactive layout playground for building layout hierarchies, tweaking every property, and seeing results in real time. Desmos-style animation sliders, presets, and resizable panels.
Small demos and Games
Build style: Vibe coded
We've also been building smaller toy demos - from a text-based adventure to a "pew pew" game - just to push animation, layout transitions, and interactivity in unexpected directions. These aren't serious applications, but they've been surprisingly useful for finding layout edge cases and animation bugs - and have honestly been incredibly fun to make.
We can share some of the source code for these projects if you come ask us about them on Discord.
What's Next
With the core in a solid place, it’s time to open the doors wider.
The focus now is getting PanGui into more hands, backed by the onboarding material and documentation needed to make that experience smooth.
We’ve already onboarded the first alpha wave, and it has been incredibly exciting to see people try PanGui, explore it, and begin forming their own impressions of what it can do.
From here, we’ll continue expanding the closed alpha toward an open beta. We’re handpicking candidates from the beta list to cover as broad a range of use cases as possible, while staying within the C# ecosystem and moving at a pace where we can properly follow and act on the feedback we receive.
So, if you haven’t already, sign up for the beta, leave us a message about your use case, and we’ll bring you in when it aligns with the current stage of development.
At the same time, work on the transpiler is actively underway, with the current goal of starting the C++ alpha when PanGui reaches open beta.
We’re excited to continue scaling the Alpha over the coming months and to see what you build with PanGui. As always, if you have questions or want to follow along, come join us on Discord.