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.

Bun server
→
React + Vite
→
Monaco Editor
→
xterm.js
→
tmux PTY

Why Not code-server?

code-server (VS Code)
RAM idle300-400MB
Bundle size~80MB
Startup3-5s
ExtensionsFull VS Code
web-ide-v3
RAM idle~30MB
Bundle size~250KB
Startup<1s
FeaturesFile 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

LayerTechWhy
RuntimeBunFaster than Node, native TypeScript, built-in bundler
ServerHonoLightweight, fast, similar to Express but smaller
FrontendReact + ViteFast builds, HMR for development
EditorMonacoSame engine as VS Code, great syntax highlighting
Terminalxterm.js + tmuxFull terminal emulation, session persistence
PTYBun.TerminalNative 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.

A tmux session runs in the background.
The browser connects to it using WebSockets via tmux attach.
If you disconnect, tmux stays alive and keeps your work safe.
When you reconnect, tmux attach sends the latest screen state to the browser.
The xterm.js library handles drawing the text and scrolling.
Important tmux settings: set 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

Bun installed (curl -fsSL https://bun.sh/install | bash)
tmux (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

Built with Bun, React, Vite, Monaco Editor, xterm.js, and tmux. Runs on ARM64 (Raspberry Pi) and x86_64.