Preact vs. React
Tags: react, preact, webdev
Published: 2022-11-30 12:19:28

---
title: Preact vs. React
published: true
date: 2022-11-29 11:58:13 UTC
tags: react, preact, webdev
canonical_url: https://www.syncfusion.com/blogs/post/preact-vs-react.aspx
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sq8w7n7gr1s0wwdyxoe6.png
---
Front-end development has evolved tremendously over time. The constant need for large-scale web app development at a faster pace has led to the inception of many JavaScript frameworks.

Of the many, React has become one of the most popular with time. It has large community adoption, easy-to-use APIs, and is developer-friendly, especially for newbies. According to the StackOverflow[developer survey](https://insights.stackoverflow.com/survey/2021?ref=hackernoon.com#most-loved-dreaded-and-wanted-webframe-want "StackOverflow Developer survey"), it is the most popular framework for web app development.

Despite its popularity, React is still considered a slow framework because of its virtual DOM and the large file size of its core implementation, especially for large applications.

These drawbacks of React inspired a new framework named Preact, which is custom-tailored for certain types of applications as an alternative to React.

Preact is a 3KB but uses the same cutting-edge API and has the same support for ECMAScript. Its small size is due to the fact that it was created to function in a browser with the DOM, incorporating the virtual DOM like many frameworks. Additionally, it beats other JavaScript frameworks in terms of speed.

The popularity of Preact is reflected by the fact that it has 33,100 stars on GitHub and 1,799,020 weekly downloads on npm at the time of writing this article.

## Where does React excel?

React is the best choice when we have to build complex and highly scalable apps, especially SPAs. It has kept functional programming at the core, still infusing declarative and component-based styles, making it easier to distribute and develop applications in a large team.

The virtual DOM ensures high speed and minimum change re-renders of components when there is an update in the application.

React also provides effective server-side rendering, making it the ideal JavaScript framework for building apps that are simple to optimize for search engines.

Having extensive community support is the cherry on top.

## Where does Preact excel?

If performance, speed, and size of the application are important factors to you, Preact is the ideal option. It is mainly utilized to create advanced web apps. For instance, Uber moved to Preact in production to make its PWA lightweight and powerful.

Aside from this, Preact is a tiny library, and it is built on top of React, so there is not much additional learning required. It is simple to use and can be used with the current React package with some aliasing, i.e., using [preact/compat](https://www.npmjs.com/package/@preact/compat "@preact/compat NPM package"), due to its compatibility and likeness to React.

## Differences between Preact and React

Preact is not the reimplementation of React. Rather, it is a booster dose that aims to fix certain bottlenecks that hamper performance.

[preact/compat](https://www.npmjs.com/package/@preact/compat "@preact/compat NPM package") adds a thin layer on Preact in an effort to make Preact completely compatible with React.

### Primary Difference

#### Events

The primary difference between React and Preact is that React uses [synthetic events](https://reactjs.org/docs/events.html "SyntheticEvent in React"), which are wrapped around the actual events that React has added to make all the events work seamlessly across all browsers.

Preact has discarded these for their performance and code-size issues.

It registers event handlers using the browser’s standard **addEventListener.** Event nomenclature and behavior are identical to those of simple JavaScript/DOM.

With a few minor exceptions, the standard browser events function similarly to how they operate in React:

- Events don’t bubble up through components.
- Form inputs support native events. For example, we can use **oninput** rather than React’s **onChange.**
- Similarly, rather than using React’s **onDoubleClick** _ **,** _ the standard **onDblClick** should be used.
- In Preact, for **“input type = search,”** always use **onsearch** to listen to the events. In **IE11,** the clear icon doesn’t’ fire **_onInput_.**

Preact adheres more closely to the DOM specification, custom events are supported with case-sensitive names, and custom elements are handled similarly to standard elements (as they are in the DOM).

If you want to use the existing APIs of React in Preact, you can do so with the help of [preact/compat](https://www.npmjs.com/package/@preact/compat "@preact/compat NPM package").

#### Hooks

Hooks are not part of the core in Preact. They have been separated out to keep the main bundle small and thus need to be imported separately.

We can import Hooks either from preact/hooks or preact/compat.

```js
import { useState } from 'preact/hooks';

const App = () => {
  const [number, setNumber] = useState(0);
  const increment = () => setNumber(count + 1);
  // callback can be passed to the setter
  const decrement = () => setNumber((currentNumber) => currentNumber - 1);

  return (
    <div>
      <p>Number: {Number}</p>
      <button onClick={increment}>Increment</button>
      <button onClick={decrement}>Decrement</button>
    </div>
  )
};

```

#### Rendering

Preact is one of the quickest virtual DOM libraries available thanks to its small size as well as its simple and reliable implementation of the diff.

### Secondary differences

#### Native support for ES modules

Preact was one of the earliest frameworks to support ES modules because it was designed with the module system in mind. We can load ES modules directly in browsers using the import keyword without going via a bundler first.

```js
<script type="module">
  import { h, Component, render } from 'https://unpkg.com/preact?module';
  import htm from 'https://unpkg.com/htm?module';

  // initialize htm with Preact
  const html = htm.bind(h);

  function App (props) {
    return html`<h1>Hello ${props.name}!</h1>`;
  }
  
  // render App with bypassing prop name=”world”
  render(html`<${App} name="World" />`, document.body);
</script>

```

#### render() method has arguments

Preact has conveniently given **_this.props_** and **_this.state_** to the class component’s **render()** method.

_In React and Preact, using_ [_preact/compat_](https://www.npmjs.com/package/@preact/compat "@preact/compat NPM package")_._

```js
class App extends Component {
  state = { count: 1 };

  render() {
    return <div>Name: {this.props.name}, Count: {this.state.count}</div>;
  }
}

```

_In Preact without_ [_preact/compat_](https://www.npmjs.com/package/@preact/compat "@preact/compat NPM package")_._

```js
class App extends Component {
  state = { count: 1 };

  render({ name }, { count }) {
    return <div>Name: {name}, Count: {count}</div>;
  }
}

```
#### Native HTML attribute/property names

Preact strives to resemble the DOM specification that is accepted by all significant browsers. Preact internally determines whether each prop should be set as an HTML attribute or a property when applying props to an element. This not only allows complex properties to be put on custom elements, but also allows attribute names like the class in JSX.

```js
//Preact
<div class="foo" />

//React
<div className="foo" />

```

#### SVG inside JSX

SVG are the JavaScript of the HTML tags when it comes to properties and attributes.

A few properties and their attributes are **camelCased** such as the **clipPathUnits** on a **clipPath** element. Others are kebab-cased, such as clip-path on many SVG elements), while those inherited from the DOM, such as **oninput,** are all lowercase.

Preact supports the SVG natively. You can copy any SVG snippet and have it go as expected. This makes developers’ life easy, as they can directly pick things from mockups rather than converting attributes or properties to camel case.  
**_SVG in React_**

```js
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
  <circle fill="none" strokeWidth="2" strokeLinejoin="round" cx="24" cy="24" r="20" />
</svg>
```

**_SVG in Preact_**

```js
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
  <circle fill="none" stroke-width="2" stroke-linejoin="round" cx="24" cy="24" r="20" />
</svg>

```

#### Form events

We no longer have to use the **onChange** event on form elements. You can use the native input, and it will work the same.

**_React_**

```js
<input onChange={e => console.log(e.target.value)} />
```

**_Preact_**

```js
<input onInput={e => console.log(e.target.value)} />
```

The majority of **onChange** events are internally transformed to **onInput** when using **preact/compat** to mimic React’s behavior. This is one of the techniques to make sure the React ecosystem is as compatible as possible.

#### JSX constructor

Simply put, JSX is the JavaScript syntactic extension that transforms JSX into nested functional calls.

Preact promotes the original universal community standard that the [hyperscript](https://github.com/dominictarr/hyperscript "GitHub example for Hyperscript") project popularized in JavaScript and makes use of nested function calls to construct tree structures.

**_JSX_**

```js
<a href=”/”>
  <span>Home</span>
</a>
```

**_React output_**

```js
React.createElement(
  'a',
  { href:'/' },
  React.createElement('span', null, 'Home')
);
```

**_Preact output_**

```js
h(
  'a',
  { href:'/' },
  h('span', null, 'Home')
);

```

#### Children API

In React, for interacting with the value of **props.children** , there is a specific collection of methods called the Children API. Preact normally does not need this, so they advise using the built-in array methods.

In Preact, props.children can be a virtual DOM node, a value that is empty, such as null, or an array of virtual DOM nodes. Since children can be used or returned in their current state, the first two scenarios are the most straightforward and frequent.

**_React_**

```js
function App(props) {
  return <Element content={Children.only(props.children)} />
}

```

**_Preact_**

```js
// Preact: use props.children directly:
function App(props) {
  return <Element content={props.children} />
}

```

If you want to iterate over the children received, you can use the **toChildArray()** method. It accepts any **props.children** value and return a flattened and normalized array of virtual DOM nodes.

**React**

```js
function App(props) {
  const cols = Children.count(props.children);
  return <div data-columns={cols}>{props.children}</div>
}
```

**Preact**

```js
function App(props) {
  const cols = toChildArray(props.children).length;
  return <div data-columns={cols}>{props.children}</div>
}
```
## Integrating an existing React app with Preact

There are also some specialized components in Preact designed for special cases.

In order to use them, we have to set up the **preact/compat**.

The simplest way is to use the alias and partly migrate the features of React with Preact while still continuing to use the existing libraries of React.

To set any package in the webpack as the alias, update or add the **resolve.alias** section in your webpack config.

```js
"resolve": { 
    "alias": { 
      "react": "preact/compat",
      "react-dom/test-utils": "preact/test-utils",
      // should always be below the test-utils
      "react-dom": "preact/compat",     
      "react/jsx-runtime": "preact/jsx-runtime"
    },
  }
```

Our setup is done, and now we can use these extra features of Preact in the existing application:  
[PureComponent](https://preactjs.com/guide/v10/switching-to-preact#purecomponent "PureComponent in Preact"): Component rerenders or updates only when the props or state have changed.

```js
import { render } from 'preact';
import { PureComponent } from 'preact/compat';

class App extends PureComponent {
  render(props) {
    console.log("called")
    return <div />
  }
};

const dom = document.getElementById('root');
render(<App name="syncfusion" />, dom);
// Logs: "called"

// second time, doesn't log anything
render(<App name="syncfusion" />, dom);
```

[memo](https://preactjs.com/guide/v10/switching-to-preact#memo "memo in Preact"): Similar to PureComponent, but memo lets you use a custom comparison function for deciding the updates conditionally.

```js
import { memo } from 'preact/compat';

function App(props) {
  return <div>Hello {props.name}</div>
}

// normal memoization
const Memoed = memo(App);

// memoizing with custom comparison function
const Memoed2 = memo(App, (prevProps, nextProps) => {
  // re-render when `name' changes
  return prevProps.name === nextProps.name;
});
```

[forwardRef](https://preactjs.com/guide/v10/switching-to-preact#forwardRef "Switching to Preact (from React)"): Passes the reference to the child components.

```js
import { createRef, render } from 'preact';
import { forwardRef } from 'preact/compat';

const App = forwardRef((props, ref) => {
  return <div ref={ref}>Hello world</div>;
})

// `ref` will reference to the div child rather than the `App`
const ref = createRef();
render(<App ref={ref} />, dom);
```

[Portals](https://preactjs.com/guide/v10/switching-to-preact#portals "Portals in Preact"): Allows us to render components in different DOM elements.

```js
<html>
  <body>
    <!-- app will render here -->
    <div id="app"></div>
    <!-- modal will render here -->
    <div id="modals"></div>
  </body>
</html>

import { createPortal } from 'preact/compat';
import MyModal from './MyModal';

function App() {
  const container = document.getElementById('modals');
  return (
    <div>
      I'm app
      {/*modal will render in its container outside the app*/}
      {createPortal(<MyModal />, container)}
    </div>
  )
}
```

## Creating a fresh Preact app

Preact also has a built-in CLI and we can use it to scaffold a new project, similar to the create-react-app.

**Install CLI**

```js
npm install -g preact-cli
```

**Create new project**

```js
preact create default my-project
```

Here, the default keyword refers to the one you would like to use for your project.

Popular available choices are:

- **Simple:** Blank setup with Vanilla JS.
- **TypeScript:** Setup using TypeScript.
- **Material:** Setup using Material design.
- **Netlify:** Setup using Netlify CMS template.
- **Widget:** To be embeddable as a widget in another web app.

## Advantages of choosing Preact over React

- **Tiny and speedy** : Preact is the best framework for creating high-performing, lightweight apps because it is only 3.5 KB in size and renders swiftly using the optimized diff algorithm.
- **Integrable:** It supports the same ECMAScript and is extremely compatible with the React APIs, making it effective enough to integrate into an active React project for improved performance.
- **Easy to learn** : The learning curve is easy because it is well-documented, and the APIs are similar to React.
- **Built-in CLI** : Preact features a strong CLI that enables developers to create a PWA in a matter of seconds without having to set up Babel or WebPack.

## Conclusion

I hope you now have a clear idea of differences between Preact and React. React is a popular JavaScript library among web developers, while Preact is an enhanced version of React that makes applications lighter and faster.

The [Syncfusion Essential Studio for React](https://www.syncfusion.com/react-ui-components "Syncfusion React UI Components Library") suite offers over 70 high-performance, lightweight, modular, and responsive UI components in a single package. It’s the only suite you’ll ever need to construct a complete app.

If you have questions, contact us through our [support forum](https://www.syncfusion.com/forums "Syncfusion Support Forum"), [support portal](https://support.syncfusion.com/ "Syncfusion Support Portal"), or [feedback portal](https://www.syncfusion.com/feedback "Syncfusion Feedback Portal"). We are always happy to assist you!

## Related blogs

- [7 VS Code Extensions for React Developers](https://www.syncfusion.com/blogs/post/7-vs-code-extensions-for-react-developers.aspx "Blog: 7 VS Code Extensions for React Developers")
- [Create a Simple Dashboard for Data Analysis in React](https://www.syncfusion.com/blogs/post/create-a-simple-dashboard-for-data-analysis-in-react.aspx "Blog: Create a Simple Dashboard for Data Analysis in React")
- [React Router vs. React Router DOM](https://www.syncfusion.com/blogs/post/react-router-vs-react-router-dom.aspx "Blog: React Router vs. React Router DOM")
- [What is Memoization in React?](https://www.syncfusion.com/blogs/post/what-is-memoization-in-react.aspx "Blog: What is Memoization in React?")