Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/thePrnvBot/dispel-web-stylist/llms.txt

Use this file to discover all available pages before exploring further.

WXT handles all bundling, tree-shaking, and manifest generation for Dispel. You never need to configure Rollup or Webpack directly — a single command produces a fully optimised, production-ready extension in .output/. From there, a second command packages the output into a zip file suitable for upload to the Chrome Web Store or Firefox Add-ons (AMO). This page walks through the full release pipeline from a clean checkout to a store-ready artifact.

Production Build Commands

Production builds strip development tooling, apply minification, and write static assets with content hashes. Run the build for whichever browser target you are releasing:
bun run build
WXT compiles each entrypoint (background service worker, content script, side panel, options page, and welcome page) and writes the output to:
  • Chrome.output/chrome-mv3/
  • Firefox.output/firefox-mv3/
After running bun run build, load .output/chrome-mv3/ as an unpacked extension (via chrome://extensionsLoad unpacked) for final pre-submission testing. This ensures you are validating the exact artifact that will be submitted to the store, not the dev build.

Creating Store Packages

Once the production build passes your testing, generate the zip archives for store submission:
bun run zip
WXT runs a production build (if the output is stale) and then zips the output directory. The resulting files are placed alongside the unpacked output:
.output/
  chrome-mv3.zip      # ready for Chrome Web Store upload
  firefox-mv3.zip     # ready for Firefox AMO upload
Both zip commands run wxt zip (with -b firefox for the Firefox variant), which is equivalent to wxt build followed by a deterministic archive of the output directory.

Pre-Submission Checks

Run these two commands before building for store submission to catch lint violations and type errors early:
bun run check    # Biome lint + format — no warnings allowed
bun run compile  # tsc --noEmit — strict TypeScript type check

bun run check

Runs ultracite check, which executes the Biome linter and formatter across the entire src/ directory. The project extends ultracite/biome/core, ultracite/biome/react, and ultracite/biome/vitest rule sets. If any issues are found, run bun run fix to auto-fix what Biome can resolve automatically.

bun run compile

Runs tsc --noEmit against tsconfig.json, which enforces strict: true, noUnusedLocals, noUnusedParameters, noUncheckedIndexedAccess, and noImplicitReturns. No output is emitted — this is a type-check-only pass.
Do not submit to the Chrome Web Store or Firefox AMO without a clean bun run check and bun run compile. Store reviewers run automated checks, and a type or lint error that slips through can cause a submission rejection or delayed review.

Build Output Structure

After running all build and zip commands, .output/ contains the following:
.output/
  chrome-mv3/           # Unpacked Chrome extension (MV3)
  chrome-mv3.zip        # Packaged for Chrome Web Store submission
  firefox-mv3/          # Unpacked Firefox extension (MV3)
  firefox-mv3.zip       # Packaged for Firefox AMO submission
  chrome-mv3-dev/       # Dev build (present when dev server has run)
  firefox-mv3-dev/      # Dev build (present when dev server has run)
The unpacked directories are useful for inspecting the compiled output, checking that assets were bundled correctly, and loading the extension manually for a final smoke test. The zip files are the artifacts you upload directly to each store’s developer dashboard.

WXT Configuration

All build behaviour is controlled by wxt.config.ts in the project root. The key options are:
modules: ['@wxt-dev/module-react']
Loads the WXT React module, which configures Vite’s React plugin and enables fast refresh / HMR for all React entrypoints during bun run dev.
srcDir: 'src'
Tells WXT to look for entrypoints and assets under src/ rather than the project root. The @/* TypeScript path alias resolves to src/*.
vite: (env) => ({
  resolve: {
    alias: {
      '@/platform/sidepanel':
        env.browser === 'firefox'
          ? '/src/platform/sidepanel.firefox'
          : '/src/platform/sidepanel.chrome',
    },
  },
})
Resolves the @/platform/sidepanel import to the correct browser-specific implementation at build time. The Chrome build uses the chrome.sidePanel API; the Firefox build uses a popup-based fallback. No runtime branching is needed in the consuming code.
manifest: () => ({
  name: 'Dispel',
  description: 'AI-Native Web Styling — Generate CSS with Natural Language',
  version: '1.0.2',
  permissions: ['storage', 'tabs'],
  host_permissions: ['http://*/*', 'https://*/*'],
  commands: {
    'toggle-sidebar': {
      suggested_key: { default: 'Ctrl+Shift+Y' },
      description: 'Toggle sidebar',
    },
  },
  browser_specific_settings: {
    gecko: {
      id: 'dispel@usedispel.dev',
      strict_min_version: '142.0',
    },
  },
})
The manifest factory receives no arguments (WXT injects the browser target elsewhere) and returns an object that WXT merges with its auto-generated fields. storage and tabs are the only declared permissions; broad host_permissions are required so the content script can inject into any page.
The version field in manifest() inside wxt.config.ts is the canonical version source for the extension. Update it here before running bun run build and bun run zip for a new release — there is no separate version field to keep in sync.

Build docs developers (and LLMs) love