Local models take a while to respond, and that gets old when you’re sitting at your desk watching a spinner. I’ve been writing about putting a coding agent on every desk, adding a second GPU, and running a fast model in a sidecar. The models keep getting better, but I was still tethered to my desk waiting on them.
What I wanted was to start a task, walk away, and get a notification on my phone when the turn was done. Then I’d pick up where the agent left off from whatever device I had handy, with everything still running on my own hardware. So I built it, and as of this week there are pre-1.0 nightly builds you can run yourself. I also nerd sniped myself into the classic developer trap of buying a domain name for a hobby project, so it has its own home at openwebide.com.
Why Build It
Before this I was using Qwen Code or OpenCode for agentic work and Open WebUI for chat. They both work fine. Open WebUI is great for chat, but it can’t work in a git repo the way an agent can, and the terminal agents stay on the machine they’re running on. I wanted one thing that could do both jobs.
Having a homelab opens up some possibilities the other tools don’t take advantage of. The vendors call it “remote control” when you can pick up a session from another machine, and it’s a natural fit for a server that’s always on. In Open WebIDE everything about your session lives in the hosted SQL database: which projects you have open, which files and tabs, the agent’s conversation. Move to another device and it’s all just there.
Local models also mean there’s no token meter and no spend limit, so I don’t have to worry about accidentally running up a bill. I can hand the agent a long-running goal, go do something else, and check in from my phone every so often. That’s most of the fun for me. I can spin this stuff out without thinking about the cost.
It’s the same itch I was scratching in Rethinking Build vs. Rent, and honestly it’s closer in spirit to Please Learn to Do It Yourself. Open WebIDE is a hobby project. I’m not trying to replace Visual Studio or Rider, and it’s free to use. I built it because I like tinkering, and because it fits how I work.
The name is a nod to Open WebUI: it’s what you get when the chat window has a git client, a terminal, and an editor attached.
Rust All the Way Down
I’ve always been interested in WebAssembly, and I wanted to see how far I could push the performance to make a browser app feel native. I also wanted to install it as a PWA instead of writing Android, iOS, and desktop apps for every platform. And I didn’t want to default to React, TypeScript, and Electron, because those apps always feel heavy and memory-hungry to me.
The frontend and backend are both Rust compiled to WebAssembly, running on Spin. A small native bridge handles terminals, commands, Git, and agent runs that survive you closing the tab. Projects, sessions, and preferences live in SQLite, which is what makes resuming from another browser possible.
It felt native to me the first time I ran it on my phone as an installed PWA, with no browser chrome at all, and got a web push notification when the agent finished a turn. It’s also my second Rust homelab project in a row, after OBS HomeRun.
Local and Remote
Projects come in two modes. In remote mode, the repo lives on the host running Open WebIDE. That’s the “remote control” mode: start a run from your desktop and pick it up from your phone as turns complete.
In local mode, the repo lives on your own machine and the app reaches it through a paired bridge. It’s more constrained. If the project lives on a different machine, you can’t pick it up from your phone, because the files aren’t on the server. That only works in remote mode.
There’s also project-less chat, which is the Open WebUI-style experience: a plain conversation with no repo attached. Scheduled tasks live there too.
What’s in the Box
The agent reads, searches, edits, runs commands, and uses Git. Pending edits show up with Accept and Reject controls, and Shift+Tab cycles through approval modes from Manual up to YOLO. Around it there’s an editor with syntax highlighting, search, diffs, and Markdown and image previews, plus a Git pane with commit history and a terminal, all in one workspace.
Slash commands cover the usual things (/model, /test, /diff, /commit, /sync), and there’s live token and speed telemetry with a context-window gauge, which is handy when you’re working with small local context windows. It talks to Ollama and OpenAI-compatible servers like llama.cpp and LM Studio, so it works with whatever you’re already running.
For long-running work, /goal <objective> queues it on the host, and it keeps going with the browser closed. After each turn a separate model check decides whether the objective is met, and if it isn’t, another turn gets queued. A goal pauses for review on a blocker, an error, or after 100 turns, and tool approvals stay pending until you come back to decide them.
You can also schedule tasks, set up monitors that watch for a condition and tell you, and extend the agent with MCP servers. Host administration lets you point it at your homelab over SSH and ask the agent about the machine, with any changes proposed for your approval.
Plugins
Plugins are Rust compiled to WebAssembly components against a public SDK. They run on the host in a sandbox, with bounded memory and no ambient filesystem, environment, or network access, and they get what they need through scoped capability grants. A plugin can contribute agent skills, tools, read-only context hooks, durable events, and declarative workspace panels.
The built-in Web, Project Memory, Scheduling, and Skill Authoring plugins use the same SDK and the same grants a community plugin would. A marketplace is just a public Git repository with a catalog file, pinned to commits, so the official one is no more special than yours would be.
Panels are a versioned JSON UI schema instead of UI code the plugin runs, which is how I think of them as Slack’s Block Kit for the IDE. There’s a panel playground in the docs where you can drag blocks around, see the production components render them, and export the validated document along with Rust SDK examples.
Get the Nightly
There’s one channel until 1.0, and it’s nightly. Whenever main passes the full test suite and both platform image checks, the nightly image (amd64 and arm64) is published, and the downloads on the nightly release are refreshed to match. The package is public, so there’s nothing to authenticate.
Grab the Compose file from that release, drop it in its own directory, and it already points at nightly:
curl -LO https://github.com/openwebide/openwebide/releases/download/nightly/docker-compose.yml
mkdir -p ~/source
docker compose pull
docker compose up -d
Open http://localhost:8080/, register the first account, and use the Servers wizard to point it at your model server. Compose mounts ~/source as the workspace, and the agent can see everything in it, so think about what you want in there.
The biggest hurdle is that installing it as a PWA and getting push notifications both require HTTPS. I recommend Tailscale Serve in a separate container, which gives your phone a trusted https://<device>.<tailnet>.ts.net address with no custom domain or port forwarding. It’s all documented on the project site, and there are Podman Quadlet units for the systemd crowd.
What’s Next
It’s still pre-1.0. Most of the roadmap is polish: more UI refinement and a lot more work on the editor. I want LSP support, intellisense-style popups, and inline LLM features. The panel playground will get more blocks, and I’ll keep chasing down editor latency and memory use.
My bar for 1.0 is whether I can use Open WebIDE as the primary environment for working on Open WebIDE. It’s getting close to good enough to build itself, and when it crosses that line I’ll call it 1.0.
Until then I’ll keep tinkering.