@nomideusz/svelte-qr

Zero-dependency QR code generation for Svelte 5. A pure-TypeScript encoder (Reed-Solomon error correction, all 40 versions, byte-mode UTF-8) plus a drop-in <QrCode /> component that emits a single SVG. No canvas, no image decoding, no runtime dependencies.

Install

pnpm add @nomideusz/svelte-qr

Requires Svelte 5 (^5.0.0). Zero runtime dependencies.

Quick start

<script>
  import { QrCode } from '@nomideusz/svelte-qr';
</script>

<QrCode data="https://example.com/verify/abc123" />

That's it — a 256×256 SVG with sensible defaults (error correction M, 4-module quiet zone, black modules on white).

Customizing

All options are props on <QrCode />:

<QrCode
  data="https://example.com"
  size={320}
  errorCorrection="Q"
  foreground="#18181b"
  background="#fafafa"
  padding={6}
  label="Scan to verify booking"
/>
Prop Type Default Description
data string required Payload to encode (URL, text, UTF-8 OK)
size number 256 SVG width and height in px
errorCorrection 'L' | 'M' | 'Q' | 'H' 'M' Reed-Solomon redundancy — L ≈ 7%, M ≈ 15%, Q ≈ 25%, H ≈ 30%
padding number 4 Quiet zone in modules (spec requires ≥ 4)
foreground string '#000000' Dark module color (any CSS color)
background string '#ffffff' Light module / background color
label string `QR code for: ${data}` Screen-reader label

The rendered SVG inherits its size from the size prop and has shape-rendering="crispEdges" set, so it stays sharp at any DPR. The wrapper <div> has display: inline-block and line-height: 0 so it sits cleanly next to text.

Encoder-only (no component)

If you need the matrix or SVG string directly — server-side rendering, canvas output, custom styling — the underlying functions are exported:

import { getQrMatrix, matrixToSvg } from '@nomideusz/svelte-qr';

// Returns a 2D boolean matrix: true = dark module, false = light
const matrix = getQrMatrix('https://example.com', { errorCorrection: 'H' });

// Render to SVG with the same options
const svg = matrixToSvg(matrix, { size: 512, foreground: '#003366' });

// Or roll your own renderer over the matrix
for (let r = 0; r < matrix.length; r++) {
  for (let c = 0; c < matrix[r].length; c++) {
    if (matrix[r][c]) drawDarkModule(r, c);
  }
}

Types:

type ErrorCorrection = 'L' | 'M' | 'Q' | 'H';
type QrMatrix = boolean[][];

interface QrOptions {
  errorCorrection?: ErrorCorrection;
  padding?: number;
  foreground?: string;
  background?: string;
  size?: number;
}

Choosing an error correction level

Level Recovers Use for
L ~7% damage Clean, well-lit prints where space matters
M ~15% damage Default. General-purpose: email, links, tickets
Q ~25% damage Outdoor signage, business cards, physical printing
H ~30% damage Branded QRs with a logo overlay, damaged surfaces, hostile environments

Higher levels mean a denser matrix (smaller modules) at the same pixel size — so for small rendered sizes, lower levels scan more reliably. For URLs with a logo overlay in the center, H is what you want.

Capacity

Byte mode is always used, so any UTF-8 string works. The encoder auto-picks the smallest QR version (1–40) that fits your payload at the chosen EC level. Approximate byte limits:

EC Max bytes
L 2953
M 2331
Q 1663
H 1273

Exceeding capacity throws — catch and surface a user-friendly error:

try {
  const svg = matrixToSvg(getQrMatrix(longPayload));
} catch (err) {
  // "Data exceeds maximum QR capacity for error correction level H"
}

SSR

Everything is pure functions over strings — no DOM, no canvas, no timers. <QrCode /> renders identically on server and client, so you can use it anywhere SvelteKit runs.

Styling

The component wrapper has the class asini-qr. Target it directly or with a global selector:

:global(.asini-qr) {
  padding: 12px;
  border-radius: 8px;
  background: white;
  box-shadow: 0 1px 3px rgb(0 0 0 / 0.1);
}

For full control, generate the SVG string with matrixToSvg() and drop it wherever you like with {@html svg}.

Development

pnpm install
pnpm dev             # SvelteKit dev server (demo)
pnpm check           # Typecheck
pnpm test            # Vitest
pnpm run package     # Build the library

License

MIT

Top categories

Loading Svelte Themes