A Typst 2D barcode generator, natively rendered using an optimized path.
It supports:
- Data Matrix (ECC 200 including DMRE)
- QR code (Model 2 and Micro variants)
#import "@preview/zebra:0.1.0": datamatrix, qrcode
#datamatrix("Data Matrix")
#qrcode("QR code")
Arguments
Both datamatrix and qrcode share the same arguments.
-
data:str|bytes(positional)When providing a string that includes non‑ASCII characters, an ECI UTF-8 designator is automatically added.
If that is not desired, pass the string asbytes. -
options:dictionary(default:(:))Barcode specific encoding options. See below.
-
quiet-zone:int|bool|none(default:0)When
true, the recommended quiet zone is added (4 for QR codes, 1 for Data Matrix). -
widthorheightormodule-size:auto|length(default:module-size: 3pt)The other two properties are calculated automatically.
module-sizeis the size of a single black or white square. -
fill:color|gradient(default:black) -
background-fill:none|color|gradient(default:none)
Examples:
#qrcode("data")
#qrcode(bytes((1, 2, 3)))
#qrcode("Bär") // with UTF-8 ECI
#qrcode(bytes("Bär")) // without UTF-8 ECI
#qrcode("data", quiet-zone: true, background-fill: white)
#qrcode("data", quiet-zone: 2, background-fill: white)
#qrcode("data", width: 5em)
#qrcode("data", height: 5em)
#qrcode("data", module-size: 0.5em)
#qrcode("data", fill: purple, background-fill: lime)
Data Matrix
Options:
encodation-typenone: Automatically determines the best encoding (default)"ascii": Used for numeric and ASCII"c40""text""x12""edifact""base256": Arbitrary data
symbols"square"(default)"rect": Rectangular symbols"rect-8",
"rect-12",
"rect-16": Sizes with a specific height"rect-ext": Rectangular symbols including symbols introduced in the rectangular extension (DMRE)"rect-ext-8",
"rect-ext-12",
"rect-ext-16",
"rect-ext-20",
"rect-ext-24",
"rect-ext-26": Sizes with a specific height
Examples:
// A rectangular code
#datamatrix("A rectangular Data Matrix", options: (symbols: "rect"))
// Forcing `base256` to encode the data
// Useful for consistently sized codes regardless of the data value, e.g. for UUIDs
#datamatrix(bytes(range(0, 16)), options: (encodation-type: "base256"))
The encoding is done by the datamatrix crate.
QR Code
Options:
versions"normal"(default)"micro": Micro QR code
mode: The character set used to encode the datanone: Automatically determines the best encoding (default)"numeric": 0-9"alphanumeric": 0-9, A-Z, space,$%*+-./:"byte": Arbitrary data
ec-level: The error correction level"l": Low ~7%"m": Medium ~15% (default)"q": Quartile ~25%"h": High ~30%
Examples:
// Decrease or increase the error correction level
#qrcode("QR code with low ec", options: (ec-level: "l"))
// Force `alphanumeric` mode
// Useful for consistently sized codes regardless of the data value
#qrcode("0-9 A-Z $%*+-./:", options: (mode: "alphanumeric"))
// A Micro QR code
#qrcode("01234", options: (versions: "micro", ec-level: "l"))
The encoding is done by the qrcode crate.
Native Rendering
Zebra renders the barcode using a single curve scaled to the desired size:
#block(width: 3.5pt, height: 3.5pt, {
scale(350%, origin: top + left, {
curve(fill: black, fill-rule: "even-odd", ..path)
})
})
When exporting to SVG, this results in:
<path fill-rule="evenodd" d="M 0 0h 1 v 1 h 1 v -1 h 1 v 2 h 1 ..." transform="matrix(3.5 0 0 3.5 0 0)" />
Compared to generating an SVG and passing it to the image element:
#image("<svg ...", width: 3.5pt, height: 3.5pt)
<image href="data:image/svg+xml;base64,PHN2ZyAuLi4 ..." width="3.5" height="3.5" />
This does not affect the PDF export, but offers all color options in Typst (such as CMYK) that are not available in an SVG.
Optimized Path
Zebra always combines all horizontally or vertically adjacent modules (black squares) into one shape and further optimizes the path to decrease the number of draw instructions.
The algorithm used for all barcodes is implemented in the datamatrix crate.
Other Packages
-
Uses the JavaScript package
qrcode-svg.
The generated SVG contains a<rect>element for every black module. This results in a small gap between modules. -
Impressive Typst-only implementation of the encoding.
Typst-native rendering using ablockelement for every black module. This results in a small gap between modules. -
Uses the
qrcodecrate as well.
The generated SVG contains a single path with separate draw instructions for every black module. -
Uses the
zintC library containing a large number of different barcodes.
The generated SVG contains a single path which combines adjacent modules in the same row.
The best alternative package.