hugo-qr
v0.1.0
Published
QR codes for apps: a dependency-free encoder (all 40 versions, L/M/Q/H), droplet-style shapes with room for a logo, SVG output and one link format for sign-in, sharing and joining. Runs on servers, edge workers and in React Native
Maintainers
Readme
hugo-qr
QR codes for apps. A dependency-free encoder, droplet-style shapes that are cheap to draw anywhere, SVG output, and one link format for signing in, sharing and joining. The same code runs on a Node server, an edge worker, in the browser and in React Native.
| Piece | What it does |
|---|---|
| Encoder | Byte mode (UTF-8), versions 1–40, error correction L/M/Q/H, Reed–Solomon, mask chosen by the standard penalty score |
| Shapes | The three finder "eyes" plus horizontal runs of dark modules, with an optional cleared square for a logo |
| SVG | A ready-to-serve image with rounded runs and a two-colour gradient |
| Links | <base>/q/<kind>/<value>: a phone camera opens it in the browser, your own scanner acts on it directly |
npm install hugo-qrEncode
import { encodeQr } from 'hugo-qr';
const qr = encodeQr('https://music.example/q/room/station-1'); // level Q by default
qr.version; // 4 — the smallest that fits
qr.size; // 33 modules per side
qr.modules[y][x]; // true = darkPass { ecc: 'H' } for the most error correction, { minVersion } to keep a fixed size across codes, { mask } to force a mask pattern.
Draw
qrShapes turns the matrix into a few hundred shapes instead of one per module, so a React Native view stays light:
import { encodeQr, qrShapes } from 'hugo-qr';
const { size, eyes, runs, logo } = qrShapes(encodeQr(link), { logo: 0.2 });
const m = 240 / size; // points per module
runs.map((r) => <View key={`${r.x},${r.y}`} style={{ position: 'absolute', left: r.x * m, top: r.y * m, width: r.len * m, height: m, borderRadius: m / 2 }} />);Keep logo at or under about 0.22 with level Q or H: error correction rebuilds the modules the logo covers.
import { encodeQr, toSvg } from 'hugo-qr';
res.type('image/svg+xml').send(toSvg(encodeQr(link), { colors: ['#7CE3A4', '#4AA3F5'] }));Links
import { qrLink, parseQrLink } from 'hugo-qr';
qrLink('https://music.example', 'login', 'k3J9…'); // "https://music.example/q/login/k3J9…"
parseQrLink(scannedText); // { kind: 'login', value: 'k3J9…' } or nullAny address is accepted when reading, including development links such as exp://…/--/q/login/…. Only the kind and value are used, and only against your own server, so a code made elsewhere can at most point at something your server already knows.
Tests
npm test checks exact matrices for known inputs (recorded after a module-by-module comparison with an independent encoder), the fixed patterns every reader looks for, version limits, shapes and links, then builds the type declarations.
License
MIT
