Skip to main content

Documentation Index

Fetch the complete documentation index at: https://extension.js.org/llms.txt

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

Ship smaller extension UI bundles while keeping a React-like developer experience and fast local iteration. Extension.js detects Preact from your dependencies. It configures JSX/TSX transforms, React compatibility aliases, and fast-refresh support automatically. Your React imports map to Preact through these aliases.

When Preact is a good fit

  • You want smaller UI bundle size for popup/sidebar/new tab surfaces.
  • You like React-style components but want a lighter runtime.
  • You are optimizing extension startup and UI responsiveness on lower-end devices.

Template examples

new-preact

Template screenshot Ship a lighter new-tab UI with Preact and React-compatible ergonomics.
npx extension@latest create my-extension --template=new-preact
Repository: extension-js/examples/new-preact

content-preact

Template screenshot Inject a compact Preact UI into page content using content scripts.
npx extension@latest create my-extension --template=content-preact
Repository: extension-js/examples/content-preact

Usage with an existing extension

Add Preact to an existing extension with the steps below.

Installation

Install the required dependencies: Preact ships its own TypeScript types, so you do not need a separate @types/preact package.

Configuration

Extension.js expects Preact files to use the following file extensions:
  • If you do not enable TypeScript: *.jsx
  • If you enable TypeScript: *.tsx

Development behavior

When Extension.js detects Preact, it configures:
  • Compatibility aliases (for example, react → preact/compat).
  • JSX handling tuned for Preact.
  • Refresh integration in development using @rspack/plugin-preact-refresh.
If your project lacks optional refresh dependencies, Extension.js installs them and asks for a restart.

Troubleshooting

  • Missing refresh dependency warning: Install @rspack/plugin-preact-refresh (and related packages if prompted).
  • Prompt to restart after install: Stop and rerun extension dev so the dev server can reload refresh wiring cleanly.
  • No Preact integration detected: Confirm preact appears in dependencies or devDependencies.

Usage examples

In a new tab extension

To use Preact in a new tab extension, include it as a <script> in your HTML file:
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>New Extension</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this extension.</noscript>
    <div id="root"></div>
  </body>
  <script src="./index.tsx"></script>
</html>
import {h, render} from 'preact'
import App from './App'

const root = document.getElementById('root')

render(<App />, root)
export default function App() {
  return <h1>Hello, Preact Extension!</h1>
}

In a content_script file

For content scripts, inject Preact into the page by creating an HTML element and rendering into it:
import {h, render} from 'preact'
import App from './App'
import './content.css'

const rootDiv = document.createElement('div')
rootDiv.id = 'extension-root'
document.body.appendChild(rootDiv)

render(<App />, rootDiv)

Next steps

Video walkthrough