A React compatibility layer for Preact
npm install preact-compat


> 🚨 Note: This module is for Preact 8.x and prior - Preact X includes compat by default.
> For Preact X, please uninstall preact-compat and replace your aliases with preact/compat.
This module is a compatibility layer that makes React-based modules work with [Preact], without any code changes.
It provides the same exports as react and react-dom, meaning you can use your build tool of choice to drop it in where React is being depended on.
> Interested? Here's an example project that uses preact-compat to work with an existing React library unmodified,
> achieving more than 95% reduction in size:
>
> preact-compat-example
---
> _... or really, "why [preact]"?_
React is a great library and a great concept, and has a large community of module authors creating high-quality components.
However, these components are tightly coupled to React through the use of generic package imports _([example][1])_.
[Preact] is a tiny _(3kb)_ implementation of the core value of React, and maintains a nearly identical API.
With a shim like this in place, it is possible to use other React-like libraries like Preact, without forking modules just to change their imports.
There are better long-term ways to solve the coupling issue, like using factory functions that accept named generic methods _(not just React DI)_,
as [suggested by Eric Elliot][2]. However, since the React community has already authored so many modules in a more explicitly coupled manner, it's worth
having a simple short-term solution for those who would like to liberate themselves from library lock-in.
---
preact-compat first through npm:``bash`
npm i --save preact-compat
NOTE: You need to have preact already installed, if you don't, install it like so:
`bash`
npm i --save preact
Using preact-compat with Webpack is easy.
All you have to do is add an alias for react and react-dom:
`jscreateClass
{
// ...
resolve: {
alias: {
'react': 'preact-compat',
'react-dom': 'preact-compat',
// Not necessary unless you consume a module using react-dom-factories
'create-react-class': 'preact-compat/lib/create-react-class',
// Not necessary unless you consume a module requiring `
'react-dom-factories': 'preact-compat/lib/react-dom-factories'
}
}
// ...
}
Using preact-compat with Browserify is as simple as installing and configuring aliasify.
First, install it: npm install --save-dev aliasify
... then in your package.json, configure aliasify to alias react and react-dom:
`jscreateClass
{
// ...
"aliasify": {
"aliases": {
"react": "preact-compat",
"react-dom": "preact-compat",
// Not necessary unless you consume a module using react-dom-factories
"create-react-class": "preact-compat/lib/create-react-class",
// Not necessary unless you consume a module requiring `
"react-dom-factories": "preact-compat/lib/react-dom-factories"
}
}
// ...
}
If you want to use a package that has a peer dependency of React and want it to point to preact-compat you’ll need to set Aliasify to be a global transform. This is not achievable by editing package.json, you’ll need to use the Browserify api and include the global option there:
``
b.transform(aliasify, {
global: true,
aliases: {
'react': 'preact-compat',
'react-dom': 'preact-compat'
}
});
Using preact-compat with Babel is easy.
Install the babel plugin for aliasing: npm install --save-dev babel-plugin-module-resolver
All you have to do is tell babel to process jsx with 'h' and add an alias for react and react-dom in your .babelrc:
`jscreateClass
{
// ...
"plugins": [
["module-resolver", {
"root": ["."],
"alias": {
"react": "preact-compat",
"react-dom": "preact-compat",
// Not necessary unless you consume a module using react-dom-factories
"create-react-class": "preact-compat/lib/create-react-class",
// Not necessary unless you consume a module requiring `
"react-dom-factories": "preact-compat/lib/react-dom-factories"
}
}]
],
"presets": [
"react"
]
// ...
}
Using preact-compat with Brunch requires no extra plugins.
In your brunch-config.js you can export an npm object to configure aliases:
`js`
// ...
exports.npm = {
enabled: true,
aliases: {
'react': 'preact-compat',
'react-dom': 'preact-compat'
}
}
// ...
With the above Webpack or Browserify aliases in place, existing React modules should work nicely:
`js
import React, { Component } from 'react';
import { render } from 'react-dom';
class Foo extends Component {
propTypes = {
a: React.PropTypes.string.isRequired
};
render() {
let { a, b, children } = this.props;
return
render((
), document.body);
`
---
preact-compat and its single dependency prop-types are both published as UMD modules as of preact-compat version 0.6. This means you can use them via a
`
You can see the above in action with this JSFiddle Example.
---
preact-compat adds support for validating PropTypes out of the box. This can be disabled the same way it is when using React, by defining a global process.env.NODE_ENV='production'. PropType errors should work the same as in React - the prop-types` module used here is published by the React team to replace PropTypes in React.

[MIT]
[preact]: https://github.com/developit/preact
[MIT]: http://choosealicense.com/licenses/mit
[1]: https://github.com/developit/preact-toolbox/blob/master/components/app/index.jsx#L1
[2]: https://gist.github.com/ericelliott/7e05747b891673eb704b