{"id":51417768,"url":"https://github.com/didrod205/works-on-my-machine","last_synced_at":"2026-07-04T21:30:39.831Z","repository":{"id":368299347,"uuid":"1266776863","full_name":"didrod205/works-on-my-machine","owner":"didrod205","description":"\"Works on my machine\" — finally with receipts. Capture a paste-safe env fingerprint, diff it against a teammate's or CI, and get told exactly what's different and why it broke. Plus the legendary ✓ badge. npx womm — 100% local, no telemetry.","archived":false,"fork":false,"pushed_at":"2026-06-29T23:23:28.000Z","size":55,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-30T01:15:45.226Z","etag":null,"topics":["badge","bug-report","ci","cli","debugging","developer-tools","diff","envinfo","environment","node","onboarding","reproducibility","typescript","works-on-my-machine","zero-dependency"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/didrod205.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"didrod205"}},"created_at":"2026-06-12T00:11:44.000Z","updated_at":"2026-06-29T23:23:32.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/didrod205/works-on-my-machine","commit_stats":null,"previous_names":["didrod205/works-on-my-machine"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/didrod205/works-on-my-machine","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/didrod205%2Fworks-on-my-machine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/didrod205%2Fworks-on-my-machine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/didrod205%2Fworks-on-my-machine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/didrod205%2Fworks-on-my-machine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/didrod205","download_url":"https://codeload.github.com/didrod205/works-on-my-machine/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/didrod205%2Fworks-on-my-machine/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35136712,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-04T02:00:05.987Z","response_time":113,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["badge","bug-report","ci","cli","debugging","developer-tools","diff","envinfo","environment","node","onboarding","reproducibility","typescript","works-on-my-machine","zero-dependency"],"created_at":"2026-07-04T21:30:37.723Z","updated_at":"2026-07-04T21:30:39.807Z","avatar_url":"https://github.com/didrod205.png","language":"TypeScript","funding_links":["https://github.com/sponsors/didrod205"],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n# ✓ works on my machine\n\n### The most famous excuse in software — finally with receipts.\n\n[![npm version](https://img.shields.io/npm/v/but-it-works-on-my-machine.svg?color=success)](https://www.npmjs.com/package/but-it-works-on-my-machine)\n[![CI](https://github.com/didrod205/works-on-my-machine/actions/workflows/ci.yml/badge.svg)](https://github.com/didrod205/works-on-my-machine/actions/workflows/ci.yml)\n[![types](https://img.shields.io/npm/types/but-it-works-on-my-machine.svg)](https://www.npmjs.com/package/but-it-works-on-my-machine)\n[![license](https://img.shields.io/npm/l/but-it-works-on-my-machine.svg)](./LICENSE)\n\u0026nbsp;\n\u003cimg src=\"./examples/badge.svg\" alt=\"works on my machine\" /\u003e\n\n```bash\nnpx but-it-works-on-my-machine\n```\n\n*(yes, that's the real command — after `npm i -g` it's just `womm`)*\n\n*Capture a paste-safe fingerprint of your dev environment → diff it against a\nteammate's (or CI) → get told **exactly what's different and why it broke.***\n\n\u003c/div\u003e\n\n---\n\nEvery bug thread has the same three messages:\n\n\u003e **them:** it crashes on start\n\u003e **you:** works on my machine 🤷\n\u003e **them:** …well it doesn't on mine\n\nThat conversation has wasted more engineering hours than any compiler error in\nhistory — because nobody can see *what's actually different* between the two\nmachines. `envinfo` tells you what **you** have. **womm tells you what's\n*different*, and which difference is probably the bug.**\n\n## The killer move: `womm diff`\n\nYou run `npx but-it-works-on-my-machine report` and attach `womm.json` to the\nissue. They run:\n\n```bash\nnpx but-it-works-on-my-machine your-womm.json   # diff their machine against yours\n```\n\n```\n  14 differences · 5 matching · ci-linux womm:1c612ba0 vs this machine womm:a7405ec3\n\n  ● NODE_ENV       production vs —\n    └ NODE_ENV changes dependency installs (dev deps) and framework behavior.\n  ● npm            10.5.0 vs 10.8.1\n    └ Different package-manager versions resolve dependency trees differently.\n  ● npm registry   https://registry.npmjs.org/ vs https://npm.corp.acme.dev/\n    └ A non-default registry can serve different (or stale, or proxied) packages.\n  ● Lockfile hash  sha256:a1b2c3d4e5f6 vs sha256:f9e8d7c6b5a4\n    └ Lockfiles differ — you are literally not running the same dependencies.\n  ● Node           20.12.2 vs 22.3.0\n    └ Different Node majors/minors run different V8, different APIs, different bugs.\n  ○ Timezone       UTC vs Asia/Seoul\n  ○ Locale         en-US vs ko-KR\n\n  ▲ 5 critical differences — start there.\n```\n\nDifferences are **ranked by how often they're the actual culprit** — Node\nversion, package-manager version, registry, lockfile drift, `NODE_ENV` — each\nwith a one-line *why this matters*. No more eyeballing two walls of `envinfo`.\n\n## What it captures (and what it never does)\n\n```\n  ✓ works on my machine  ·  womm:2fce9e48  2026-06-12\n  🔒 captured locally · paths masked · env values hidden · nothing uploaded\n\n  Runtime           Node 25.9.0 · from homebrew (/opt/homebrew/bin/node)\n  Package manager   npm 11.12.1 · pnpm 10.33.2 · registry npmjs.org\n  Project           womm@0.1.0 · engines \u003e=18 · package-lock.json (sha256:929a…)\n  Environment       NODE_ENV? · TZ Asia/Seoul · locale en-US\n  Tools             git 2.50.1 · docker 29.5.2 · python3 3.14.4\n  System            darwin 25.4.0 · arm64 · zsh\n```\n\n**Privacy is enforced at capture time, not display time:**\n\n- home directory \u0026 username → `~` everywhere\n- env var **values are never recorded** (only \"set, N chars\") except a tiny safe\n  allowlist (`NODE_ENV`, `TZ`, `CI`…)\n- hostname is **off by default** (opt-in `--include-host` stores a salted hash)\n- a last-line-of-defense scrubber redacts anything token-shaped\n- **zero network code in the package** — grep `dist/`, it's all local\n\nSo the report is safe to paste into a public GitHub issue. That's the point.\n\n## `womm check` — stop \"wrong Node\" before it wastes a morning\n\nVerifies **this machine** against what the repo *declares* — and exits non-zero\non violations, so it works as an onboarding gate or CI step:\n\n```\n  ✗ This project declares engines.node \"^18.17.0\" but you're running 25.9.0.\n    fix: Switch Node (e.g. `nvm install 18.17.0`).\n  ✗ The repo pins Node 20.11.1 (.nvmrc/.tool-versions) but you're on 25.9.0.\n    fix: Run `nvm use` (or `asdf install`) in the repo root.\n  ⚠ Multiple lockfiles present (package-lock.json, yarn.lock) — two installs\n    can disagree about every version.\n```\n\nRules: `engines.node`/`engines.npm` (real semver-range check), `.nvmrc` /\n`.node-version` / `.tool-versions` vs the active Node, the `packageManager`\nfield vs what's installed, lockfile↔package-manager mismatches, multiple\nlockfiles, non-default registries, and a globally-set `NODE_ENV=production`.\n\n```jsonc\n// package.json — make \"works on my machine\" a guarantee instead of an excuse\n{ \"scripts\": { \"preinstall\": \"npx --yes but-it-works-on-my-machine check\" } }\n```\n\n## The badge 🏅\n\nIn loving memory of the [2007 certification program](https://blog.codinghorror.com/the-works-on-my-machine-certification-program/):\n\n```bash\nnpx but-it-works-on-my-machine badge                 # → womm.svg\nnpx but-it-works-on-my-machine badge --fingerprint   # …with your fingerprint, as receipts\n```\n\n\u003cimg src=\"./examples/badge.svg\" alt=\"works on my machine badge\" /\u003e \u0026nbsp; ← embed it in your README. You've earned it.\n\n## Install\n\n```bash\nnpx but-it-works-on-my-machine        # no install — yes, the package name is the excuse\nnpm i -g but-it-works-on-my-machine   # installs the short commands: womm + works-on-my-machine\n```\n\n\u003e The npm name is long because npm's similarity filter reserves the short ones —\n\u003e consider it a feature: the command *is* the meme.\n\nNode ≥ 18. macOS / Linux / Windows. Zero-dependency core (the CLI uses `cac` + `picocolors`).\n\n## All commands\n\n\u003csub\u003e(`womm` = the installed bin; with npx, prefix `npx but-it-works-on-my-machine …`)\u003c/sub\u003e\n\n```bash\nwomm                        # capture \u0026 pretty-print this machine\nwomm --md | --json          # also write womm.md / womm.json (with --quiet: print raw)\nwomm report                 # write womm.json + womm.md to attach to an issue\nwomm their-report.json      # diff this machine against a report (shorthand)\nwomm diff a.json b.json     # diff two reports\nwomm check                  # validate vs engines/.nvmrc/packageManager/lockfile → exit code\nwomm badge [file]           # the legendary badge\nwomm doctor                 # what the project declares, at a glance\n```\n\n`womm.config.json` (optional): `{ \"extraTools\": [\"terraform\", \"ffmpeg\"], \"envAllowlist\": [\"MY_FLAG\"], \"includeHost\": false }`\n\n## For maintainers: a better bug-report block\n\nIssue templates have asked for `npx envinfo` output for years.\n`npx but-it-works-on-my-machine --quiet --md` prints a **collapsed, paste-safe\ndetails block** — and unlike a wall of text, the reporter's JSON can be\n**diffed against yours** in one command:\n\n```md\n\u003c!-- ISSUE_TEMPLATE/bug_report.md --\u003e\nRun `npx but-it-works-on-my-machine --quiet --md` and paste the output below.\n```\n\nTriaging then becomes: download their `womm.json` → `npx but-it-works-on-my-machine their.json`\n→ the critical differences are at the top, explained.\n\n## Library API\n\nThe diff/verdict engine is pure and browser-safe:\n\n```ts\nimport { parseReport, diffReports, runVerdicts, satisfies } from \"but-it-works-on-my-machine\";\n\nconst d = diffReports(parseReport(a), parseReport(b));\nd.entries[0]; // { key: \"runtime.node\", a: \"20.12.2\", b: \"22.3.0\", severity: \"critical\", note: \"…\" }\n```\n\n## Roadmap\n\n- 🌐 **Web diff playground** — paste two reports, see the verdict, 100% client-side.\n- 🧰 More ecosystems: Python (`.python-version`, `uv.lock`), Ruby, Rust toolchains.\n- 🤝 `womm diff --gh \u003cissue-url\u003e` — pull the reporter's block straight from a GitHub issue.\n- 🔌 Verdict plugins (your org's \"it's always the proxy\" rule).\n\n## 💖 Sponsor\n\nFree, MIT, built in spare time. If womm ended a \"works on my machine\" argument for you:\n\n- ⭐ **Star the repo** — it's how the next person finds it mid-argument.\n- 🍋 **[Sponsor via Lemon Squeezy](https://elab-studio.lemonsqueezy.com/checkout/buy/5d059b89-51d0-456b-b33a-ed56994f7010)** — one-time or recurring.\n\n## License\n\n[MIT](./LICENSE) © womm contributors\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdidrod205%2Fworks-on-my-machine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdidrod205%2Fworks-on-my-machine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdidrod205%2Fworks-on-my-machine/lists"}