Skip to main content

What is preact/compat?

preact/compat is a compatibility layer that allows you to use React libraries and components with Preact. It provides a React-compatible API surface, making it possible to leverage the vast React ecosystem while benefiting from Preact’s small size and performance.
preact/compat adds approximately 2-3kb to your bundle size, keeping Preact significantly smaller than React while maintaining compatibility.

Key Features

React API Compatible

Full support for React’s component API, hooks, and utilities

Ecosystem Access

Use popular React libraries like React Router, Redux, and more

Minimal Overhead

Only 2-3kb additional size compared to core Preact

Automatic Aliasing

Simple bundler configuration to alias React to Preact

Supported React Features

The preact/compat package provides comprehensive React compatibility. Based on the implementation in compat/src/index.js:157, here’s what’s included:

Core Components & APIs

import {
  Component,
  PureComponent,
  createElement,
  createContext,
  createRef,
  Fragment,
  cloneElement,
  createFactory,
  createPortal,
  Children
} from 'preact/compat';

All React Hooks

import {
  useState,
  useEffect,
  useLayoutEffect,
  useContext,
  useReducer,
  useRef,
  useMemo,
  useCallback,
  useImperativeHandle,
  useDebugValue,
  useId,
  // React 18 hooks
  useTransition,
  useDeferredValue,
  useSyncExternalStore,
  useInsertionEffect
} from 'preact/compat';

Advanced Features

import {
  memo,
  forwardRef,
  lazy,
  Suspense,
  StrictMode,
  // Utilities
  isValidElement,
  isFragment,
  isMemo,
  findDOMNode,
  unmountComponentAtNode,
  // Rendering
  render,
  hydrate,
  flushSync,
  unstable_batchedUpdates
} from 'preact/compat';

Quick Setup

The easiest way to use preact/compat is to configure your bundler to alias React imports to Preact.

Webpack Configuration

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

Vite Configuration

vite.config.js
import { defineConfig } from 'vite';

export default defineConfig({
  resolve: {
    alias: {
      'react': 'preact/compat',
      'react-dom': 'preact/compat',
      'react/jsx-runtime': 'preact/jsx-runtime'
    }
  }
});

Rollup Configuration

rollup.config.js
import alias from '@rollup/plugin-alias';

export default {
  plugins: [
    alias({
      entries: [
        { find: 'react', replacement: 'preact/compat' },
        { find: 'react-dom', replacement: 'preact/compat' },
        { find: 'react/jsx-runtime', replacement: 'preact/jsx-runtime' }
      ]
    })
  ]
};

esbuild Configuration

build.js
import { build } from 'esbuild';

build({
  alias: {
    'react': 'preact/compat',
    'react-dom': 'preact/compat',
    'react/jsx-runtime': 'preact/jsx-runtime'
  }
});

React Version Compatibility

As seen in compat/src/index.js:43, preact/compat identifies itself as React 18.3.1 to ensure library compatibility.
Preact/compat is compatible with:
  • React 18.x features (concurrent features, automatic batching)
  • React 17.x features (JSX transform, event delegation)
  • React 16.x features (hooks, context, Suspense)
  • Most React ecosystem libraries

Import Paths

preact/compat supports multiple import paths for React compatibility:
// Main compat layer
import React from 'preact/compat';

// React DOM
import ReactDOM from 'preact/compat';

// React DOM Client (React 18)
import { createRoot, hydrateRoot } from 'preact/compat/client';

// React DOM Server
import { renderToString, renderToStaticMarkup } from 'preact/compat/server';

// JSX Runtime
import { jsx, jsxs } from 'preact/jsx-runtime';

// Scheduler
import * as Scheduler from 'preact/compat/scheduler';

// Test utilities
import { act } from 'preact/compat/test-utils';

Basic Usage Example

Once configured, you can use React code without any modifications:
App.jsx
import { useState, useEffect } from 'react';
import { createPortal } from 'react-dom';

function App() {
  const [count, setCount] = useState(0);
  
  useEffect(() => {
    document.title = `Count: ${count}`;
  }, [count]);
  
  return (
    <div>
      <h1>Hello from Preact!</h1>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>
        Increment
      </button>
    </div>
  );
}

export default App;
While preact/compat provides excellent React compatibility, some edge cases and library-specific behaviors may differ. See the Differences page for details.

Next Steps

Migration Guide

Step-by-step guide to migrating from React to Preact

Differences

Learn about key differences between React and Preact

Build docs developers (and LLMs) love