Knots - A library for building GUIs with Zig

Hi! In this post I briefly mentioned an immediate-mode GUI library I was working on, that is being used to build a watch-party MPV client. I wanted to make a more detailed post sharing more about the GUI library knots which i find myself spending more and more time on. knots is an immediate mode GUI rendering library/framework (I don’t like the idea of a framework but I think it makes it more clear that it handles more than just putting stuff on the screen).

You might already be familiar with projects like dvui (awesome project, you should check it out), and while there is definitely a large overlap in terms of features I would say the main differentiator between knots and dvui are the goals. dvui is a lot more “general-purpose”, from their README: “GUI toolkit for whole applications or debugging windows in existing apps/games.”. The current scope of knots is a lot slimmer/focused, I am mainly interested in providing a way for people to build really performant cross-platform standalone desktop applications, where “UI code” is essentially out of the way entirely, so you can spend more time on solving “real” problems. I.e, if you are looking for a library that lets you easily create a debug UI for your game engine, or really render anything on top of an existing application/surface, knots is not for you, and will likely never be. It goes without saying that this library is in very early stages, (I just recently decided to stop force pushing on to the initial commit, as I was making massive overhauls to parts of the library every other day). Particularly, you will find many basic widgets/components to not be implemented yet, as I am still putting most of my focus on trimming down the main core of the library.

Below are just some questions and answers I think most of you might have:

  • What platforms are supported?
    • Windows, macOS, Linux, and web via emscripten + webgpu
  • Any examples?
    • Like I mentioned before, this mpv client shaven is being built with knots. You can also clone the knots repo and run some of the examples, or test the playground app on the web Playground!
  • What are you currently working on?
    • I am trying to get rid of all my c/c++ dependencies, to trim down compile times and binary sizes. I used to depend on GLFW for windowing but have now dropped it in favor of platform specific implementations which have been implemented for windows, macOS (partially), and emscripten/web. Linux builds unfortunately still depend on GLFW. As of this PR, I deleted harfbuzz as a dependency as I was not using any of its features anyways, and it was pulling all kinds of garbage like libc++, this open PR will drop freetype as a dependency in favor of https://codeberg.org/andrewrk/TrueType (built by Andrew Kelley!) to remove the final C dependency. After that, I will likely spend some time improving how text is handled in the layout module, to support text wrapping and other niceties.
  • Cross platform GUI rendering? How?
    • This is particularly important to get right and I took some risks here which might have repercussions in the future. I bet essentially on two APIs, WebGPU and Vulkan. Why these two? Well I always wanted to have the door open for supporting web, and to do that I would need to either support WebGL or WebGPU, afaik WebGL is planned to be superseded by WebGPU, and while WebGPU will potentially not work on some browsers, I am fine with that knowing they will eventually support it. I also get the added benefit of WebGPU acting as a “catch-all” GPU API which can be used when targeting native builds as well. This means you can build knots with only the WebGPU backend and be able to target Windows, macOS, Linux and Web! So why also support Vulkan? I wanted to leave the door open for opting in to even better performance for native builds, and Vulkan seemed to be the best choice here for performant cross-platform graphics. I honestly can’t see myself maintaining more than 2 GPU backends, so it is likely this will not change any time soon. Also, the WebGPU backend for native builds depends on wgpu-native being statically linked to the binary, which bloats binary sizes quite a bit (however, ensure it will run on a lot more machines).

Okay, I rambled quite a bit now and need to get back to work, please let me know if you have any more questions/concerns. This is not really an ad, as I still think the library is far from being useable for production apps. I am just more interested in what people think, am I wasting my time, or is it something you would be interested in?

17 Likes

Just wanted to post some updates here for people interested:

  • Playground web build is now hosted on codeberg pages, here: Playground
    • Web wasm build is down to 1.93 MB (900KB compressed), with about 400KB of the uncompressed data being just the font ttf. I want to get this even lower, potentially by dropping emcc as a build dependency, but will require some work to support wasm-freestanding as a target currently.
  • Some new components added
    • Color picker
    • Checkbox
    • Multi-line text input
    • Virtual list
    • General improvements to all existing components
  • The theme system got some upgrades, the theme can now be defined as a .zon file, an also changed at runtime. Themes are checked at compile theme for errors (invalid hex, rgba e.t.c). You can view the existing ones that come with knots here https://codeberg.org/shahwali/knots/src/branch/main/src/ui/themes
  • The vulkan backend vertex shaders are now written in Zig, and compiled using Zig, I wrote about it here: Writing Compute Shaders In/With Zig - #13 by shahwali
  • Text word wrapping added.
  • Grid layout support added.
  • The renderer settings/dev tools got an upgrade, now with some more stats, and even a sparklines graph!

Still so much to do…, below is a screenshot of as much I could possibly pack in one frame on the playground app. Would like to write some docs when I have time, mostly to free up some space in my head but also if anyone else is willing to try knots out, at your own risk of course.

12 Likes