What is Preact and when should you consider using it?

Of course, React is not the only framework to use! You can’t forget about Angular, and Vue, which are still popular, but also not perfect. Each of them has some drawbacks. Getting back to React, how about having all the benefits from it, in a smaller, lighter package? Are you curious? Let’s take a look at Preact!

Imagine that you can use your React.js skills to build your next SPA with a tool that weighs 3kB? Yeah, that’s right, about 3kB - for comparison plain React is about 30kB… If you're shocked, read on to learn more.

What is Preact?

Preact is a JavaScript library, claiming to be a “fast 3kB alternative to React with the same modern API”. It is one, implementing the fastest virtual DOM, compared to other frameworks on the market. Also, it is one of the smallest libraries in size!

Here are some main advantages shipped with PreactJS out of the box:

  • No build tools required for a simple app - just run it in the browser!
  • Dedicated CLI
  • Usage of well known React API
  • Ability to integrate with an existing React project

With such good sides, we can’t forget about some differences from ReactJS:

  • ‘this.props’ and ‘this.state’ are passed directly to render() method - which can be later destructed
  • There is no need to use ‘className’, you can just use ‘class’ to pass CSS classes in
  • No support for PropType validation in the base core - if you want to use it, you need to import it from ‘preact/compat’ module
  • Preact doesn’t support Synthetic Events - Preact is based on the browser's ‘addEventListener’ 

Preact goals stated in the documentation:

  1. Performance: Render quickly & efficiently.
  2. Size: Small size, lightweight (approximately 3.5kb).
  3. Efficiency: Effective memory usage (avoiding GC thrash).
  4. Understandability: Understanding the codebase should take no more than a few hours.
  5. Compatibility: Preact aims to be largely compatible with the React API.

How to run Preact directly in the browser?

Let’s try zero build approach:

<!DOCTYPE html>
<html>
<body>
<script type="module">
import { h, Component, render } from 'https://unpkg.com/preact?module';

// Create your app
// 'h' is equivalent to React.CreateElement
const app = h('h1', null, 'Hello Merixstudio!');

render(app, document.body);
</script>
</body>
</html>

That’s all you need to write to create your first Preact app! Isn't that great?  But if you don’t like such syntax, and you really want to bypass the build process, you can still use a JSX alternative called HTM. Just take a quick look at this code sample:

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

// Initialize htm to work with Preact
const html = htm.bind(h);

// Creating components with JSX like syntax
const app = html`<h1>Hello Merixstudio!</h1>`;

render(app, document.body);
</script>

There are two extra lines of codes in your script tag, that changed the last example to be more readable, and developer-friendly. Awesome, isn’t it?

CLI for the rescue!

Preact CLI is a command-line tool that can be run locally in the terminal on your computer.  It will help you to initialize, develop, and maintain Preact applications. First, just install it using NPM:

$ npm install -g preact-cli

Create your project with this simple command:

$ preact create default my-project

The “default”  keyword stands for a template which you would like to use while generating a project. Preact CLI gives you a choice, for example, you can use:

  • material - Material template using preact-material-components
  • simple - The simplest possible setup in a single file
  • typescript - Default template implemented in TypeScript
  • And more…

You can, later on, build your app for production just by running:

$ npm run build

By default Preact build will enable pre-rendering on your site, it means that the home route is converted into static index.html file - this ensures that users will see content before any JavaScript is executed. All users with slow devices or the one with a poor internet connection will load your app much faster! Great, isn't it?

React API build in Preact

Preact uses the same modern API as React, lifecycle methods look the same, and you can use the same methodologies to build your app. If you mastered building elements in React, you’ll be ready to try Preact right away! If you don't believe me, just analyze this code below:

import { h } from 'preact';
import { useState } from 'preact/hooks';

const Counter = () => {
const [count, setCount] = useState(0);
const increment = () => setCount(count + 1);
const decrement = () => setCount(count - 1);

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

If you are perceptive you noticed that this looks exactly the same compared to React functional code using hooks - but, there is one small difference in the imports section. We are importing ‘hooks’ support from another Preact module. This makes our application smaller when we don’t want to use hooks - importing it will raise our package weight by 1-2 kB.

Integration with existing project

As a frontend developer, you often use some third-party libraries with your React.js project. Many of them are strictly referring to ‘react’ or ‘react-dom’ objects, which isn’t available out of the box in the new Preact project. All you need to do is to point all ‘react’ and ‘react-dom’ imports to the Preact library. You can do that by adding the following configuration to your webpack.config.js (or any other bundler):

{
"resolve": {
"alias": {
"react": "preact/compat",
"react-dom": "preact/compat"
}
}
}

Now all React packages imported by NPM or Yarn will work with your Preact project! Easy, right? But it's not everything, there are a lot of plugins developed especially for Preact!

Other differences between React and Preact

Use class instead of className

As I mentioned, you can stop using React className syntax, and start writing using plain class attribute to add some CSS classes to you HTML elements:

# React code sample
<span className="text--orange">Do you like React?</span>

# Preact code sample
<span class="text--orange">Or maybe Preact?</span>

If you are used to writing className, you can use it, it will still work!

Use props and state as arguments in the render() method

When you want to refer to props or state in React, inside your view you need to use long and really illegible syntax. In Preact, we can make the code look cleaner and more readable for developers, by removing awkward this keyword. If you even want to go a step further, to fix your code,  you can simplify these objects using the ES6 destructuring assignment. We have such an opportunity because Preact passes props and state objects as arguments into the render method by default. Let's take a look at this example:

// React code
class MyReactComponent extends Component {
constructor (props) {
super(props);
this.state = {
messageToDisplay: 'Hello React!'
};
}
render() {
return (
<div>
<p>{this.props.text}</p>
<p>{this.state.messageToDisplay}</p>
</div>
)
}
}

// Preact code without destruction
class MyPreactComponent extends Component {
constructor (props) {
super(props);
this.state = {
messageToDisplay: 'Hello Preact!'
};
}
render(props, state) {
return (
<div>
<p>{props.text}</p>
<p>{state.messageToDisplay}</p>
</div>
)
}
}



// Preact code with ES6 destruction in render()
class MyPreactComponent extends Component {
constructor (props) {
super(props);
this.state = {
messageToDisplay: 'Hello Preact!'
};
}
render({text}, {messageToDisplay}) {
return (
<div>
<p>{text}</p>
<p>{messageToDisplay}</p>
</div>
)
}
}


Should you consider Preact in your next project?

The answer to this question really depends on your case scenario. Would you build a big fintech application or maybe a small widget that needs a really short loading time, or maybe you're targeting users with a slow internet connection?  A big advantage of switching to Preact from React is that you'll make your bundle-size smaller, and your app will load faster - this can be a key requirement for some projects.  But on the other hand, while choosing Preact you can lose some React features.

In my opinion, React will be perfect to build heavy and complicated stuff. There’s no point in building an app with Preact which requires installing additional 5-10 NPM packages to get all functionality shipped with React, out of the box. Preact should be chosen for projects like small web widgets, landing pages, or a PWA which will work all around the world, regardless of poor internet connection or used device.

If you want to know more about Preact I encourage you to visit its official site. Want to learn more things connected with React? Read about our Test-driven development approach! And if you would like to raise your skills within a great JavaScript team - check our job offers

Navigate the changing IT landscape

Some highlighted content that we want to draw attention to to link to our other resources. It usually contains a link .