Skip to content

Preact Compatibility Layer — Using React Libraries with preact/compat

DodaTech Updated 2026-06-28 4 min read

Learn how to use preact/compat to run React libraries and third-party components in Preact applications seamlessly with the compatibility layer.

In this lesson, you'll understand what preact/compat provides, how to configure aliasing, and which React libraries work with Preact.

What You'll Learn

How to install and configure preact/compat, alias React imports, handle common compatibility issues, and use popular React libraries like react-router-dom and react-hook-form.

Why It Matters

The React ecosystem has thousands of libraries. preact/compat lets you use them in Preact projects while still saving 90% of bundle size compared to React.

Real-World Use

Doda Browser's extension uses preact/compat to integrate react-color for a color picker and react-beautiful-dnd for drag-and-drop bookmark reordering, all within a 10kB total bundle.

flowchart LR
    A[React Library] -->|imports 'react'| B[preact/compat]
    B -->|Aliased| C[Preact Core]
    C -->|3kB| D[Application]
    style B fill:#673ab8,color:#fff
    style D fill:#4a148c,color:#fff

Installing preact/compat

npm install preact

preact/compat is included with the main Preact package. No separate installation needed.

Configuring Aliases

To use React libraries, configure your bundler to alias react and react-dom to preact/compat:

Vite Configuration

// vite.config.js
import { defineConfig } from 'vite';
import preact from '@preact/preset-vite';

export default defineConfig({
  plugins: [preact()],
  resolve: {
    alias: {
      react: 'preact/compat',
      'react-dom': 'preact/compat'
    }
  }
});

The @preact/preset-vite plugin handles aliasing automatically when added.

Webpack Configuration

// webpack.config.js
module.exports = {
  resolve: {
    alias: {
      react: 'preact/compat',
      'react-dom': 'preact/compat'
    }
  }
};

Using React Libraries

Once aliased, import React libraries normally:

// react-router-dom works through preact/compat
import { BrowserRouter, Routes, Route, Link } from 'react-router-dom';

function App() {
  return (
    <BrowserRouter>
      <nav>
        <Link to="/">Home</Link>
        <Link to="/about">About</Link>
      </nav>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
      </Routes>
    </BrowserRouter>
  );
}

Output: The router works exactly as in React. All react-router-dom APIs function through the compat layer without changes.

What preact/compat Provides

preact/compat adapts Preact to match the React API:

// React-style imports that work via preact/compat
import React, {
  useState,
  useEffect,
  createContext,
  createRef,
  forwardRef,
  lazy,
  Suspense,
  memo,
  Fragment,
  createElement,
  Children,
  PureComponent,
  Component
} from 'react';

// All these map to Preact equivalents through the compat layer

The compat layer implements: ReactDOM.render, ReactDOM.createRoot, createRef, forwardRef, memo, lazy, Suspense, PureComponent, Children, createElement, and synthetic events.

Testing Compatibility

Verify compat is working:

import React from 'react';

console.log('Using:', React.version);
// Output: "preact/compat" with a version string

// Create a React-style element
const element = React.createElement('h1', null, 'Hello from compat');
console.log(element.type); // Output: 'h1'

Output: React imports resolve to preact/compat. The createElement function creates Preact VNodes that are compatible with React's expected VNode structure.

Common Mistakes

  1. Forgetting aliases in Vite plugin: Without the @preact/preset-vite plugin or manual aliases, React libraries import real React, increasing bundle to 45kB.
  2. Using ReactDOM.createRoot without checking compat: preact/compat implements createRoot, but it wraps Preact's render function. Behavior may differ slightly.
  3. Relying on synthetic event pooling: React 17+ removed event pooling, so this isn't an issue. But React 16 code that calls event.persist() won't work because Preact doesn't pool events.
  4. Using useInsertionEffect: preact/compat doesn't support useInsertionEffect. Use useEffect or useLayoutEffect instead.
  5. Not testing edge cases: preact/compat covers most React APIs but has edge cases. Test third-party libraries thoroughly before relying on them in production.

Practice Questions

  1. How do you configure Vite to use preact/compat? Answer: Use @preact/preset-vite plugin or manually add resolve.alias mapping react and react-dom to preact/compat.

  2. What does preact/compat provide? Answer: It adapts Preact to match the React API, including createElement, Component, PureComponent, memo, forwardRef, lazy, Suspense, Fragment, and synthetic events.

  3. What is NOT supported by preact/compat? Answer: useInsertionEffect, useSyncExternalStore (partial), and some React 18 concurrent features.

  4. Can you use react-router-dom with Preact? Answer: Yes, through preact/compat. Configure aliases and import normally from react-router-dom.

Challenge

Create a Preact project that uses react-hook-form and react-router-dom through preact/compat. Build a multi-step form with validation and navigation between steps.

Mini Project

Build a dashboard that uses react-chartjs-2 (Chart.js wrapper) through preact/compat. Display a line chart and a bar chart. Verify that the bundle size stays under 20kB.

FAQ

Does preact/compat cover all of React's API?

: It covers the most commonly used APIs: components, hooks, context, refs, portals, memo, lazy, Suspense. Some edge-case APIs like useInsertionEffect and concurrent mode features are not implemented.

Will every React library work with preact/compat?

: Most will, but some libraries that depend on React internals (like __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED) may not work.

Does preact/compat increase bundle size?

: Yes, slightly. Preact core is 3kB, and preact/compat adds approximately 2kB. Total is 5kB compared to React's 45kB.

Is preact/compat production-ready?

: Yes. preact/compat is used in production by Lyft, Nintendo, and DodaTech products.

What's Next

Learn about Preact Routing (preact-router) to handle client-side navigation in Preact applications.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro