Skip to content

Linux Playground: CLI Tools in Your Browser

Every guide on this site ends the same way: install the thing, then try it. This page skips the first half. Below is a real Linux machine, running in your browser tab, with every tool the guides cover already installed and configured the way they recommend. Press the button, wait a few seconds, type.

Downloads about 20 MB, then runs entirely in this tab.
Best with a physical keyboard.

Not running

It is not a simulation, and nobody else’s server is involved. An x86 emulator compiled to WebAssembly boots Alpine Linux on your own CPU, inside the tab, then forgets the lot when you close it. Break whatever you like: Reset restores it from a snapshot in about the time it takes to regret rm -rf ~.

The buttons marked ▶︎ Try it here and throughout the guides type their command into this machine without pressing Enter for you. Running it remains your decision.

For Installed
Shells bash (the login shell), and zsh with the minimal .zshrc, autosuggestions and syntax highlighting
Multiplexers tmux with the guide’s starter config, and Zellij
Prompt Starship, on its defaults
The starter pack eza, bat, ripgrep, fd, zoxide, fzf and delta
Its honourable mentions dust, duf, btop, sd, hyperfine, tldr (tealdeer), jq and direnv
Everything else git (with delta as its pager), Neovim, htop, ncdu, curl, dig and less, and sudo with no password

There is also a ~/demo directory: a small, pointless project with a few commits, an uncommitted change, a JSON file, an .envrc in api/ and a log full of requests. It exists so the examples have something to chew on. The jq guide’s servers.json is in ~ as well, so its examples run as printed.

fzf with a bat preview pane, over the demo project:

Terminal window
cd ~/demo && fzf --preview 'bat --color=always {}'

Then press Ctrl+R at the prompt for fuzzy history search, and Ctrl+T to fuzzy-find a path into the command you’re typing. ripgrep and fd do the searching; note neither looks in logs/, because .gitignore says not to:

Terminal window
rg TODO ~/demo
Terminal window
fd -e py . ~/demo

jq on the demo’s user list:

Terminal window
jq '.users[] | select(.active) | .name' ~/demo/data.json

And delta on the uncommitted change, since git already pipes through it:

Terminal window
cd ~/demo && git diff

tmux, with the starter config: Ctrl+B | and Ctrl+B - split, the mouse works, and Ctrl+B d detaches. tmux attach brings it back.

Terminal window
tmux new -s demo

Zellij, for comparison, explains its own keys along the bottom of the screen. It is the heaviest program here by a distance, so give it a moment to start:

Terminal window
zellij

direnv refuses the demo’s .envrc until you allow it, then loads it at the next prompt:

Terminal window
cd ~/demo/api && direnv allow
Terminal window
tldr tar
Terminal window
eza -l --git --icons=auto ~/demo
Terminal window
dust /usr
Terminal window
hyperfine --warmup 2 'rg TODO ~/demo' 'grep -r TODO ~/demo'

duf, btop, htop and ncdu need no arguments. zsh swaps shells, and nvim is there for anyone who would like to practise leaving it.

The terminal test is installed as terminal-test. Here it measures xterm.js, the terminal this page draws with, which turns out to be better at colour than at pictures:

Terminal window
terminal-test

It is a real machine, but it is a real machine on a short lead:

  • The network is mostly imaginary. The emulator replays the guest’s plain-HTTP requests through the browser’s own fetch(), which means they arrive as your browser, from this page, and only sites that allow cross-origin requests answer at all. Most don’t. HTTPS, SSH and every other port don’t work, which rules out apk add, git clone and the terminal test’s usual curl | sh, and is why everything comes pre-installed. DNS does work: dig gets real answers, over DNS-over-HTTPS. To see what your requests look like from the other end:

    Terminal window
    curl -s http://httpbin.org/get | jq .headers

    curl, it turns out, is now your browser.

  • ping always succeeds, whatever you point it at. The emulator answers it itself, out of politeness.

  • It is slow. An emulated 32-bit PC runs at a fraction of native speed, so hyperfine’s numbers measure the emulator, and Zellij takes a while to arrive.

  • It’s best with a physical keyboard. Phones can type into it, but Ctrl and Esc are hard to find on one.

  • Nothing persists. Reload the page and it’s factory fresh. Nothing you type leaves the tab.

The machine is v86, an x86 emulator written in Rust and JavaScript and compiled to WebAssembly, running Alpine Linux built from a Dockerfile. The terminal is xterm.js, wired to the guest’s virtio console.

Two tricks keep it fast enough to bother with. The first is a snapshot: rather than booting from scratch, which takes a minute or so, the page downloads the machine’s memory as it was at its first prompt and resumes from there. The second is that the disk is fetched lazily: the root filesystem is stored as one download per file, and the browser only fetches a binary when the guest first reads it. Try zellij and you download Zellij; never try it and you never do.

Found a tool you like? The modern CLI starter pack has the install commands for your own machine, the tmux guide explains what you just split, and Starship is the prompt you’ve been looking at all along.