Iris - Immediate Mode UI library, based on Dear ImGui

Try the demo: Iris - Demonstration - Roblox

Iris

Iris is an Immediate mode GUI Library for Roblox, Based on Dear ImGui. It solves the same problems as Dear ImGui. It is fast, portable, and self-contained (no external dependencies).

what is Dear ImGui, and why is it important?
Dear ImGui is best known for its use for developing debug UI. Using the Dear ImGui paradigm (Immediate Mode), UI is remarkably easy. Because of this, Dear ImGui has seen adoption in almost every major game engine, including Unity and Unreal Engine (and now Roblox!).

Iris favors simplicity and productivity; It is designed to simplify UI, streamlining the process for creating visualization, debug tools, and data input. To accomplish this, Iris offers a different approach to Roblox UI than existing libraries, lacking certain features commonly found in more intricate UI libraries. Iris opts to supercede the Roblox UI API, instead having a streamlined Immediate-Mode library and a set of widgets whcih developers can use to create UI easily.

Usage

The Iris release comes as an rbxm or zip file. You can import the rbxm into any roblox project, and begin creating UI in any client side script. No external dependences are needed. Iris can be used in any kind of Roblox UI, including PlayerGui, CoreGui, BillboardGui, SurfaceGui, and PluginGui.

Heres a basic Example:

local StarterPlayerScripts = game.StarterPlayer.StarterPlayerScripts
local Iris = require(StarterPlayerScripts.Client.Iris).Init()

Iris:Connect(function()
    Iris.Window({"My First Window!"})
        Iris.Text({"Hello, World"})
        Iris.Button({"Save"})
        Iris.InputNum({"Input"})
    Iris.End()
end)

simpleDarkExample

And a more complex Example:

local StarterPlayerScripts = game.StarterPlayer.StarterPlayerScripts
local Iris = require(StarterPlayerScripts.Client.Iris).Init()

Iris:Connect(function()
	-- use a unique window size, rather than default
	local windowSize = Iris.State(Vector2.new(300, 400))

	Iris.Window({"My Second Window"}, {size = windowSize})
		Iris.Text({"The current time is: " .. time()})

		Iris.InputText({"Enter Text"})

		if Iris.Button({"Click me"}).clicked() then
			print("button was clicked")
		end

		Iris.InputColor4()

		Iris.Tree()
			for i = 1,8 do
				Iris.Text({"Text in a loop: " .. i})
			end
		Iris.End()
	Iris.End()
end)

complexDarkExample

The appearance of Iris is fully customizable, including colors, fonts, transparencies and layout. By default, Iris comes with a dark theme and light theme, as well as 2 layout themes.

Iris.UpdateGlobalConfig(Iris.TemplateConfig.colorLight)
Iris.UpdateGlobalConfig(Iris.TemplateConfig.sizeClear)

Iris:Connect(Iris.ShowDemoWindow)

simpleLightExample

Finally, Iris comes with a demo window, Iris.ShowDemoWindow. This window demonstrates the functionality of every part of the library, and contains useful utilities, like a style editor and a runtime information window. It is a useful reference for you and other coders can to refer to.

How it Works

Iris is an immediate mode UI library, as opposed to retained mode.

In a retained mode model, you might make a button and connect a clicked event, with code that is invoked when the event happens. The button is retained in the DataModel, and to change the text on it you need to store a reference to it.

But in an immediate mode model, call the button function and check if it’s been clicked immediately, and you do that every single frame (60 times per second). There’s no need for a clicked event or to store a reference to the button.

Check out the Dear ImGuis About the IMGUI paradigm section if you want to understand the core principles behind the IMGUI paradigm.

Credits

Developed By Michael_48, SirMallard and JakeyWasTaken. Inspriation and design: Omar Cornut, Evaera, Thanks!

362 Likes

I like the example uis, very similar-ish.

6 Likes

Thanks! The widgets are made to look and feel as similar to Dear ImGui’s as possible.

3 Likes

can you open source the game? it would be great if you did!

3 Likes

Absolutley! The place’s source should now be available. I also added the place file (.rbxl) in the releases page

