A React compatibility layer for Preact
npx @tessl/cli install tessl/npm-preact-compat@3.19.0Preact Compat is a React compatibility layer for Preact that provides the same exports as react and react-dom. It enables React-based modules to work with Preact without code changes, offering a complete React 15.1.0 API implementation optimized for Preact 8.x and prior versions.
npm install preact-compatpreact <10import React from 'preact-compat'; // Default export with all APIs
import { Component, render, createElement } from 'preact-compat'; // Named exportsFor CommonJS:
const React = require('preact-compat'); // Default export
const { Component, render, createElement } = require('preact-compat'); // Named exportsimport React, { Component } from 'preact-compat';
import { render } from 'preact-compat';
// Standard React component patterns work unchanged
class MyComponent extends Component {
state = { count: 0 };
increment = () => {
this.setState({ count: this.state.count + 1 });
};
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={this.increment}>Increment</button>
</div>
);
}
}
// Render to DOM (same as ReactDOM.render)
render(<MyComponent />, document.getElementById('root'));Preact Compat provides complete React API compatibility through several key components:
Primary React compatibility layer providing all essential React APIs including component system, virtual DOM, lifecycle methods, and rendering functions.
// Component System
class Component {
constructor(props, context);
setState(partialState, callback);
forceUpdate(callback);
render();
}
class PureComponent extends Component {}
// Element Creation
function createElement(type, props, ...children);
function cloneElement(element, props, ...children);
function createFactory(type);
function isValidElement(object);
function createPortal(vnode, container);
// Rendering
function render(vnode, parent, merge);
function hydrate(vnode, parent);
function findDOMNode(component);
function unmountComponentAtNode(container);Server-side rendering capabilities for generating HTML strings from components, supporting both static markup and hydration patterns.
function renderToString(vnode);
function renderToStaticMarkup(vnode);Comprehensive utilities for working with component children, providing safe iteration and manipulation methods.
const Children = {
map(children, fn, ctx);
forEach(children, fn, ctx);
count(children);
only(children);
toArray(children);
};Full React context system for sharing data between components without explicit prop passing.
function createContext(defaultValue);
interface Context<T> {
Provider: ComponentClass<{value: T, children?: ComponentChildren}>;
Consumer: ComponentClass<{children: (value: T) => ComponentChildren}>;
}Reference system for accessing DOM nodes and component instances directly.
function createRef();
interface RefObject<T> {
current: T | null;
}Support for legacy React patterns including createClass, DOM factories, and deprecated lifecycle methods for backward compatibility.
function createClass(spec);
const DOM = {
a: ElementFactory,
div: ElementFactory,
span: ElementFactory,
// ... all HTML elements
};Data update utilities for managing immutable state transformations safely and efficiently.
function update(object, spec);
interface UpdateSpec {
$set?: any;
$merge?: object;
$push?: Array<any>;
$unshift?: Array<any>;
$splice?: Array<Array<any>>;
$apply?: (value: any) => any;
}Animation and transition components for managing component lifecycle animations and CSS transitions.
class TransitionGroup extends Component {}
class CSSTransitionGroup extends Component {}Development and performance utilities including pure render mixins and performance measurement tools.
const PureRenderMixin = {
shouldComponentUpdate(nextProps, nextState);
};
const ReactPerf = {
start();
stop();
getLastMeasurements();
printInclusive();
printExclusive();
printWasted();
};Runtime type checking for React props, providing development-time validation and error reporting.
const PropTypes = {
// Primitive types
array: Validator;
bool: Validator;
func: Validator;
number: Validator;
object: Validator;
string: Validator;
symbol: Validator;
// Renderable types
node: Validator;
element: Validator;
// Collections
arrayOf(validator: Validator): Validator;
objectOf(validator: Validator): Validator;
// Specific values
oneOf(values: Array<any>): Validator;
oneOfType(validators: Array<Validator>): Validator;
// Complex objects
shape(spec: {[key: string]: Validator}): Validator;
exact(spec: {[key: string]: Validator}): Validator;
// Instances
instanceOf(constructor: Function): Validator;
// Any type (no validation)
any: Validator;
};
interface Validator {
isRequired: Validator;
(props: object, propName: string, componentName: string): Error | null;
}Usage:
import { PropTypes } from 'preact-compat';
class MyComponent extends Component {
static propTypes = {
name: PropTypes.string.isRequired,
age: PropTypes.number,
items: PropTypes.arrayOf(PropTypes.string),
config: PropTypes.shape({
debug: PropTypes.bool,
level: PropTypes.oneOf(['info', 'warn', 'error'])
})
};
render() {
return <div>Hello {this.props.name}</div>;
}
}Note: PropTypes validation only runs in development mode when process.env.NODE_ENV !== 'production'.
// Core types used throughout the API
type ComponentChildren = VNode<any> | object | string | number | boolean | null | undefined | Array<ComponentChildren>;
interface VNode<P = {}> {
type: ComponentType<P> | string;
props: P & { children?: ComponentChildren };
key: string | number | null;
ref: Ref<any> | null;
}
interface ComponentClass<P = {}> {
new (props: P, context?: any): Component<P, any>;
defaultProps?: Partial<P>;
contextTypes?: ValidationMap<any>;
childContextTypes?: ValidationMap<any>;
}
type ComponentType<P = {}> = ComponentClass<P> | ((props: P) => VNode<any>);
type Ref<T> = ((instance: T | null) => void) | RefObject<T>;