Skip to content

Add ESM bundle support#1280

Open
rezrah wants to merge 13 commits intomainfrom
rezrah/esm-lib
Open

Add ESM bundle support#1280
rezrah wants to merge 13 commits intomainfrom
rezrah/esm-lib

Conversation

@rezrah
Copy link
Copy Markdown
Collaborator

@rezrah rezrah commented Mar 9, 2026

Summary

Towards https://github.com/github/brand-marketing-design/issues/2759

Adds an ESM entrypoint for @primer/react-brand so that modern UI frameworks and bundlers can import Primer Brand components in a more efficient way.

The previous UMD bundle and import mechanisms are still in-place and default. No breaking changes are proposed as part of this change.

The ESM bundles will allow users of the package to import only the components and styles they need, rather than the entire library. It also simplifies the way styles are loaded, which is now performed automatically.

Eventually ESM will become the default, and we will remove the UMD + Webpack legacy bundles. This will happen once we ship the v1 release of Primer Brand.

Build times (cold start)
Webpack (UMD) Vite (ESM)
10.1s 1.1s

List of notable changes:

  • Added Vite 8 to create a new entrypoint at @primer/react-brand/esm, which users can opt-into.
    • Note: Bundlers won't pick this up automatically to avoid a breaking change. This will be deferred to the v1 release.
  • Updated the Getting Started guide to include new documentation on ESM bundles
  • Fixed integration tests for Astro
  • Updated integration tests for Next.js to run in matrix strategy and test both UMD and the new ESM bundles
  • Added a new bundle size comment to PRs for future use

What should reviewers focus on?

  • Check the CI checks pass first
  • Take the canary package and install it into a new Next.js or Tanstack Start installation using ESM guide
  • Verify that the instructions are valid

Steps to test:

  1. Go to this updated documentation guide
  2. Install the canary package from this repo in your own, separate ESM-compatible framework
  3. Verify it works as expected

Supporting resources (related issues, external links, etc):

Contributor checklist:

  • All new and existing CI checks pass
  • Tests prove that the feature works and covers both happy and unhappy paths
  • Any drop in coverage, breaking changes or regressions have been documented above
  • UI Changes contain new visual snapshots (generated by adding update snapshots label to the PR)
  • All developer debugging and non-functional logging has been removed
  • Related issues have been referenced in the PR description

Reviewer checklist:

  • Check that pull request and proposed changes adhere to our contribution guidelines and code of conduct
  • Check that tests prove the feature works and covers both happy and unhappy paths
  • Check that there aren't other open Pull Requests for the same update/change

Screenshots:

New bundle size comment in PRs (scroll down to see the real version):

Screenshot 2026-03-26 at 11 15 29

@rezrah rezrah requested a review from a team as a code owner March 9, 2026 10:31
Copilot AI review requested due to automatic review settings March 9, 2026 10:31
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 9, 2026

🦋 Changeset detected

Latest commit: 15aebdb

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 8 packages
Name Type
@primer/react-brand Minor
@primer/brand-docs Minor
@primer/brand-css Minor
@primer/brand-primitives Minor
@primer/brand-e2e Minor
@primer/brand-fonts Minor
@primer/brand-config Minor
@primer/brand-storybook Minor

Not sure what this means? Click here to learn what changesets are.

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

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 9, 2026

🟢 No design token changes found

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 9, 2026

🟢 Bundle size report

CheckMainBranchChange
UMD — full bundle (JS)0 B93.16 kB🆕 93.16 kB
UMD — full bundle (CSS)0 B59.63 kB🆕 59.63 kB
ESM — full bundle (JS + CSS)0 B1.39 MB🆕 1.39 MB
ESM — tree-shaken simple (Button)0 B62.70 kB🆕 62.70 kB
ESM — tree-shaken complex (ActionMenu)0 B71.34 kB🆕 71.34 kB

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 9, 2026

⚠️ Visual differences found

Our visual comparison tests found UI differences.

Please review the differences by using the test artifacts to ensure that the changes were intentional.

Artifacts can be downloaded and reviewed locally.

