Skip to content

feat: add barcode component for email-safe HTML table barcodes#2960

Open
balcsida wants to merge 17 commits intoresend:canaryfrom
balcsida:feat/barcode-component
Open

feat: add barcode component for email-safe HTML table barcodes#2960
balcsida wants to merge 17 commits intoresend:canaryfrom
balcsida:feat/barcode-component

Conversation

@balcsida
Copy link

@balcsida balcsida commented Feb 15, 2026

Summary

  • Add new @react-email/barcode package that generates barcodes as pure HTML tables — no images needed, works in every email client
  • Supports 7 barcode formats: QR Code, Aztec Code, Data Matrix, Code 128, Code 39, EAN-13, UPC-A
  • Ported from qr2table with identical algorithms: D4 rectangle packing, lossy compression, Safari rowspan fix

Component API

<Barcode
  value="https://example.com"
  type="qrcode"              // qrcode | azteccode | datamatrix | code128 | code39 | ean13 | upca
  foregroundColor="#000000"
  backgroundColor="#ffffff"
  cellSize={4}
  quietZone={true}
  errorCorrection="M"        // L/M/Q/H (QR and Aztec only)
  lossy={false}
  lossyBudget={0.2}
  style={...}
/>

Output uses dangerouslySetInnerHTML with a <table> — same pattern as @react-email/markdown.

Key design decisions

  • Dependencies: qrcode-generator and bwip-js as regular dependencies (matches how @react-email/markdown uses marked)
  • Custom bwip-js drawing backend: Implements GridDrawing class with scanline polygon fill, avoiding any canvas/native dependency — fully synchronous, works in React render
  • D4 rectangle packing: Tries all 8 dihedral group orientations, picks the one with fewest <td> cells
  • Safari fix: Zero-width sizing cell per row to lock rowspan heights

Test plan

  • pnpm --filter @react-email/barcode build produces dist/
  • pnpm --filter @react-email/barcode test — 9 vitest tests pass:
    • QR Code render
    • Code 128 render
    • Aztec Code render
    • Custom foreground/background colors
    • Custom cellSize
    • Quiet zone toggle
    • Lossy compression mode
    • Safari sizing cell presence
    • Prop passthrough (style, data-testid)

Summary by cubic

Add @react-email/barcode to render QR and other barcodes as pure HTML tables in emails—no images. Uses a custom no-canvas bwip-js backend with packing/compression for smaller HTML and broad client support.

  • New Features

    • New @react-email/barcode component; supports qrcode, azteccode, datamatrix, code128, code39, ean13, upca.
    • Options: quiet zone, foreground/background colors, cell size, EC L/M/Q/H (QR/Aztec), optional lossy compression.
    • Optimizations: D4 packing, protection masks, 1D column uniformity, Safari rowspan fix.
    • Implementation: custom bwip-js grid backend (no canvas) and HTML table renderer with inline styles.
    • Build/test scaffold; 9 tests.
  • Bug Fixes

    • QR input now encoded in UTF-8 byte mode for non-ASCII.
    • Suspense tests: reverted unrelated changes; kept fetch mocking and simplified snapshot to avoid TLS flakiness and stabilize CI.

Written for commit 0d5bdfe. Summary will update on new commits.

@changeset-bot
Copy link

changeset-bot bot commented Feb 15, 2026

⚠️ No Changeset found

Latest commit: 0d5bdfe

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel
Copy link

vercel bot commented Feb 15, 2026

@balcsida is attempting to deploy a commit to the resend Team on Vercel.

A member of the Team first needs to authorize it.

@balcsida balcsida changed the base branch from main to canary February 15, 2026 16:15
@balcsida balcsida force-pushed the feat/barcode-component branch from 6a133b4 to e7aec55 Compare February 15, 2026 16:19
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 issues found across 31 files

Confidence score: 3/5

  • Potential data corruption risk: packages/barcode/src/generate-qr.ts passes string input to qrcode-generator as raw bytes, so non-ASCII/multi-byte characters may be truncated or corrupted
  • Two naming-convention violations (hasEC, generateQR) are style issues and low impact compared to the encoding concern
  • Given the concrete user-facing encoding risk (sev 7/10), this is a moderate-risk merge despite mostly stylistic issues
  • Pay close attention to packages/barcode/src/generate-qr.ts, packages/barcode/src/types.ts, packages/barcode/src/barcode.tsx - encoding handling and acronym naming consistency.
Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/barcode/src/generate-qr.ts">

<violation number="1" location="packages/barcode/src/generate-qr.ts:10">
P1: Potential data corruption for non-ASCII input due to missing UTF-8 encoding. The qrcode-generator library treats string input as raw bytes (ISO-8859-1) by default. Multi-byte characters will be truncated or corrupted.</violation>
</file>

<file name="packages/barcode/src/types.ts">

<violation number="1" location="packages/barcode/src/types.ts:25">
P2: Rule violated: **Initialisms and Acronyms Naming Conventions**

Rename `hasEC` to a normalized acronym form like `hasEc` to comply with the Initialisms and Acronyms Naming Conventions rule (all-caps acronyms inside identifiers are disallowed).</violation>
</file>

<file name="packages/barcode/src/barcode.tsx">

<violation number="1" location="packages/barcode/src/barcode.tsx:9">
P2: Rule violated: **Initialisms and Acronyms Naming Conventions**

Rename the `generateQR` identifier to `generateQr` to avoid all-uppercase acronyms inside camelCase/PascalCase identifiers, per the Initialisms and Acronyms Naming Conventions rule.</violation>
</file>

Since this is your first cubic review, here's how it works:

  • cubic automatically reviews your code and comments on bugs and improvements
  • Teach cubic by replying to its comments. cubic learns from your replies and gets better over time
  • Add one-off context when rerunning by tagging @cubic-dev-ai with guidance or docs links (including llms.txt)
  • Ask questions if you need clarification on any suggestion

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

@balcsida balcsida changed the title feat(barcode): Add barcode component for email-safe HTML table barcodes feat: add barcode component for email-safe HTML table barcodes Feb 15, 2026
@socket-security
Copy link

socket-security bot commented Feb 15, 2026

All alerts resolved. Learn more about Socket for GitHub.

This PR previously contained dependency changes with security issues that have been resolved, removed, or ignored.

View full report

@pkg-pr-new
Copy link

pkg-pr-new bot commented Feb 15, 2026

Open in StackBlitz

npm i https://pkg.pr.new/resend/react-email/@react-email/barcode@2960
npm i https://pkg.pr.new/resend/react-email/@react-email/render@2960

commit: 0d5bdfe

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments