Preact
Preact is a lightweight, 3KB JavaScript library offering a React-compatible API for building user interfaces with a Virtual DOM. Currently in its stable v10.29.1 series, it maintains a rapid release cadence with frequent patch and minor updates, alongside public betas for upcoming major versions like 11.0.0-beta.1. Key differentiators include its extremely small footprint, which is beneficial for performance and bundle size, while largely replicating the modern React API including hooks, functional components, and class components. It offers extensive compatibility with the React ecosystem through its `preact/compat` alias, enabling many existing React libraries to function with minimal configuration. Preact features an optimized diffing algorithm, supports Server-Side Rendering (SSR), and includes developer tools and Hot Module Replacement (HMR) capabilities. It targets all modern browsers and maintains compatibility with IE11, providing a robust yet minimal alternative for web development.
Common errors
-
ReferenceError: h is not defined
cause JSX factory function (`h`) is not configured for your build process (Babel/TypeScript).fixConfigure your `tsconfig.json` (`jsxFactory: "h"`) or Babel config (`@babel/plugin-transform-react-jsx` with `pragma: 'h'`) to use Preact's `h` function for JSX, or add `/** @jsx h */` to your files. -
Cannot use import statement outside a module
cause Attempting to use ES module `import` syntax in a CommonJS context (e.g., an older Node.js environment or a non-bundled script without proper module configuration).fixEnsure your project's `package.json` has `"type": "module"` for Node.js environments, or use a bundler (Webpack, Rollup, Vite) that handles ES module compilation for browser code. -
React is not defined
cause A React-dependent library or component is being used in a Preact project without `preact/compat` being properly aliased to `react` and `react-dom` in the build configuration.fixInstall `preact/compat` and configure your bundler (e.g., Webpack, Rollup) to alias `react` and `react-dom` imports to `preact/compat`. -
Hooks can only be called inside the body of a function component.
cause A Preact hook (e.g., `useState`, `useEffect`) is being called outside of a functional component or a custom hook, violating the Rules of Hooks.fixEnsure all hook calls are made directly within the top level of a functional component or a custom hook, and not inside loops, conditions, or nested functions.
Warnings
- breaking For extensive compatibility with the broader React ecosystem (e.g., UI libraries, router components), installing `preact/compat` and aliasing `react` and `react-dom` to `preact/compat` in your bundler configuration (e.g., Webpack, Rollup) is critical. Failing to do so will result in runtime errors when using React-dependent libraries.
- gotcha Preact uses `h` (or `jsx` for modern JSX transform) as its JSX factory function. You must configure your build tools (Babel, TypeScript) to use this function when compiling JSX, otherwise you will encounter `ReferenceError: h is not defined` or similar errors.
- breaking Modern Preact versions, especially since v10, are primarily designed for ES Modules. Attempting to use `require('preact')` in a pure CommonJS environment without proper transpilation or module resolution can lead to errors like `Cannot use import statement outside a module` or unexpected behavior. Use a bundler or ensure your Node.js environment is configured for ESM.
- breaking Preact version 11 is in beta (`11.0.0-beta.1`) and is expected to introduce breaking changes. While `10.x` is stable, users should anticipate a migration effort when upgrading to the next major release.
Install
-
npm install preact -
yarn add preact -
pnpm add preact
Imports
- h, render
const { h, render } = require('preact');import { h, render } from 'preact'; - Component
import Component from 'preact/Component';
import { Component } from 'preact'; - useState, useEffect
import { useState } from 'react';import { useState, useEffect } from 'preact'; - Fragment
import { Fragment } from 'react';import { Fragment } from 'preact';
Quickstart
import { h, render } from 'preact';
// Configure JSX pragma for TypeScript or Babel via tsconfig.json or babel.config.js
// For TypeScript, add "jsxFactory": "h" to your compilerOptions.
// For Babel, configure @babel/plugin-transform-react-jsx with 'pragma': 'h'.
// Alternatively, add this pragma comment to the top of your JSX files:
/** @jsx h */
function Greeting({ name }) {
return (
<main>
<h1>Hello, {name}!</h1>
<p>This is a simple Preact application.</p>
<button onClick={() => alert(`Welcome, ${name}!`)}>Say Hello</button>
</main>
);
}
// Initial render to the document body
render(
<Greeting name="World" />,
document.body
);
// Update the component in-place after 3 seconds
setTimeout(() => {
render(
<Greeting name="Preact User" />,
document.body
);
}, 3000);