Como Gerar QR Code em JavaScript (2026): Guia Completo com Código Pronto
Gerar QR Code em JavaScript é tarefa de algumas linhas quando se conhece a biblioteca certa. Este guia cobre as três principais libs em 2026, casos de uso (URL, PIX, WiFi, vCard), customização visual com logo, download em PNG e SVG, e testes automatizados para garantir que o QR realmente escaneia.
Por Vitor Morais
Fundador do MochaLabz ·
Gere QR Codes online
URL, texto, WiFi, vCard ou PIX — download em PNG e SVG, customização de cor.
Usar gerador →QR Code virou padrão universal em 2020 (pandemia acelerou adoção) e segue em 2026 como interface entre papel e digital. Cardápios, pagamentos PIX, Wi-Fi de café, login em serviços, eventos, rastreio de entrega, vCards — tudo codificado em pontos brancos e pretos. Gerar QR em JavaScript é tarefa de menos de 10 linhas quando você sabe qual biblioteca usar.
Este guia cobre as três principais bibliotecas em 2026, os casos de uso mais comuns com código pronto (URL, PIX, WiFi, vCard), customização visual com logo, download nos formatos PNG e SVG, e como testar automatizadamente se o QR gerado realmente escaneia.
Como funciona QR Code (versão rápida)
QR é uma matriz 2D de pontos brancos e pretos que codifica dados via Reed-Solomon (correção de erro). Os três quadrados grandes nos cantos são o padrão de localização — qualquer leitor identifica orientação por eles. O conteúdo central é a combinação de: formato (URL, texto, vCard...), máscara de bit (oito variações padronizadas) e código de correção de erros (4 níveis: L, M, Q, H).
Contexto
Três bibliotecas principais em 2026
| Critério | Tamanho | Melhor para |
|---|---|---|
| qrcode | ~50 KB | Uso geral, padrão da indústria |
| qr-code-styling | ~200 KB | QR visual com logo e cores customizadas |
| qr-creator | ~20 KB | Quando peso do bundle importa muito |
| qrcode-svg | ~15 KB | Apenas SVG, sem canvas |
| qrious | ~25 KB | Alternativa leve, canvas-only |
Biblioteca qrcode: a escolha padrão
Instala via npm e cobre 90% dos casos. Suporta canvas (preview), SVG (responsivo), data URL (embedir em HTML) e string no terminal (CLI).
npm install qrcode
# Se usar TypeScript:
npm install -D @types/qrcodeUso básico: URL em canvas
import QRCode from "qrcode";
const canvas = document.getElementById("qr") as HTMLCanvasElement;
await QRCode.toCanvas(canvas, "https://mochalabz.com", {
width: 320,
margin: 2,
color: {
dark: "#28190a", // cor dos pontos
light: "#fffdf9", // cor do fundo
},
});Gerar como SVG (ideal pra web)
import QRCode from "qrcode";
const svgString = await QRCode.toString("https://mochalabz.com", {
type: "svg",
width: 320,
margin: 2,
color: { dark: "#28190a", light: "#fffdf9" },
});
// Injetar no DOM
document.getElementById("qr-container")!.innerHTML = svgString;Gerar como Data URL (PNG inline)
import QRCode from "qrcode";
const dataUrl = await QRCode.toDataURL("https://mochalabz.com");
// "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg..."
// Usar em <img>
const img = document.createElement("img");
img.src = dataUrl;
document.body.appendChild(img);Salvar em arquivo (Node.js)
import QRCode from "qrcode";
// Gera e salva PNG direto no disco
await QRCode.toFile(
"./meu-qr.png",
"https://mochalabz.com",
{
width: 512,
margin: 2,
color: { dark: "#000000", light: "#ffffff" },
errorCorrectionLevel: "H",
},
);Biblioteca qr-code-styling: para QR com identidade visual
Quando você precisa de logo no meio, pontos em formato custom (redondos, estrelas) ou cores gradient, qr-code-styling entrega. Mais pesada (~200 KB) mas suporta controle visual completo.
npm install qr-code-stylingimport QRCodeStyling from "qr-code-styling";
const qrCode = new QRCodeStyling({
width: 320,
height: 320,
type: "svg",
data: "https://mochalabz.com",
image: "/logo.png", // logo central
dotsOptions: {
color: "#28190a",
type: "rounded", // rounded | dots | classy | classy-rounded | extra-rounded
},
backgroundOptions: {
color: "#fffdf9",
},
cornersSquareOptions: {
color: "#c98238",
type: "extra-rounded",
},
imageOptions: {
crossOrigin: "anonymous",
margin: 8, // padding em torno do logo
imageSize: 0.3, // 30% do QR
},
qrOptions: {
errorCorrectionLevel: "H", // obrigatório com logo
},
});
qrCode.append(document.getElementById("qr-container")!);
// ou
qrCode.download({ name: "meu-qr", extension: "svg" });Dica
Casos de uso com código pronto
1. URL simples
await QRCode.toCanvas(canvas, "https://mochalabz.com");2. Texto livre
await QRCode.toCanvas(canvas, "Seu texto qualquer aqui");3. WiFi (conectar automaticamente)
function gerarQrWifi({
ssid,
senha,
encriptacao = "WPA", // WPA | WEP | nopass
hidden = false,
}: {
ssid: string;
senha: string;
encriptacao?: "WPA" | "WEP" | "nopass";
hidden?: boolean;
}) {
const payload = `WIFI:T:${encriptacao};S:${ssid};P:${senha};H:${hidden};;`;
return QRCode.toDataURL(payload);
}
// Uso
const qr = await gerarQrWifi({
ssid: "MochaCafe",
senha: "caramelo2026",
});
// Usuário escaneia → celular conecta automaticamente ao WiFi4. vCard (contato)
function gerarQrVCard({
nome,
empresa,
telefone,
email,
site,
}: {
nome: string;
empresa?: string;
telefone?: string;
email?: string;
site?: string;
}) {
const vcard = [
"BEGIN:VCARD",
"VERSION:3.0",
`FN:${nome}`,
empresa ? `ORG:${empresa}` : "",
telefone ? `TEL:${telefone}` : "",
email ? `EMAIL:${email}` : "",
site ? `URL:${site}` : "",
"END:VCARD",
]
.filter(Boolean)
.join("\n");
return QRCode.toDataURL(vcard);
}
const qr = await gerarQrVCard({
nome: "Vitor Morais",
empresa: "MochaLabz",
email: "vitor@mochalabz.com",
site: "https://mochalabz.com",
});5. E-mail com assunto pré-preenchido
const payload = `mailto:contato@empresa.com?subject=Orcamento&body=Olá,`;
await QRCode.toCanvas(canvas, payload);6. SMS
const payload = `sms:+5511999999999?body=Olá,`;
await QRCode.toCanvas(canvas, payload);7. Localização (Google Maps)
const payload = `geo:-23.550520,-46.633308?q=Praça da Sé`;
await QRCode.toCanvas(canvas, payload);8. PIX (pagamento)
Pix tem payload específico EMV. O formato completo exige múltiplos campos Bacen; para gerar corretamente, use biblioteca dedicada:
npm install pix-utilsimport { createStaticPix, hasError } from "pix-utils";
import QRCode from "qrcode";
const pix = createStaticPix({
merchantName: "JOAO DA SILVA",
merchantCity: "SAO PAULO",
pixKey: "joao@exemplo.com",
infoAdicional: "Pagamento curso",
transactionAmount: 50.0,
});
if (hasError(pix)) {
throw new Error(pix.error);
}
const payload = pix.toBRCode();
const qrCodeImage = await QRCode.toDataURL(payload);
// Exibir no site
document.querySelector("img#pix-qr")!.setAttribute("src", qrCodeImage);Atenção
Componente React pronto
Em projetos React (Next.js, Vite, Remix), você geralmente quer um componente reusável:
"use client";
import { useEffect, useRef } from "react";
import QRCode from "qrcode";
interface QRCodeProps {
data: string;
size?: number;
color?: string;
background?: string;
}
export function QRCodeImage({
data,
size = 320,
color = "#000000",
background = "#ffffff",
}: QRCodeProps) {
const canvasRef = useRef<HTMLCanvasElement>(null);
useEffect(() => {
if (!canvasRef.current) return;
QRCode.toCanvas(canvasRef.current, data, {
width: size,
margin: 2,
color: { dark: color, light: background },
errorCorrectionLevel: "M",
}).catch(console.error);
}, [data, size, color, background]);
return <canvas ref={canvasRef} aria-label="QR Code" />;
}
// Uso
<QRCodeImage data="https://mochalabz.com" size={256} />Download do QR (PNG ou SVG)
// PNG a partir de canvas
function baixarPng(canvas: HTMLCanvasElement, nome: string) {
const link = document.createElement("a");
link.href = canvas.toDataURL("image/png");
link.download = `${nome}.png`;
link.click();
}
// SVG a partir de string
async function baixarSvg(data: string, nome: string) {
const svg = await QRCode.toString(data, {
type: "svg",
width: 512,
margin: 2,
});
const blob = new Blob([svg], { type: "image/svg+xml" });
const link = document.createElement("a");
link.href = URL.createObjectURL(blob);
link.download = `${nome}.svg`;
link.click();
URL.revokeObjectURL(link.href);
}Testes automatizados: garantir que o QR escaneia
Geração correta não garante leitura. Use jsQR para decodificar o próprio QR e validar:
npm install -D jsqr jest-canvas-mock// qr-code.test.ts
import QRCode from "qrcode";
import jsQR from "jsqr";
import { createCanvas } from "canvas";
describe("QR Code", () => {
it("gera QR que decodifica para o dado original", async () => {
const data = "https://mochalabz.com";
const canvas = createCanvas(320, 320);
await QRCode.toCanvas(canvas, data);
const ctx = canvas.getContext("2d")!;
const imageData = ctx.getImageData(0, 0, 320, 320);
const decoded = jsQR(imageData.data, 320, 320);
expect(decoded?.data).toBe(data);
});
it("gera QR para vCard válido", async () => {
const vcard = "BEGIN:VCARD\nVERSION:3.0\nFN:Teste\nEND:VCARD";
const canvas = createCanvas(320, 320);
await QRCode.toCanvas(canvas, vcard);
const ctx = canvas.getContext("2d")!;
const imageData = ctx.getImageData(0, 0, 320, 320);
const decoded = jsQR(imageData.data, 320, 320);
expect(decoded?.data).toContain("BEGIN:VCARD");
});
});Armadilhas comuns
- Dados longos com ECC baixo: URLs compridas + ECC L geram QR denso que falha em scan rápido. Aumente para M ou use URL encurtada.
- Cores de baixo contraste: cinza em branco, pastel em pastel. Teste em luz ruim antes de publicar.
- Logo muito grande: cobre quiet zone ou pattern de localização. Mantenha em 25-30% do tamanho total.
- Sem quiet zone: o espaço em branco ao redor do QR é obrigatório. A margem default (2 módulos) costuma ser mínima; considere 4 em material impresso.
- QR muito pequeno: abaixo de 2cm impresso, leitores precisam de foco perfeito. Mínimo saudável: 2,5-3cm.
- Confiar em canvas para download de alta resolução: canvas tem DPI do monitor. Para impressão, gere PNG em pelo menos 1024×1024 ou SVG.
Customização visual sem quebrar leitura
| Critério | Seguro | Cuidado |
|---|---|---|
| Cor dos pontos | Qualquer cor escura | Gradient que reduz contraste |
| Forma dos pontos | Rounded, dots | Formas muito estilizadas |
| Logo central | Até 30% do tamanho, ECC H | Mais que 30% ou sem ECC H |
| Borda externa | Deixe quiet zone (margem) | Sem margem ao redor |
| Background textura | Sólido, claro | Padrão que confunde o leitor |
QR gerador completo (cliente web)
Para oferecer ao usuário final a capacidade de gerar QR customizado no site, você combina input de formulário + biblioteca + download. Um exemplo completo em React consolida tudo:
"use client";
import { useEffect, useRef, useState } from "react";
import QRCode from "qrcode";
export default function GeradorQRCode() {
const canvasRef = useRef<HTMLCanvasElement>(null);
const [data, setData] = useState("https://mochalabz.com");
const [cor, setCor] = useState("#28190a");
const [bg, setBg] = useState("#fffdf9");
useEffect(() => {
if (!canvasRef.current || !data) return;
QRCode.toCanvas(canvasRef.current, data, {
width: 320,
margin: 2,
color: { dark: cor, light: bg },
errorCorrectionLevel: "M",
}).catch(console.error);
}, [data, cor, bg]);
const baixarPng = () => {
if (!canvasRef.current) return;
const link = document.createElement("a");
link.href = canvasRef.current.toDataURL("image/png");
link.download = "qrcode.png";
link.click();
};
return (
<div>
<input value={data} onChange={(e) => setData(e.target.value)} />
<input type="color" value={cor} onChange={(e) => setCor(e.target.value)} />
<input type="color" value={bg} onChange={(e) => setBg(e.target.value)} />
<canvas ref={canvasRef} />
<button onClick={baixarPng}>Baixar PNG</button>
</div>
);
}QR em uma frase
Gerar QR Code em JavaScript é 3 linhas de código com biblioteca qrcode, 10 linhas com logo e customização via qr-code-styling, e serve para URL, WiFi, vCard, PIX e praticamente qualquer texto codificável. A dificuldade real não está no gerador — está em testar que o QR escaneia em ambiente hostil (papel ruim, luz fraca, celular antigo). Gere certo, teste sempre.
Perguntas frequentes
Qual biblioteca JavaScript usar para gerar QR Code?+
Três opções populares em 2026. (1) qrcode (por Ryan Day) — ~50 KB, pronta, renderiza canvas/SVG/terminal, suporta todos os modos. (2) qr-code-styling — mais visual, permite logo no centro, formas customizadas de pontos, mais pesada (~200 KB). (3) qr-creator — leve (~20 KB), mínima. Para 90% dos casos, qrcode é a escolha. Para QR com identidade visual da marca (logo, cores), use qr-code-styling.
QR Code pode ter imagem no meio (logo)?+
Sim. O padrão QR ECC (Error Correction Code) permite cobrir até 30% dos pixels com logo e ainda funcionar. Use nível de correção 'H' (High) para maior tolerância. Bibliotecas como qr-code-styling fazem o overlay automaticamente. Para sites importantes de produção, teste escaneando em múltiplos leitores — logos muito grandes ou colocados errado reduzem a leitura mesmo com ECC alto.
Quais formatos de saída um QR Code suporta?+
Dois principais: PNG (raster, universal, bom para impressão e web) e SVG (vetorial, escalável sem perda, ideal para mídia digital com diferentes tamanhos). Canvas também é usado para preview em tempo real no navegador. A escolha depende do destino: PNG para redes sociais e impressão; SVG para páginas web responsivas.
Como gerar QR Code para Pix?+
O Pix usa um payload EMV específico com chaves como merchant account, valor e identificador da transação. Você monta a string EMV (conforme padrão Bacen) e codifica em QR. Bibliotecas específicas: pix-qrcode-js e pix-utils simplificam. Para integração com conta comercial real, o Pix Cobrança exige certificado digital e endpoint do banco — sua biblioteca gera apenas o QR visual a partir do payload que o banco retorna.
QR Code precisa de internet para gerar?+
Não. A geração é puramente algorítmica — nenhuma API externa ou servidor é necessário. Qualquer biblioteca client-side em JavaScript funciona 100% offline no navegador. Use serviço online apenas se você não quiser bibliotecas no código; mas usar API para algo tão simples adiciona dependência e latência sem benefício.
Existe tamanho máximo para QR Code?+
Sim. Versão 40 (a maior) suporta ~4.296 caracteres alfanuméricos ou ~2.953 binários. Mas na prática, QR com muito conteúdo vira denso demais para scan confiável — câmeras precisam de qualidade perfeita. Para URLs, mantenha abaixo de 200 caracteres (use encurtador). Para vCard, resumido. Para PIX, payload padrão tem 200-400 caracteres e funciona bem.
QR Code funciona em modo escuro?+
Sim, desde que o contraste entre cor dos pontos e do fundo seja suficiente. Padrão é preto em branco. Variações válidas: qualquer cor escura em fundo claro ou vice-versa. Evite contraste ruim (cinza médio em branco) e combinações que quebrem leitura (vermelho em laranja). Para QR em material escuro, use pontos claros em fundo escuro — funciona em qualquer leitor moderno.
Como posso testar se o QR gerado realmente funciona?+
Três métodos. (1) Escaneie com o próprio celular usando a câmera padrão (iOS 12+ e Android 9+ detectam nativamente). (2) Use biblioteca de decodificação em JavaScript (jsQR, zxing) no próprio teste automatizado. (3) Em produção, teste em múltiplos leitores e ambientes de iluminação variada. Para uso comercial, nunca confie apenas no QR renderizado na sua tela — teste em papel impresso, em tela pequena e com iluminação fraca.
Artigos relacionados
O Que É QR Code (2026): Como Funciona, Tipos, Usos e Boas Práticas
Guia completo do QR Code: origem, como a matriz codifica dados, tipos (estático, dinâmico, PIX, Wi-Fi, vCard), níveis de correção de erros, segurança e casos de uso reais.
QR Code em Marketing (2026): Estratégias que Geram Resultado Real
Guia completo de QR Code em marketing: campanhas que funcionam, rastreamento com UTM, cases reais, integração com funil e erros que matam conversão.