itworksbut
v0.5.0
Published
Static CI checks for common security, repo, dependency, build, and deployment risks in JavaScript vibe coding projects.
Maintainers
Readme
ItWorksBut
ItWorksBut is a Node.js CI tool for static checks in JavaScript, Node.js, web, Tauri, and Electron vibe coding projects.
It focuses on common "it works, but..." risks often found in AI-generated or rushed prototypes: committed env files, missing lockfiles, weak CI, unsafe web APIs, broad desktop permissions, and similar issues.
For every finding, ItWorksBut gives you a copy-ready fix prompt you can paste into your coding agent. It does not just say what is wrong; it tells your AI exactly what to inspect, what to change, and what not to leak.
It only reads files and reports findings. It does not call external APIs, does not send telemetry, and does not modify the scanned project unless you explicitly ask it to write todo.md with --todo.
Installation
npm install --global itworksbut
itworksbut scanHomebrew
With the Homebrew tap:
brew tap oliverjessner/tap
brew install itworksbut
itworksbut scanQuick Start
itworksbut scanscan is intentionally the strict/default path: all checks are enabled, only heavy generated folders are skipped, and the default fail-on threshold is low so more issues fail early. Use --config only when you deliberately want to tune or suppress checks.
Common commands:
itworksbut scan --path .
itworksbut scan --fail-on high
itworksbut scan --json
itworksbut scan --sarif > itworksbut.sarif
itworksbut scan --todo
itworksbut scan --config itworksbut.config.json
itworksbut scan --verbose
itworksbut --versionOptions
itworksbut scan [options]--path <path>: Scan a specific project directory. Defaults to the current directory.--config <path>: Use a custom config file. Defaults toitworksbut.config.jsonwhen present.--fail-on <severity>: Exit with code1when a finding at or above the severity exists. Levels:critical,high,medium,low,info. Default:low.--json: Print machine-readable JSON only. No banner, colors, spinner, table, or extra text.--sarif: Print SARIF JSON for GitHub Code Scanning. No banner, colors, spinner, table, or extra text.--todo: Write an AI-readytodo.mdinto the scanned project with prioritized findings, fix prompts, and acceptance criteria.--verbose: Include scanner warnings and extra metadata in console output.--quiet: Print only the summary.--no-color: Disable colored output.--no-banner: Disable the ASCII intro banner.--version,-v: Print the installed ItWorksBut version.
Exit codes:
0: no findings at or above the configuredfail-onseverity1: at least one finding at or above the configuredfail-onseverity2: tool/runtime error
Severity levels are critical, high, medium, low, and info.
Terminal Experience
Normal console output is intentionally more opinionated than the machine-readable reporters:
itworksbut scanConsole-only flags:
--no-color--no-banner--quiet--verbose
In CI, spinners and banners are automatically disabled. With --json and --sarif, stdout contains only valid machine-readable output. The edgy tone applies only to the Console Reporter.
To create a fix list for a coding agent:
itworksbut scan --todoThis writes todo.md to the scanned project. The file is ordered by severity and includes agent rules, exact fix prompts, locations, recommendations, and final verification checkboxes.
GitHub Actions
name: ItWorksBut
on:
pull_request:
push:
branches: [main]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
- run: npx itworksbut scan --fail-on highFor GitHub Code Scanning-style output:
itworksbut scan --sarif > itworksbut.sarifConfiguration
Optional itworksbut.config.json:
{
"ignore": ["dist/**", "build/**", "node_modules/**"],
"failOn": "low",
"checks": {
"env.env-file-tracked": true,
"dependencies.lockfile-missing": true,
"node.rate-limit-missing": false
}
}Checks are enabled by default. Set a check id to false to disable it.
This repository also has itworksbut.self.config.json for its own CI run. It ignores intentional test fixtures and scanner regex files. Do not use that profile if you want the highest finding rate.
Default ignored paths:
node_modules/**
dist/**
build/**
.next/**
.nuxt/**
coverage/**
.git/**
target/**
src-tauri/target/**
out/**
release/**
.vite/**Example Output
✖ CRITICAL It works, but your .env is tracked.
✔ Check: env.env-file-tracked
📁 File: .env
🤔 Why: .env appears to be tracked by git. Secrets may be exposed.
🤖 prompt: You are a senior security engineer working in this repository. Fix the ItWorksBut finding env.env-file-tracked at .env. Treat this as a concrete finding. Problem: .env appears to be tracked by git. Secrets may be exposed. Required change: Remove tracked env files from git, add safe examples such as .env.example, and make sure any exposed credentials are treated as compromised. Do not print, log, or preserve raw secret values; use placeholders only. Keep existing behavior intact where possible, add or update focused tests when useful, and do not silence the check unless the underlying risk is actually fixed.
▲ HIGH It works, but your SQL query is one template string away from pain. ✔ Check: database.raw-sql-interpolation 📁 File: src/db.js:12 🤔 Why: Possible SQL injection risk: raw SQL appears to be built with template string interpolation. 🤖 prompt: You are a senior security engineer working in this repository. Fix the ItWorksBut finding database.raw-sql-interpolation at src/db.js:12. This finding is heuristic, so inspect the code first and only change behavior when the risk is real. Problem: Possible SQL injection risk: raw SQL appears to be built with template string interpolation. Required change: Replace SQL string interpolation or concatenation with parameterized queries, prepared statements, or a safe ORM query builder. Keep existing behavior intact where possible, add or update focused tests when useful, and do not silence the check unless the underlying risk is actually fixed.
SUMMARY
- ship status: DO NOT SHIP
- Fix the red stuff before production.
- total findings: 2
- critical: 1
- high: 1
- medium: 0
- low: 0
- info: 0
- fail-on: high
- exit decision: 1
Secret-like findings never print the full secret value. Findings report the file, line, and secret type where possible.
## What It Detects
The baseline includes 50 modular checks:
- `git.gitignore-missing`
- `git.gitignore-incomplete`
- `git.ignored-files-tracked`
- `env.env-file-tracked`
- `env.env-example-missing`
- `env.possible-secret-in-code`
- `env.frontend-secret-exposure`
- `secrets.secrets-in-logs`
- `dependencies.lockfile-missing`
- `dependencies.multiple-lockfiles`
- `dependencies.install-scripts-risk`
- `dependencies.audit-script-missing`
- `package.scripts-missing`
- `ci.no-ci-config`
- `ci.npm-install-instead-of-npm-ci`
- `ci.no-build-step`
- `ci.no-test-step`
- `node.express-json-limit-missing`
- `node.rate-limit-missing`
- `node.helmet-missing`
- `node.cors-wildcard`
- `node.child-process-user-input`
- `web.client-side-auth-only`
- `web.dangerous-inner-html`
- `web.missing-output-sanitization`
- `api.missing-auth-on-routes`
- `api.idor-risk`
- `auth.jwt-secret-weak-or-fallback`
- `auth.password-hashing-missing`
- `auth.missing-csrf-protection`
- `api.missing-method-guard`
- `api.mass-assignment-risk`
- `api.no-schema-validation`
- `database.raw-sql-interpolation`
- `database.no-migrations`
- `cookies.insecure-session-cookie`
- `uploads.public-executable-upload`
- `webhooks.missing-raw-body`
- `llm.prompt-injection-risk`
- `frontend.sourcemaps-production`
- `frontend.localstorage-token`
- `files.path-traversal-risk`
- `ssrf.user-controlled-fetch`
- `next.public-server-code-risk`
- `config.debug-production`
- `electron.node-integration-enabled`
- `electron.context-isolation-disabled`
- `electron.remote-content-with-node`
- `tauri.dangerous-allowlist-or-capabilities`
- `tauri.remote-url-permissions-risk`
Each check is a plain ESM module with an `id`, metadata, and async `run(context)` function. Add new checks under `src/checks/` and register them in `src/checks/index.js`.
## What It Does Not Guarantee
ItWorksBut is a static heuristic scanner, not a pentest, SAST replacement, dependency vulnerability database, or runtime security monitor. Findings intentionally use wording such as "possible", "potential", and "appears to" when a check is heuristic.
Use it as a CI guardrail for common project hygiene and security mistakes. For production systems, combine it with code review, tests, dependency scanning, secrets scanning, threat modeling, and focused security assessment.