Building a Lightweight Web IDE
I needed a web IDE that runs on a Raspberry Pi 4. code-server (VS Code in the browser) uses 300-400MB RAM just sitting idle. My Pi has 4GB total. So I built one that uses ~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 |
code-server on a Raspberry Pi eating hundreds of MB of RAM just idling before opened a single file.
I don't need VS Code extensions, debugging, or git integration.
All I actually wanted was: edit files, run commands, keep the terminal alive when I close the tab. So instead of running a full IDE, I built just the three parts I 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
Single Bun process handles everything: file API, static files, and WebSocket for terminal.
No separate services, no nginx reverse proxy needed.
Server is Bun + Hono, one process, no build step for the backend. Frontend is React + Monaco for the editor, compiled with Vite and served as static files by the same Bun process.
"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 for session persistence. When you close the browser and come back, your session is still alive. htop, editors, long-running commands. everything survives page reload.
tmux attachtmux attach sends current screen statemouse off (xterm.js handles scroll),
terminal-overrides xterm*:smcup@:rmcup@ (no alternate screen conflict).
File System API
Simple REST API for file operations. Supports multi-select, rename, delete, and right-click context menu. Files are served from the workspace directory.
# 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