termino
~/docs/custom/qrcode

QRCodecustom

QR code rendered from real bytes

~/custom/qrcode
live
$ termino qrcode — click to rotate payload
█▀▀▀▀▀█ ▄ █ ▀█▄▄█ █▀▀▀▀▀█
█ ███ █ ▄▄▄ █▄█▄ █ ███ █
█ ▀▀▀ █ ▄█ ▄▄▀▄▄▀ █ ▀▀▀ █
▀▀▀▀▀▀▀ ▀▄█▄▀ █ █ ▀▀▀▀▀▀▀
█▀▀▀▀ ▀▀█▀▄▀▄▄ █ █ ▀ █
▄▄▀▄▄█▀▀█ ▀ ▄█▀█▀ ███▀ ▀█
██▀█▄ ▀▄ ▀▀ ▀ ▀ ▄▀▀▄▀▄▀█▀
█ ▀ █▀▀▄▄█▄█▀ ▄██████▀ ▀█
▀ ▀▀ █▀ ▀▄▄▄▀█▀▀▀█▄▀
█▀▀▀▀▀█ ▀██ ▄█▀ █ ▀ █▄▀█▀
█ ███ █ █ ▀ ▀ ▀█▀██▀█▄█▄█
█ ▀▀▀ █ ██ █▀ ▄ ▄▄ ▄▄█▀ █
▀▀▀▀▀▀▀ ▀ ▀▀ ▀▀▀▀▀▀
v2 · 25×25 modules · https://opentui.com

##API

Encodes the input with a real QR encoder (byte mode, EC level L, versions 1–5, best-of-8 masking with penalty scoring) and renders it as ▀▄█ half-blocks. Pair with your terminal's URL-click support to make codes scannable.

properties
proptypedefaultdescription
valuestring-Payload, UTF-8 bytes; max 106 bytes
fgstring"#9ece6a"Dark module color
bgstring"#1a1b26"Light module background
quietnumber2Quiet-zone modules (spec requires 4 for scanners)

##Keymap

~/keymap
Display only

##Notes

  • The encoder (`qr-encoder.ts`) is dependency-free: GF(256) arithmetic, Reed–Solomon EC, pattern placement, mask scoring — the whole spec.
  • Returns `null` when the payload exceeds 106 bytes instead of rendering garbage.
  • Scanners usually need a quiet zone of 4 — bump `quiet` if a phone fails to read it.

##Source

Real implementation — this is the code that runs in your terminal.

tsxqrcode.tsx
1/* eslint-disable react/no-array-index-key -- These renderers draw a fixed
2 terminal grid: a child's identity *is* its row and column, and the grid
3 never reorders, so the index is the stable key rather than a stand-in
4 for one. */
5
6import { createElement as h, useMemo } from "react";
7import { encodeQR, qrToGlyphs, type QRMatrix } from "./qr-encoder";
8
9export interface QRCodeProps {
10 value: string;
11 fg?: string;
12 bg?: string;
13 quiet?: number;
14}
15
16export function QRCode({
17 value,
18 fg = "#9ece6a",
19 bg = "#1a1b26",
20 quiet = 2,
21}: Readonly<QRCodeProps>) {
22 const matrix: QRMatrix | null = useMemo(() => {
23 try {
24 return encodeQR(value);
25 } catch (error) {
26 // An unencodable payload renders nothing; report why rather than
27 // failing silently.
28 console.error(
29 `QRCode: cannot encode value${
30 error instanceof Error ? error.message : String(error)
31 }`,
32 );
33 return null;
34 }
35 }, [value]);
36
37 const lines = useMemo(
38 () => (matrix ? qrToGlyphs(matrix, quiet) : null),
39 [matrix, quiet],
40 );
41
42 if (!lines) return null;
43
44 return h(
45 "box",
46 { flexDirection: "column" },
47 lines.map((line, i) =>
48 h(
49 "text",
50 { key: i, fg, bg },
51 line,
52 ),
53 ),
54 );
55}
56