Go SLAY

Enjoy making utility style gui apps

SLAY is a Go framework to create GUI applications.

SLAY is still work in progress!

Immediate mode

Practical experience has shown that an immediate mode API is the only sane way to build GUI applications.

No one wants to write code to keep track of UI widgets and bidirectionally mirror their state with their application data.

Unfortunately, there's a lot of misunderstanding about what immediate mode means, so let's clarify what it means for SLAY.

No widget state management

Your code does not need to care at all about UI widgets. You want to display a button and perform some action when it's clicked. You want to iterate some list and for each item render a custom view with buttons, labels, and various elements.

When your data changes, you don't want to track all the previously created widgets and mutate them manually to put them in sync. You just render the view again.

Widget state is managed by the system

Just because you don't manage widgets, doesn't mean they don't exist. The system knows about widgets and keeps track of their state for you. This means the system knows which elements can receive focus, so it can support cycling focus via the 'tab' key. It keeps track of text input fields so it can position the cursor, animate, apply selection, cut and paste, etc.

UI elements are assigned an automatic id based on their placement in the UI hierarchy, but the caller can override this by supplying their own ids.

When you supply an id for an element, it must be unique and stable.

Unique means no two elements produced in the same frame can share the same ID.

If two elements in the same view are assigned the same ID, the UI will behave erratically.

Stable means that you can use string literals, but should not use strings created dynamically on the fly.

Animations

SLAY creates snappy animations when the UI state changes across frames, all without any boilerplate code on the caller side.

The animations are based on the IDs. If the position, size, or color of an element changes across frames, this change will be animated.

This can be used to create interesting transition from list page to detail page.

The only requirements is to set the element IDs accordingly.

Demo

This is a demo of this principle in action.

Since the list is dummy, there isn't even a real list of items, just a counter, with a custom type used to create a stable id.

The application side code of this demo is not even 100 lines.

Let's take a look.

First, notice the setup code is nearly non-existent. The only thing you need to provide is a root view function.

Next, let's look at the main list view.

The code builds the UI hierarchy by calling the Layout function, which can be thought of as a <div> element if you want to think of an analogy to the DOM. It opens up a container, and when you call Layout inside it, it will become a child container of it.

The important thing to notice here how immediate mode UI code looks like.

It's just regular code.

It's even better than JSX, because you can mix in if statements and for loops.

Next, let's look at the code for the item list and detail "view" functions.

Since this is a dummy view, there isn't much. Just two dummy rectangles at different sizes.

What matters is that we use a stable id that identifies each element. Again since this is a dummy element and there isn't even any data behind it, we use a custom int type.

In total, the code is less than 100 lines!

Work in Progress

SLAY is still work in progress.

The "API" surface you saw in the above demo is tentative and subject to change.