JavaScript QR Code — the library
Create beautiful QR codes in JavaScript, entirely in the browser or in Node. One file, no dependencies, no server: no Google Charts, no quickchart.io.
Quick start: zero lines of JavaScript
Add the script and write the text in a data-qrcode attribute. The library draws every one of them when the page loads.
<script src="qrcode.min.js"></script>
<div data-qrcode="https://example.com"></div>
<div data-qrcode="Hello!" data-size="200" data-style="ocean" data-caption="Scan me"></div>
Attributes: data-size, data-style, data-color, data-background, data-ecl, data-dots, data-frame, data-ball, data-caption, data-logo (image URL), data-format (canvas, svg or img), data-margin. Add data-qrcode-manual to <html> to turn the automatic drawing off.
From JavaScript
// draw inside an element (id, CSS selector or element) — returns a Promise
JSQRCode.render("#box", "https://example.com", { size: 300, style: "soft" });
// with a logo: error correction goes to H automatically
JSQRCode.render("#box", "https://example.com", { logo: "logo.png", caption: "Our menu" });
// get the image
const png = JSQRCode.toDataURL("Hello", { size: 512 }); // "data:image/png;base64,..."
const svg = JSQRCode.toSVG("Hello", { size: 1024, dots: "dots" }); // vector, for print
// let the user download it
JSQRCode.download("Hello", { style: "sunset" }, "my-qr.svg");
Wi‑Fi, contacts, payments…
JSQRCode.payload builds the text in the right standard format, with all the escaping done for you:
JSQRCode.render("#wifi", JSQRCode.payload.wifi({ ssid: "Home", pass: "secret;123", sec: "WPA" }));
JSQRCode.payload.contact({ first: "Ada", last: "Lovelace", org: "ACME", mobile: "+39 333 1234567", email: "ada@acme.it" });
JSQRCode.payload.epc({ name: "ACME srl", iban: "IT60X0542811101000000123456", amount: "25.50", reference: "Invoice 12" });
JSQRCode.payload.whatsapp({ number: "+39 333 1234567", message: "Hi!" });
// also: email, sms, phone, geo, event, text
And the other way round: JSQRCode.parse(text) tells you what a scanned text is ({ type, fields, title }).
Options
| Option | Default | What it does |
|---|---|---|
size | 256 | Width in pixels (16–4096). |
ecl | "M" ("H" with a logo) | Error correction: L 7%, M 15%, Q 25%, H 30%. |
boostEcl | true | Use a higher correction level for free when the text still fits in the same size. |
style | — | Ready-made look: classic, soft, ocean, sunset, forest, grape, mint, night. Other options override it. |
color, background | #111827, #fff | Colors. transparent: true for no background. |
gradient, fg2, angle | "none" | "linear" or "radial" from color to fg2. |
dots | "square" | square, rounded, dots, small, fluid, classy, diamond, vertical, horizontal. |
frame, ball | "square" | Shape of the three corner "eyes": square, rounded, circle, leaf, edge / octagon. |
eye, eyeBall | — | A different color for the corners. |
logo, logoScale | —, 0.22 | Image (URL or loaded <img>) in the middle, with a white plate. |
caption, captionStyle | —, "below" | Text under the code, or in a "badge". |
margin, radius | 4, 0 | Quiet zone in modules, rounded background corners. |
format | "canvas" | For render(): canvas, svg or img. |
All functions
| Function | Returns |
|---|---|
render(target, text, options) | Promise of the element drawn inside target. |
toDataURL(text, options) / toDataURLAsync(…) | PNG as data URL (the async one loads a logo URL first). |
toCanvas(text, options, [canvas]) | A <canvas>. |
toSVG(text, options) | SVG markup (works in Node too). |
matrix(text, options) | { size, version, ecl, mask, rows }: the raw modules, to draw them your way. |
download(text, options, "name.png|svg") | Saves the file. |
payload.*, parse(text), maxBytes(ecl), contrast(a, b), auto() | Contents, scanned-text parser, capacity, WCAG contrast, redraw [data-qrcode]. |
Node.js
const JSQRCode = require("./qrcode.js");
require("fs").writeFileSync("qr.svg", JSQRCode.toSVG("https://example.com", { size: 1024, style: "forest" }));
console.log(JSQRCode.matrix("Hi").rows); // [[1,1,1,1,1,1,1,0,…], …]
Upgrading from 1.x / 2.x
Old pages keep working: the 3.0 file still provides qrgchart.getQRCode(), qrgchart.standardimQR(), qrgchart.getQRimg() and qrgchart.shareQRimg(). The difference is that the image is now drawn locally: the old versions asked Google Charts, and later quickchart.io, to draw it, so your users' text went to a third party and the code broke when those services closed. Just replace qr-2.x.js with qrcode.min.js.
<!-- before --> <script src="js/qr-2.10.js"></script>
<!-- after --> <script src="js/qrcode.min.js"></script>
<!-- your existing code does not change -->
qrgchart.getQRCode("containerqr", 300, 300, "https://example.com");
How it is tested
The encoder follows ISO/IEC 18004 and is the same one inside the Firefox add-on. Every release is checked against an independent reference implementation (with the same version, level and mask it produces exactly the same modules) and every style is read back by an independent decoder, so a design that looks good but does not scan never ships.