WorksHere
"Works on my machine" has been a joke since 2007. It never said which machine.
This one does.
npx workshere
Reads the environment you actually ran it in — OS and kernel, architecture,
processor, memory, installed runtime versions, a digest of your nearest
lockfile, your git commit and dirty flag, and the exit code of a test suite it
can run for you — and issues it back as an engraved certificate: a PNG you can
paste into the issue where somebody said they couldn't reproduce it.
Zero dependencies. No account, no server, no telemetry. MIT.

That image was produced by running the command in this repository. Every value
on it was read off the machine.
Use it
npx workshere
npx workshere --test
npx workshere --test "pnpm test"
npx workshere --json
npx workshere verify cert.png
-t, --test [cmd] | — | Run the tests first and print the exit code and count on the certificate. With no argument it infers the command from package.json, Cargo.toml, go.mod or pyproject.toml. |
-o, --out <path> | works-on-my-machine.png | Where to write it. |
-f, --format <fmt> | png | png, svg, or both. |
-s, --scale <n> | 1 | Raster scale. 1 is 1600×1132. |
--anonymous | — | Omit the hostname and the git author. Everything else still goes on. |
--json | — | Print the values and exit. |
-q, --quiet | — | Print only the output path. |
Node 18 or newer.
In CI
- uses: kyisaiah47/workshere@v1
with:
test-command: npm test
Issues a certificate from the runner, uploads it as a workflow artifact, and
writes the values into the job summary. fail-on-void: false lets a failing
suite still produce its (void) certificate without failing the step.
What it reads
- OS name and kernel release, architecture, processor model, core count, RAM
- Installed runtime versions — node, bun, deno, python, go, rustc, java, ruby, php, dotnet
- The nearest lockfile by name, and a SHA-256 digest of its contents
- git: short commit, branch, uncommitted-file count, author name
- The test command's exit code, and its test count where the runner's own
summary line can be parsed (jest, vitest, mocha, pytest, cargo, go, node:test)
- The CI provider, when running in CI
- A UTC timestamp
What it deliberately does not read
Environment variables. The working directory path. The git remote URL. The
contents of any file beyond the lockfile digest. People paste this into public
threads.
--anonymous additionally drops the hostname and the git author.
It will not lie for you
If --test runs a suite and the suite fails, you still get a certificate — but
it is titled DOES NOT WORK HERE, stamped VOID in red across the middle, its
seal reads EXIT 1, and the process exits non-zero so it cannot quietly turn a
red build green.
That behaviour is the whole reason a certificate that isn't void is worth
anything.
The digest
The seal carries a SHA-256 of exactly the values printed on the page. The same
values are embedded in the PNG as a tEXt chunk.
npx workshere verify works-on-my-machine.png
reads them back, recomputes the digest and prints the values so you can check
them against the pixels. An edited certificate stops matching.
It is a checksum of a claim, not a signature from an authority. There is no
authority. That is the joke.
The ornament is yours
The guilloche rosettes — the watermark, the four corner medallions and the
emblem inside the seal — are real spirographs: hypotrochoids and epitrochoids,
the same curves the geometric lathes that engraved bank notes actually traced.
Their petal counts, turn counts and proportions are drawn from the certificate's
own digest.
Two machines produce visibly different ornaments. The same machine on the same
commit produces the same one every time. A static badge image cannot do that.
How it draws
There is no headless browser, no canvas dependency and no font file in the
output.
src/geom.mjs — paths and curve flattening
src/text.mjs — text set as outlines; every glyph becomes a filled path
src/guilloche.mjs — the spirograph engine
src/certificate.mjs — the layout, pure: facts and faces in, a scene out
src/raster.mjs — a scanline rasteriser, 4 sub-scanlines per row with exact
horizontal coverage
src/png.mjs — a PNG encoder over node:zlib
src/svg.mjs — the same scene, serialised
The SVG is self-contained: no @font-face, no external reference, no script.
Because certificate.mjs touches nothing outside itself, the website renders
the same certificate about your browser with the same code — see
tools/sync-renderer.mjs.
Programmatically
import { certify } from 'workshere';
const { payload, digest, png } = certify({ tests: 'npm test' });
await fs.writeFile('cert.png', png());
Licence
MIT for the code. The glyph outlines in fonts/ are derived from Playfair
Display, EB Garamond and Geist Mono and stay under the SIL Open Font License 1.1
— see THIRD-PARTY.md.