Building Production Desktop GUIs in Julia at NASA with Dear ImGui and Mirage.jl
What if building an interactive scientific GUI in Julia didn't require a web stack, a server boundary, or a second language? We'll share how our team replaced a React frontend and Julia backend with a standalone Julia application for planning lunar rover routes at the Moon's south pole—rendering terrain, illumination, waypoints, solar exposure, and communications windows in one process.
The talk introduces a practical immediate-mode stack: Dear ImGui via CImGui.jl for responsive UI, and Mirage.jl for simple Canvas2D-style 2D and 3D rendering on OpenGL. Along the way, we'll cover the architectural tradeoffs, our REPL-driven workflow, and patterns applicable to geospatial viewers, simulation dashboards, instrument panels, and data-exploration tools. No graphics programming experience required.
When our team needed an interactive planning tool for lunar surface missions, we started with what seemed like the obvious approach: a React web frontend backed by a Julia server. It worked, but the developer experience was not ideal. Every piece of data had to be serialized over HTTP. UI bugs could live in JavaScript, Julia, or the communication layer between them. Adding a feature meant touching two codebases in two languages, as well as maintaining state in two different places using two different metaphors. Not to mention trying to do custom 2D / 3D rendering meant mixing React and HTML5 Canvas. For a small team, the overhead was becoming too much to maintain.
So we tried something different - build the whole thing in Julia. The result is a standalone desktop application for planning rover routes on the lunar south pole. The GUI renders terrain maps with sun illumination overlays, lets users place and adjust waypoints, and visualizes time-varying data like solar exposure and communications windows. One language, one process, no server.
The stack has two pieces:
Dear ImGui (via CImGui.jl) handles all the UI: windows, sliders, buttons, menus, tables. It's an immediate-mode library, which means every frame your code says "draw a button here, a slider there," and ImGui handles interaction. If your state changes, the UI reflects it next frame using Dear ImGui's immediate-mode model. No widget trees, no callbacks, no syncing. This is a good match for scientific tools where the interface evolves constantly.
Mirage.jl handles rendering. I wrote it because the available Julia OpenGL wrappers were too low-level for rapid prototyping. The API feels like HTML5 Canvas2D: draw_image(), fill_rect(), draw_circle(). It manages shaders and vertex buffers internally so you don't have to. I later added 3D mesh rendering following the same minimal, immediate-mode philosophy.
The immediate-mode approach has another real benefit beyond simplicity, one that is aligned with Dear ImGui. There's no retained state to go stale. Your render function is a function of your current application state, and your current application state are simply Julia variables. When we needed a new overlay or visualization, it is simply just a few draw calls in the right place.
But the biggest accelerator was the REPL workflow. Start the GUI from the Julia REPL, use it, close the window, change some code and see it update live. This turns GUI development into the same fast iteration loop Julia developers already use for everything else, and it's something you really can't get with compiled GUI frameworks. It brings the fast-paced iteration of the web ecosystem (like React) into Julia.
This stack is general-purpose. Any application that puts an interactive visual frontend on Julia computation could work this way: instrument control panels, geospatial viewers, simulation monitors, data exploration tools. The patterns are the same regardless of domain.
In this talk I'll cover:
- Why we moved away from a React/Julia split architecture and what we gained
- How Dear ImGui and OpenGL compose into an application framework in Julia
- How Mirage.jl maps Canvas2D-style calls to OpenGL
- A live demo of the tools in action
- Practical patterns for structuring a Julia GUI app, and the rough edges to watch for
No graphics programming experience needed.
Zach Booth Lead Software Engineer at the Automated Decision Making Group at NASA Ames Resarch Center working on SHERPA, strategic planning software for lunar rovers using MDPs and POMDPs. On the side, Zach develops indie games and loves to study financial markets.