The Odin app framework for polished native and web desktop tools—without Electron.
Open the interactive WebAssembly/WebGPU gallery
Ingot is a self-contained immediate-mode framework built on Odin's bundled
vendor:wgpu. One renderer targets macOS/Metal, Windows/D3D12, Linux/Vulkan,
and browser WASM/WebGPU. GLFW remains the default native host backend; install
SDL3 and pass -define:INGOT_GFX_SDL3=true to select the optional SDL3 host.
- Native and web builds from one source
- Immediate-mode UI for desktop tools
- Bounded named commands and contextual keyboard shortcuts
- Bounded raw mouse, touch, and pen events with caller-owned behavior
- Batched 2D graphics, input, audio, networking, accessibility, and terminals
- Event-driven rendering with near-zero idle work
- Deterministic, bounded test harnesses
[!IMPORTANT] >
0.1.7is the latest source tag for a young0.xAPI. Pin an exact revision and validate every platform your application ships on.
Ingot explores whether deterministic simulation testing can shape an application framework from the start. Explicit state, bounded work, and compile-gated seams let seeded harnesses exercise production code without requiring a window, GPU, network, shell, or assistive technology. This is an engineering experiment—not a claim of correctness or production readiness. See Testing.
Use ingot:fit for applications and ingot:gfx for graphics-first programs.
ingot:ui and managed ingot:ui_gfx hosts are advanced application layers.
Optional networking, terminal, engine, and accessibility packages compose
through explicit imports; there is no umbrella runtime profile.
git submodule add https://github.com/Nic-vdwalt/ingot.git libs/ingot
git -C libs/ingot checkout 0.1.7
odin build src -collection:ingot=libs/ingotUse the Odin revision recorded in ODIN_VERSION.
The recommended
entry point for UI applications is ingot:fit:
package main
import "core:fmt"
import fit "ingot:fit"
App_State :: struct {
button_clicks: u64,
}
app: fit.App
state: App_State
main :: proc() {
_ = fit.Run(&app, {width = 960, height = 640, title = "Ingot app"}, Draw, &state)
}
Continue :: proc(user_data: rawptr) {
assert(user_data != nil)
state := cast(^App_State)user_data
state.button_clicks += 1
}
Draw :: proc(builder: ^fit.Builder, user_data: rawptr) {
assert(builder != nil && user_data != nil)
state := cast(^App_State)user_data
root := fit.Center(builder, {gap = .SM, padding = .LG})
fit.Label(root, "Hello from Ingot")
fit.Label(root, fmt.tprintf("Button clicks: %d", state.button_clicks))
fit.Button(root, "continue", "Continue", fit.action(Continue, state))
}See the layout guide for responsive Flow, track Grid, sizing,
and placement options. Larger applications can optionally converge buttons,
menus, shortcuts, and integration completions on a caller-owned bounded typed
queue; the direct Action API above remains the shortest primary path. See
Commands and contextual shortcuts and
examples/typed_commands.
Advanced applications that need direct control over UI state and rendering can
use the lower-level ui and ui_gfx packages. These expose more lifecycle and
layout details than fit, so the application assumes more integration
responsibility:
package main
import "core:fmt"
import ui "ingot:ui"
import "ingot:ui_gfx"
App_State :: struct {
button_clicks: u64,
}
app: ui_gfx.App
state: App_State
main :: proc() {
_ = ui_gfx.app_run(
&app,
{
width = 960,
height = 640,
title = "Ingot app",
session = {semantics_enabled = true},
},
{ui = Draw},
&state,
)
}
Draw :: proc(app: ^ui_gfx.App, form: ^ui.Ui, user_data: rawptr) {
assert(app != nil && form != nil && user_data != nil)
state := cast(^App_State)user_data
ui.padding(form, .LG)
ui.label(form, "Hello from Ingot", ui.ui_frame_metrics(form.frame).FONT_SIZE_TITLE)
ui.label(form, fmt.tprintf("Button clicks: %d", state.button_clicks))
if ui.button(form, "continue", "Continue") {
state.button_clicks += 1
}
}Run an example:
odin run examples/gallery -collection:ingot=.- Widget gallery
- Builder controls example
- API map
- Why immediate mode
- Choosing Ingot
- Examples
- Widget benchmarks
- End-to-end performance evidence
- GUI parity target
- API layers
- Commands and shortcuts
- Widget reference
- Choosing a widget
- Dependencies and package composition
- Performance evidence
- Pointer input
- Borrowed UI ideas
- Text and asset dependency policy
- Testing
- Compatibility
- Rendering
- Networking
- Migrating from raylib
- Production readiness
See Contributing, Security, and the Changelog. Licensed under Apache 2.0; bundled works are listed in Third-party notices.
