DEV Community

Evan Bacon for Expo

Posted on • Updated on

Fast Refresh with Expo Web! 🏃🏻‍♂️🔄

Alt Text

If you've used Expo on iOS or Android recently you've probably used Fast Refresh (by Dan Abramov) to achieve stateful hot reloading during development. But how do you use Fast Refresh with Expo for web.?.. (Pretty easily).

On web this will update the DOM without reloading the page, this means the state will remain the same across updates. To fully update you can simply reload the window with ⌘ + R.

🤔 How to use

Currently there's no official Fast Refresh Webpack plugin, but you can get started today using a great community plugin by Michael Mok!

  • Bootstrap a new universal React Native project:
    • Expo: expo init then select any project
    • Other: npx create-react-native-app
  • Install the community Fast Refresh package:
    • yarn add -D @pmmmwh/react-refresh-webpack-plugin webpack-hot-middleware
  • Eject the Webpack config:
    • expo customize:web
  • In your newly created webpack.config.js:
const createExpoWebpackConfigAsync = require("@expo/webpack-config");
const ReactRefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin");

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

  // Use the React refresh plugin in development mode
  if (env.mode === "development") {
    config.plugins.push(
      new ReactRefreshWebpackPlugin({ disableRefreshCheck: true })
    );
  }

  return config;
};
Enter fullscreen mode Exit fullscreen mode
  • Now in your babel.config.js:
module.exports = function (api) {
  // This caches the Babel config by environment.
  api.cache.using(() => process.env.NODE_ENV);

  return {
    presets: ["babel-preset-expo"],
  };
};
Enter fullscreen mode Exit fullscreen mode
  • Now run expo start:web to use it!

💡 BTW

When the official React fast refresh has been released, we will work on unifying it with native to create a universal solution. Until then this is a pretty nifty little feature! :]

Why share now then?

I got the idea for this tutorial from my friend Tim Neutkens of Next.js. I highly recommend using Next.js with Expo for web especially for navigation!

👋 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 (15)

Collapse
 
raarts profile image
Ron Arts

This was the result for me (though I didn't do this on a new project, but an existing one):

Invalid options object. React Refresh Plugin has been initialized using an options object that does not match the API schema.

  • options has an unknown property 'disableRefreshCheck'. These properties are valid: object { exclude?, forceEnable?, include?, overlay?, useLegacyWDSSockets? }
Collapse
 
younes0 profile image
Younes Bieche • Edited

remove disableRefreshCheck (deprecated option)

if (env.mode === 'development') {
  config.plugins.push(new ReactRefreshWebpackPlugin())
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
walidvb profile image
Walid

I also couldn't make it work, both with @expo/webpack-config 0.12.20 and @expo/webpack-config 0.12.17.

My save does trigger a new compilation, but the webpack message sent via websocket to the browser is {"type": "invalid"}

Collapse
 
seanmclem profile image
Seanmclem

When I do this, my iOS project gets errors like no such file or directory "css-to-react-native"

Which seems related to styled-components, but never had the issue before, and it immediately goes away when I revert.

Collapse
 
orawko profile image
Bartłomiej Orawiec • Edited

Great tutorial!
In my case to make it work, @younes0 change was required, and additional command to solve issue with this library:

yarn add -D react-refresh

After that is working, Expo SDK 46.

Collapse
 
benceg profile image
Ben Ceglowski • Edited

This is broken by @expo/webpack-config 0.12.20. And not just fast refresh: no refreshes happen at all.

The issue was opaque, but after enough digging I found pinning that dependency to @0.12.17 restored fast refresh functionality.

Collapse
 
benceg profile image
Ben Ceglowski

Followup: I no longer experience this problem with @expo/webpack-config 0.12.25.

Collapse
 
asdaswnwow profile image
nonamelol

it doesn't seem to work for me

Collapse
 
asdaswnwow profile image
nonamelol

ah nevermind. it worked after upgrading Expo

Collapse
 
danieloi profile image
Mayowa Daniel

expo customize:web doesn't appear to work anymore.

It just says 'Exiting with no change...'

Collapse
 
ajinkyax profile image
Ajinkya Borade

I was an expo fan, untill I started using Flutter :)

Collapse
 
yoyooo profile image
yoyooo

EXPO is my favorite

Collapse
 
beepsoft profile image
beep

I could make it work in 2022 like this:

forums.expo.dev/t/enabling-fast-re...

Collapse
 
protoplan profile image
Protoplan • Edited

Aaaand in 2023, not working (for me at least). Same results as with this article, it prevents the automatic refresh which loses state, but instead, nothing updates. Will keep looking.

I am here bc I can't get HMR working on Expo Go either 😥

Collapse
 
kakavip profile image
Phạm Quý Hải

Current not working. please update