Devlog 6 — Taking the CLI to the Browser
Biggest struggle
The hardest part wasn’t writing new features. It was translating existing ones into a completely different environment.
The original CLI felt natural because Node.js gives you everything: file system, stdin/stdout, process control. The browser gives you none of that. Every tool I had been relying on: readline, fs, chalk, console.log even process either doesn’t exist or behaves differently in a browser context.
The trickiest translation was the input loop. readline handles line buffering automatically, you just wait for the user to press Enter and get the full line back. With xterm.js, you get one raw character at a time via onData.
The other catch was the expression evaluator. After porting everything over, sin(90) + 10 was returning "Invalid command or expression" because the Function() scope didn’t know what sin was. The fix was straightforward once I understood the cause, exposing the math functions as local constants inside the Function() string but it was a good reminder that a working feature in one environment isn’t automatically working in another.
What changed in this version
New files
-
src/calc-demo.js:- full browser port ofcalc.jsusing xterm.js -
main.js:- entry point: boots xterm, loads the fit addon, callsinitCalc(term) -
index.html:- static shell with topbar, terminal mount and statusbar -
style.css:- dark terminal theme built around a monospace font stack and a single green accent
Key substitutions made
Node.js (calc.js)
Browser (calc-demo.js)
readline
xterm.js onData + manual buffer
chalk
ANSI escape codes
fs / history.txt
localStorage
console.log
term.write() via print()
process.exit
location.reload()
calc.js is untouched. The original CLI still runs exactly as before with node src/calc.js. The browser build is a separate port not a replacement.
Current features
- Everything from Devlog 5, now running in the browser
- Live deployment on Vercel. No install, no terminal, just a URL
- Terminal emulator UI with topbar, statusbar and live clock
- Full xterm.js input handling: backspace, local echo, line buffering
- History persisted in
localStorageacross page reloads - Expression evaluator now supports
sin(90) + 10,sqrt(144),abs(-5)etc. directly -
clsclears the xterm screen properly using escape sequences -
exitreloads the page
Reflection
Devlog 5 ended with “maybe create a simple web version for easier demo access” as a future idea. This devlog is that idea, actually shipped.
What surprised me most was how much invisible work Node.js was doing. You write readline and it just works but behind it is a whole input loop, line buffering, echo management and terminal control that you never think about. Doing it manually in xterm.js made all of that visible which was frustrating at first but genuinely useful to understand.
The project now has two lives: a proper Node.js CLI tool and a browser demo that looks and feels identical. That separation, keeping calc.js untouched and building the browser port as a parallel file felt like the right architectural call. One doesn’t compromise the other.
It’s also the first time something I built has a real public URL.
Comments 0
No comments yet. Be the first!
Sign in to join the conversation.