wxt-dev / wxt-dev/wxt

Avoid duplicating shared CSS across multiple WXT entrypoints

Open
#2,605 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

pending-triage
Dominant language
TypeScript
Stars
10.5k
Forks
564
PR merge metrics
No merged PRs in 30d

Description

When multiple WXT entrypoints import the same CSS file, WXT generates separate CSS for each entrypoint.

For example:

src/
├── entrypoints/
│   ├── popup/
│   ├── aliexpress.content/
│   └── ebay.content/
│
└── styles/
    └── tailwind.css

All three use:

import "@/styles/tailwind.css";

But the build effectively produces:

                 tailwind.css
                     │
          ┌───────────┼───────────┐
          ▼           ▼           ▼
       popup.css  aliexpress.css  ebay.css
          │           │              │
          └───────────┴──────────────┘
                  duplicated CSS

Instead, it would be ideal to have:

                 shared.css
                     │
        ┌────────────┼────────────┐
        ▼            ▼            ▼
      Popup      AliExpress      eBay

Why this matters

This becomes especially problematic with Tailwind CSS, where the generated stylesheet can be relatively large.

It can cause:

  • 📦 Larger extension builds
  • 💾 Duplicate CSS in the final dist
  • ⚡ Unnecessary CSS parsing/loading
  • 📈 Increasing overhead as more content scripts are added
  • 🧩 More complexity when sharing UI components/design systems

This is common when an extension has:

Popup
Options
Side panel
Content script A
Content script B
Content script C
...
        ↓
   Same UI/CSS

Expected behavior

WXT should ideally detect shared CSS dependencies and emit them as a single shared CSS asset:

dist/
├── assets/
│   └── shared-[hash].css
├── popup/
├── content-scripts/
│   ├── aliexpress.js
│   └── ebay.js
└── ...

Multiple entrypoints could then reference the same CSS asset.

Current workaround

Developers can manually place CSS in public/ and load it with:

const link = document.createElement("link");

link.rel = "stylesheet";
link.href = browser.runtime.getURL("/shared.css");

document.head.appendChild(link);

However, this means manually managing CSS that should ideally be handled by WXT's build system.

Request

Could WXT support shared/deduplicated CSS chunks across multiple entrypoints, similar to shared JavaScript dependencies?

This would significantly reduce build size and make multi-content-script + Tailwind projects more efficient.

Thanks for the great work on WXT! @aklinker1 @PatrykKuniczak

Reproduction

wxt-css-dup-demo.zip

Steps to reproduce

Run bun install and then bun run zip

System Info
System:
    OS: Windows 11 10.0.26200
    CPU: (8) x64 Intel(R) Core(TM) i5-8250U CPU @ 1.60GHz
    Memory: 996.68 MB / 7.88 GB
  Binaries:
    Node: 22.15.0 - C:\Program Files\nodejs\node.EXE
    npm: 11.13.0 - C:\Users\oyzamil\AppData\Roaming\npm\npm.CMD
    pnpm: 10.28.2 - C:\Users\oyzamil\AppData\Local\pnpm\pnpm.CMD
    bun: 1.3.14 - C:\Users\oyzamil\.bun\bin\bun.EXE
  Browsers:
    Chrome: 151.0.7922.174
    Edge: Chromium (151.0.4129.107)
    Firefox: 153.0.3 - C:\Program Files\Mozilla Firefox\firefox.exe
    Internet Explorer: 11.0.26100.8115
Used Package Manager

bun

Validations

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the reproduction's src/entrypoints and src/styles/tailwind.css, then run bun install and bun run zip to observe the generated dist files. Trace how CSS imported by multiple entrypoints is emitted and determine what tests cover asset sharing. Done means shared CSS is emitted once and multiple entrypoints reference the same asset without the public/ workaround.

Written by the indexing model from the issue text.

Assessment

Tech stack
bun, tailwindcss, typescript
Domain
build-system, tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.