Immediate Mode GUI

Have you ever wanted UI in your projects, but either cant find a library or dont want retained mode? Well heres something!

Example code:

That will produce this:
image

I do plan to extend this with other controls such as checkboxes, textboxes, or comboboxes.

What is “retained mode”??

There are two different types of UI - retained and immediate.

  • Retained uses a state of controls (e.g. a list of children.) This is what Snap! uses (Morphic!)
  • and Immediate stores almost no state, and the UI is determined by functions (blocks!) called every frame to draw, and variables the user made for the value of them. Note that even still you need some global state for interacting with the UI, but aside from that everything is variables the user controls.

what is this?

what is this?

A tree:

ROOT WORLD
  |
  | > Morph
  | |
  | | > Child...
  |
  | > AnotherMorph

Some state to store stuff like “did the mouse do down just this frame?” or “what control is hovered over”:

I have now added checkboxes. Now I’m going to make a theme system, and I’ll try to base the rest of my stuff over Dear ImGui

Thanks, that makes sense.

Got a theme system and improved everything, to a Dear ImGui style:

But.. averaging 100ms. 10 frames per second. This is horrible (I had to close every single other app on my computer for it to run, even at that, otherwise it would be like 150ms). Any optimization ideas? (maybe my computer is just bad.. but its Snap!, so you never know.)

Anyway, I’m still happy with what I’ve made so far!

It looks really cool! I might use this in my projects.
It could benefit from some documentation.
(Also, the demo broke)

Found the bug:


It wont work unless

Also, the reason you need to WARP the script is because the LET doesn’t have a warp in its definition.


It runs way smoother if you remove the warp from the forever and update it to

.

With that, it looks stellar :star_struck:
ScreenRecording2026-06-30185917-ezgif.com-video-to-gif-converter

The same error happened:

Way ahead of you, I found what was causing it

Well, using item of instead of field of works, saved.

Oh! That works better, however its still slow :D

No way! You made a UI engine before me! Absolutely astonished!

Though mine is "retained", while yours is "immediate".

Unfortunately, it is laggy for me. The frame time loves to average 200 ms for me.

the lag seems to me to be from the block copying from the ring creation in Process.prototype.reify, and the excess operations from the field [ v] @list @:> ::list reporter block, and the fact that snap’s not that fast

Microbenchmark - 10 labels on screen, 64 ms

Without let 11 ms. Much better but it’s still almost whole frame just to draw 10 labels.
Primitive write does the trick < 1ms.

BTW:
For trivial case field getter is 50 times slower them item with a key

Thank you for those ideas!
I have modifed my context write block to manually join the font family and size, as to skip the logic that the stats write block does, while still allowing font changes in the theme.
I have done several let → script variable changes, and that also improved the speed.
And then I also did a bunch of field → item conversions.

After all that, I’m proud to annouce:

It breaks above 30 FPS! Seems like now it does multiple “frames” in one Snap! thread frame. Fun!
Give me a bit while I do a bit more polish (and some docs!)

Fixed up, with rough documentation on the blocks! I’m really suprisied that the optimizations were THAT easy…

Also fixed up the slider grab part (now its contained within). I’m going to add a details control and probably a combo box also.