How this works
The images are Exercism's own
Each track runs in its own Linux VM, booted from the test-runner image Exercism publishes. The image is pinned by digest and converted to an OxideVM image without changing a file, so the runner, the language, the test framework and the Alpine Linux underneath are the ones Exercism ships.
They run the way Exercism runs them
Exercism's tooling-invoker starts a runner as root, with the image's own entrypoint, working directory and environment, and hands it one directory that holds the solution and receives results.json. greenbar does the same. The directory is /workspace/exercism-iteration/ rather than /mnt/exercism-iteration/, because the VM's root filesystem is read-only there, and the VM has no network.
Python and Ruby start from a prepared snapshot
Under emulation, a fresh CPython or Ruby spends most of a run loading the runner's libraries. So greenbar keeps one interpreter per track that has loaded them, and forks a fresh child for every run. The child executes the runner's own bin/run.py or bin/run.rb, unmodified, with the same arguments, working directory and environment that bin/run.sh gives it. That interpreter does not load in your tab: the page restores a signed snapshot of the VM, taken after the launcher had loaded everything and, for Python, run one warm-up job. A snapshot keeps memory and processes but not the processor's translated code, so the page then runs one passing solution before yours. If a snapshot cannot be used, the page starts the launcher itself and says so. To leave the launcher out, tick Run through bin/run.sh
before you run.
Checked against Docker, byte for byte
Every prepared solution was also run under Docker, with the same image and the same invocation, and greenbar keeps the results.json Docker wrote. When you run an unedited prepared solution, the page compares the file your tab wrote with it byte for byte and shows its SHA-256. Once you edit a solution there is nothing to compare with, and the job record says so. On 6 November 2026, with OxideVM SDK 0.0.16, all 52 runs in a browser matched Docker exactly: the 16 prepared solutions of the four tracks twice each through the runner's own entry point, and the 10 Python and Ruby solutions twice more through the warm launchers.
It is slower than a server
The runners execute on an emulated x86-64 processor that translates hot code to WebAssembly, so they take longer than on Exercism's servers. On the desktop we tested, the page started its four tracks two at a time, and all four were ready within 17 seconds: SQLite and Bash in one to three seconds, Ruby in 10 to 14 seconds and Python in 14 to 17 seconds, both restored from their snapshots. Without the snapshots, Ruby takes about half a minute and Python about a minute and a half. The first run of a solution takes a few seconds more while its files are copied into the VM; after that, SQLite runs took one to three seconds, Ruby runs one to two seconds and a 47-test Python run five to eight seconds, while Bash runs took half a minute to a minute, because bats starts new shells for every test. Your computer will differ, so every job record shows its own times.
Sources and licenses
greenbar is a demonstration of OxideVM. It is not affiliated with or endorsed by Exercism. Exercism's test runners are licensed under the AGPL-3.0, and the exercises come from Exercism's MIT-licensed track repositories at pinned commits. Every image this page runs, with its license texts, notices and complete corresponding sources, is listed on the open-source page.