A small command-line tool that turns a string (typically a website URL) into a high-resolution, phone-scannable QR code — as a PNG, an SVG, or a live terminal preview.
Defaults are tuned for reliable scanning: a 1024px image, a spec-recommended
4-module quiet zone, maximum black-on-white contrast, and M-level error
correction.
npm install # install dependencies
npm run build # compile TypeScript to dist/
npm link # expose the `qr` command globally (optional)Without npm link, run it via npm run dev -- <args> (uses tsx, no build
step) or node dist/cli.js <args> after building.
The simplest case prints a scannable QR code straight to your terminal:
qr https://example.comSave it as an image file instead:
qr https://example.com -o qr.png # 1024px PNG, ready to scan
qr https://example.com -o logo.svg # scalable SVG, ideal for printA few common variations:
qr https://example.com -e H -w 2048 # high error-correction, 2048px
qr https://example.com --dark "#0a3d62" # custom foreground color
echo https://example.com | qr -f png -o - # read stdin, PNG bytes to stdoutNot linked yet? Substitute
npm run dev --(ornode dist/cli.js) forqrin any command, e.g.npm run dev -- https://example.com -o qr.png.
qr <text|url> [options]
| Option | Description | Default |
|---|---|---|
-o, --output <path> |
Output file path (- writes to stdout) |
— |
-f, --format <fmt> |
png | svg | terminal |
terminal if no -o, else from extension |
-w, --width <px> |
PNG width in pixels | 1024 |
--scale <n> |
Pixels per module (overrides --width) |
— |
-m, --margin <modules> |
Quiet-zone width | 4 |
-e, --ecc <L|M|Q|H> |
Error-correction level | M |
--dark <color> |
Foreground/module color (hex) | #000000 |
--light <color> |
Background color (hex) | #ffffff |
--no-validate |
Don't warn when the input isn't a valid URL | — |
- No
-o, no-f→ prints the QR to the terminal (instant preview). -f png\|svgwithout-o→ writes./qrcode.png/./qrcode.svg.-o file.png→ writes that file; the extension picks the format unless-foverrides it.-o -→ streams raw bytes to stdout for piping (requires-f png|svg).
Confirmation messages and warnings go to stderr, so stdout stays clean when piping the image bytes.
Pass the text as an argument, or pipe it via stdin. The input is checked against
new URL(): if it isn't a valid absolute URL you get a warning (e.g. a
missing https://), but it is still encoded — a QR code can hold any string.
Use --no-validate to silence the warning.
qr https://example.com # preview in the terminal
qr https://example.com -o qr.png # save a 1024px PNG
qr https://example.com -o logo.svg # save a scalable SVG (great for print)
qr https://example.com -e H -w 2048 # high error-correction, 2048px
qr https://example.com --dark "#0a3d62" # custom foreground color
echo https://example.com | qr -f png -o - > qr.png # read stdin, bytes to stdoutTips for maximum scannability: keep the default high contrast (dark on
light), don't shrink the --margin below 4, and bump --ecc H if the code will
be printed small or might get partially obscured.
src/
cli.ts # entry point: argument parsing (commander), wiring, exit codes
qr.ts # pure encoding core: text + options -> PNG bytes / SVG / terminal
options.ts # QrOptions type, tuned defaults, validation & coercion
input.ts # resolve input (arg or stdin), URL validation (warn-only)
output.ts # resolve destination (file/stdout/terminal) and write it
errors.ts # CliError for clean, user-facing failures
test/
qr.test.ts # unit tests for the core, option handling, and target routing
The core (qr.ts) is pure and side-effect free, so it's trivially testable;
all I/O and process handling lives in the thin CLI shell.
npm run dev -- https://example.com -o qr.png # run from source (tsx)
npm test # run the unit tests
npm run build # type-check + emit dist/