DEV Community

Cover image for 👑⚙️ Smaller, Faster Websites with Preact and Expo
Evan Bacon
Evan Bacon

Posted on • Edited on

👑⚙️ Smaller, Faster Websites with Preact and Expo

React Native for web is awesome because not only can you reuse all of the dope native Expo packages like expo-camera and react-native-gesture-handler, but you can also use any of the neat things coming out of the React/web community to create blazingly fast websites.

A great example of this is the library Preact by Jason Miller! Preact is a light-weight (~3kb) alternative to React.
When building a web-only project setup is simple, you can just replace React with Preact and start coding right away, but React Native for web is a little bit more complicated.
Because RNWeb uses many different React features we have to really push Preact to its limits to get it working with Expo for web. Luckily it's still pretty simple to setup.

Before Preact

Before we cover the how, let's talk about why you might want to use Preact. If you create a standard Expo web project (at the time of writing this article), the bundle size will look something like the report below.

❌ 60.75 KB Gzipped

expo web bundle without preact

After Preact

If you configure your project to use Preact instead of React, the bundle will reduce drastically! This means your website will load faster and work much better for users with poor internet connections or low-end devices.

✅ 27.98 KB Gzipped

expo web bundle with preact

⚽️ Getting Started

To use Preact with React Native for web, you'll need to install the packages and alias them to React.

💡 The most updated info is in the Expo docs: Using Preact

  • Install Preact (requires Preact 10+):
    • yarn add preact-responder-event-plugin preact
    • or npm install --save preact-responder-event-plugin preact
  • Create a custom Webpack config for the Expo CLI to use:
    • Run expo customize:web
    • Select webpack.config.js
  • Modify the Webpack config to use Preact instead of React:
  const createExpoWebpackConfigAsync = require('@expo/webpack-config');
  const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');

  module.exports = async (env, argv) => {
    const config = await createExpoWebpackConfigAsync(env, argv);

    // Add more aliases
    config.resolve.alias = {
      ...config.resolve.alias,
      // Use Preact aliases
      react$: 'preact/compat',
      'react-dom$': 'preact/compat',
      // Fix the responder system which react-native-web depends on
      'react-dom/unstable-native-dependencies$': 'preact-responder-event-plugin',
    };

    // Optionally you can enable the bundle size report. 
    // It's best to do this only with production builds.
    if (env.mode === 'production') {
      config.plugins.push(new BundleAnalyzerPlugin({
        path: 'web-report',
      }));
    }
    return config;
  };
Enter fullscreen mode Exit fullscreen mode
  • Running expo build:web will now use Preact instead of React. This means you'll now have a significantly smaller bundle! 🚀

Drawbacks

To achieve a smaller bundle size Preact has to cut a few features. For instance they don't support synthetic events. Another major drawback is that usage with React Native isn't very clear, if you're building a universal app you may want to consider using the same version of React across web and mobile. For more information on issues using Preact with React Native for web, please refer to this issue react-native-web#1219 (link courtesy of Max Thirouin)

👋 That's all

Thanks for reading, that's all I've got for you today. Let me know if you enjoyed this article, and reach out if you have any more questions!

Top comments (4)

Collapse
 
barzi92367868 profile image
Barzi

Didn't know about preact! Thank you!

Collapse
 
evanbacon profile image
Evan Bacon

It's a really awesome package, I'm super excited to have it as part of the Expo web ecosystem now!

Collapse
 
natetronn profile image
Nathan Doyle

Noob question:

Why is Preact only mentioned under the umbrella, if you will, of RNWeb, but not standard React Native (mobile)?

Collapse
 
kayis profile image
K

As far as I know, Preact is so small because it tries to re-use many of the things a browser already brings, so it's not as portable as React.