1 Like

Docs for the library are now available at: https://SirMallard.github.io/Iris

2 Likes

Nice module! Albeit there’s one big issue: Game UI can and will appear on top of the windows:
image

2 Likes

Thanks for letting me know! I just commit the fix for this in Iris v1.0.1 -
config.DisplayOrderOffset allows the user to customize the DisplayOrder of Iris Windows, relative to the rest of the UI. The default value is now 127, and can be increased or lowered if necessary.

1 Like
What I was originally going to post

This is an amazing UI library, however, I receive a lot of type warnings in my scripts:

image

I’m not sure if there’s something I may have overlooked? (This doesn’t affect the actual functionality of the library)


After looking around in the source code for a few minutes, I noticed that the parameters use (typename | nil) as opposed to (typename?). The former makes it manual that the developer needs to inserts nil into the argument list in order to satisfy the type requirement but the latter doesn’t require the developer to manually insert nil.

TL;DR: (typename | nil) ≠ typename?

I fixed one of the type warnings in the script by changing the parameter list to:

Which silenced the type warning for Iris.Init:

image


Other than that, once again, this is a fantastic resource!

3 Likes

I wasn’t able to replicate the type warnings for Iris.Window or Iris.Text but nonetheless the typings should be fixed for v1.0.2. Thanks for letting me know!

2 Likes

I looked through the examples again and the other type warnings were my own fault as I was calling Window and Text from the ModuleScript itself instead of from the returned value of the Init function

3 Likes

I’m definitely planning on using this but how would I go about adding my own widgets such as a color picker? Although it seems pretty easy to use, it would be very helpful to have some docs to refer to. Also what would be the correct way to scale a window?

2 Likes

Creating custom widgets is a pretty elaborate process, so right now i am working on a docs page specifically on that topic.
As for scaling a window, you can use the size field of the Window’s State.

local myWindowSize = Iris.State(Vector2.new(300, 400)) -- can be any value
Iris.Window({"Window"}, {size = myWindowSize})
Iris.End()

to change this value from your code, you can use the :set() method of State

if Iris.Button({"Change Window Size to 250, 250"}).clicked then
    myWindowSize:set(Vector2.new(250, 250))
end

to disable users of the window from resizing the window you can enable the NoResize field of Window’s Arguments

Iris.Window({"Window", [Iris.Args.Window.NoResize] = true})
Iris.End()
3 Likes

Loving this resource so far, my only complaint is when you respawn your ui disappears permanently. Is there a way to toggle that or is it an unintended feature?

4 Likes

Great job, looks clean and accurate. A nice addition would be graphs.

4 Likes

I suggest turning off the screen gui’s ResetOnSpawn property

3 Likes

Great library!

For anyone that does not certainly like how this library formats, I can show you a way to format your iris code:

Iris.Window{"First Window"} do
	Iris.InputNum{"Hello, World"}
	Iris.Button{"Save"}
end Iris.End()

By putting a “do” after creating windows and tables and such it will add an end which makes lua format it nicely! This also makes your iris code feel more like lua if you will.

9 Likes

Did you really post a exploit gui framework on the devforum :sob: cool library but wild

4 Likes

So I’ve looked into the incorrect button formatting problem, and the source of the issue is actually very interesting.

Iris uses as few formatting updates as possible, so when text is updated its actually the Button Instances’ AutomaticSize property which adjusts the size of the Button.

I think the intentions of the AutomaticSize code were to consolidate updates to size, but the behavior is very strange (this is all that i can understand from what i’ve tested):

  1. Strings with only 1 or 0 sequence of whitespace will not update AutomaticSize When their whiespace is increased or decreased
    abcdef → abc def
  2. Strings with only 1 whitespace character will not update AutomaticSize when an even character is appended or an odd character is removed
    abc dd → abc eee

Because this is a bug with Roblox’s UI, I’m not sure that i can reasonably patch Iris to mitigate it, but thanks for mentioning it!

2 Likes

Just fixed this! check the releases for Iris v1.0.3

2 Likes