Building a Lightweight Web IDE
I needed a web IDE that runs smoothly on a Raspberry Pi 4. The popular option, code-server (which is VS Code in the browser), uses 300-400MB of RAM just sitting there doing nothing. Since my Pi only has 4GB of RAM in total, that is too much. So, I decided to build my own web IDE that only uses around 30MB.
Why Not code-server?
| RAM idle | 300-400MB |
| Bundle size | ~80MB |
| Startup | 3-5s |
| Extensions | Full VS Code |
| RAM idle | ~30MB |
| Bundle size | ~250KB |
| Startup | <1s |
| Features | File editor + Terminal |
Seeing code-server eat up hundreds of megabytes of RAM on my Raspberry Pi before even opening a single file was frustrating.
I do not need all the heavy features like VS Code extensions, debugging tools, or Git integration.
All I really wanted was to edit files, run commands, and keep my terminal running even if I close the browser tab. Instead of running a heavy IDE, I built a simple one with just the parts I actually need.
Stack
| Layer | Tech | Why |
|---|---|---|
| Runtime | Bun | Faster than Node, native TypeScript, built-in bundler |
| Server | Hono | Lightweight, fast, similar to Express but smaller |
| Frontend | React + Vite | Fast builds, HMR for development |
| Editor | Monaco | Same engine as VS Code, great syntax highlighting |
| Terminal | xterm.js + tmux | Full terminal emulation, session persistence |
| PTY | Bun.Terminal | Native PTY support, no node-pty needed |
How it Works
Server Architecture
A single Bun process handles everything: the file API, serving the web pages, and the WebSocket for the terminal.
There are no extra services running, and you do not need an Nginx proxy.
The server uses Bun and Hono running as one process with no build step required. The front-end uses React and the Monaco editor, built with Vite, and is served directly by the Bun server.
"dependencies": {
"@monaco-editor/react": "^4.7.0",
"@xterm/xterm": "5.5.0",
"@zuppif/termx": "^1.0.3",
"hono": "^4.7.10",
"react": "^19.0.0"
}
A Real Terminal
The terminal uses tmux to keep your sessions running. When you close the browser
and come back later, your terminal session is still right there. Tools like htop, command-line editors, and long-running scripts all survive a page reload.
tmux session runs in the background.tmux attach.tmux stays alive and keeps your work safe.tmux attach sends the latest screen state to the browser.xterm.js library handles drawing the text and scrolling.mouse off (so xterm.js handles scrolling) and
terminal-overrides xterm*:smcup@:rmcup@ (to prevent screen issues).
File System API
The backend provides a simple REST API to manage files. It supports selecting multiple files, renaming, deleting, and using a right-click menu. All files are loaded directly from your workspace folder.
# List files
GET /api/files?root=/home/user/project
# Read file
GET /api/file?path=src/index.ts
# Write file
POST /api/file
{"path": "src/index.ts", "content": "..."}
# Delete file
DELETE /api/file?path=old-file.txt
Run It
Requirements
curl -fsSL https://bun.sh/install | bash)apt install tmux)1. Clone and install
git clone https://github.com/MrFatoni/web-ide.git
cd web-ide
git checkout vite
bun install
2. Build and run
bun run build
bun run start
# Or with hot reload:
bun run dev
3. Open in browser
http://localhost:4242
# Or with custom workspace:
http://localhost:4242?root=/home/user/projects
4. Run as systemd service
sudo tee /etc/systemd/system/web-ide.service << 'EOF'
[Unit]
Description=Web IDE
After=network.target
[Service]
Type=simple
WorkingDirectory=/path/to/web-ide
Environment=PORT=4242
ExecStart=/home/user/.bun/bin/bun --hot run server/index.ts
Restart=always
RestartSec=3
User=your-username
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl enable --now web-ide
GitHub: github.com/MrFatoni/web-ide
References & Further Reading
- code-server RAM usage discussions (GitHub)
- Bun: A fast all-in-one JavaScript runtime
- Hono: Ultrafast web framework for the Edges