Download links are available at the bottom of the workflow summary screen.

Example:

artifacts section of workflow run

If the changes are expected, please run npm run test:visual:update-snapshots to replace the previous fixtures.

Review visual differences

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 9, 2026

🟢 No unit test coverage changes found

All components and hooks with tests maintain the same coverage as the main branch.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds an ESM build/output pathway for @primer/react-brand alongside the existing UMD build, plus CI/docs updates to support and validate the new distribution and bundle-size reporting.

Changes:

  • Added a Vite-based ESM build (packages/react/esm) with a new @primer/react-brand/esm export path and corresponding TypeScript declarations.
  • Introduced bundle size checks (Size Limit + GitHub Action) and a script to generate a PR comment report.
  • Updated Next.js integration tests and docs to exercise/describe UMD vs ESM consumption paths.

Reviewed changes

Copilot reviewed 23 out of 26 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
packages/repo-configs/scripts/bundle-size-report.js Generates PR comment output for Size Limit comparisons.
packages/react/vite.esm.config.ts Adds Vite build config for the ESM output, including CSS module naming and CSS injection.
packages/react/tsconfig.esm.json Emits ESM declaration files into esm/.
packages/react/src/index.esm.ts Adds an ESM entry that re-exports the main index.
packages/react/src/css/stylesheets.ts Adds a noop export intended to prevent global styles from being tree-shaken away.
packages/react/src/LogoSuite/LogoSuite.tsx Switches play/pause icons to Octicons components.
packages/react/scripts/postbuild Copies LICENSE into esm/ output.
packages/react/package.json Adds exports map entries for /esm, adds ESM build script, and updates sideEffects/files.
packages/react/.gitignore Ignores esm/ output.
packages/e2e/integration-tests/fixtures/index.umd.ts Updates UMD fixture imports and ensures global CSS is loaded for UMD case.
packages/e2e/integration-tests/fixtures/index.esm.ts Switches fixture imports to @primer/react-brand/esm.
packages/e2e/integration-tests/fixtures/KitchenSink.tsx Removes global CSS import (now handled in the UMD fixture barrel).
package.json Adds size script and Size Limit deps.
package-lock.json Locks new dependencies (Size Limit, Vite-related, Octicons bump, etc.).
apps/next-docs/package.json Bumps @primer/octicons-react.
apps/next-docs/next-env.d.ts Changes Next route types reference (currently problematic).
apps/next-docs/content/** Adds/adjusts docs navigation + new ESM getting-started guide.
.size-limit.js Defines bundle-size checks for UMD and ESM (including tree-shaken cases).
.gitignore Ignores esm/ output and adds an integration-test artifact ignore entry (currently mismatched).
.github/workflows/integration_test_nextjs.yml Runs Next.js integration tests for both UMD and ESM setups via a matrix.
.github/workflows/bundle_size.yml Adds PR-time bundle-size reporting workflow.
.changeset/free-planets-fold.md Changeset describing the new ESM entry point and usage.

You can also share your feedback on Copilot code review. Take the survey.

@rezrah rezrah changed the title [WIP] Add ESM support Add ESM bundle support Mar 26, 2026
Copy link
Copy Markdown
Collaborator

@danielguillan danielguillan left a comment

Choose a reason for hiding this comment

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

Great work! Just one minor fix in the changeset and a question regarding sideEffects.


We recommend switching to ESM as soon as possible, as it will eventually become the default in future.

🔗 [Get started with ESM](https://primer.style/brand/introduction/getting-started/esm)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
🔗 [Get started with ESM](https://primer.style/brand/introduction/getting-started/esm)
🔗 [Get started with ESM](https://primer.style/brand/getting-started/esm)

"sideEffects": [
"**/*.css",
"./esm/index.esm.js",
"./src/css/stylesheets.ts"
Copy link
Copy Markdown
Collaborator

@danielguillan danielguillan Mar 31, 2026

Choose a reason for hiding this comment

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

Should this use the compiled output path instead? I'm not sure how to verify this.

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.

3 participants