Live Reload and Hot Module Replacement

— Written by chicoxyzzy

If you've ever worked on a frontend project, you probably know how annoying it is to refresh the page every time you make a change. It's even more frustrating when you have to wait for the page to load and then navigate back to the page you were working on. It's a waste of time and not fun at all. That's why everyone loves live reload. It's a feature that reloads the page every time you make a change. It's a great feature, but it's not always easy to set up. You are likely using a dev server provided by Vite or Webpack.

Socket runtime, a modern and "batteries included" runtime for desktop and mobile apps, doesn't have a built-in web server. Does that mean we don't provide live reload? No! We have you covered.

Socket's Built-in Live Reload

Let's start with a fresh project. We will use the Socket CLI tool named ssc (short for Socket Supply Compiler or Socket Supply CLI). It's a tool that helps you create new projects, build them, and run them. You will use it a lot, so it's a good idea to install it globally.

Note that the Socket CLI doesn't require Node.js to build or run your apps. I only use it to install the Socket CLI itself, but there are other ways to install it.

Once you have ssc installed, you can create a new project by running ssc init. Let's create a new project named live-reload in the directory also named live-reload:

ssc init live-reload

The contents of the live-reload directory should look like this:

├── .gitignore
├── socket.ini
└── src
    └── icon.png
    └── index.html

Now, let's move to the project directory and try to build and run the app:

cd live-reload
ssc build -r

We have the app running! On my mac it looks like this:

Since Socket v0.5 ssc build has a new --watch flag. Let's try it out:

ssc build -r --watch

Now when you make any changes in the files in the src directory, Socket will rebuild the app and reload it!

Let's see how it works under the hood. Open the socket.ini file. There, you can see lines like these:

; Configure your project to watch for sources that could change when running `ssc`.
; Could be a string or an array of strings
sources[] = "src"

; Tell the webview to watch for changes in its resources
; default value: false
watch = true

; Configure webview to reload when a file changes
; default value: true
reload = true

You can add more directories or files to watch for changes. For example, if you have a src/styles directory, you can add it to the sources array. If you have a src/index.css file, you can add it to the sources array as well.

When any of the files in the sources array changes and if the [webview] watch value is true, Socket will rebuild the app and run the [build] script (if defined). Then, Socket will reload the webview if the reload option is set to true (it's true by default).

Hot Module Replacement

Sometimes you don't want to reload the whole page. For example, if you have a form with some data, you don't want to lose that data when you make a change in the code. That's where Hot Module Replacement (HMR) comes in. It's a feature that allows you to replace modules in the running app without reloading the whole page. HMR is usually provided by a bundler like Webpack or Vite. Socket allows you to use these tools too!

Use the --port (and, if necessary, --host) flag to specify the port on which your dev server is running. Socket will inject the HMR client into your app. To make HMR work correctly, all you need to do is make all the built-in modules prefixed with socket: external.

For Vite, you can do it like this:

  build: {
    rollupOptions: {
      external(id) {
        return id.startsWith('socket:')

Note that Vite has an open issue about HMR and external modules, so for dev mode, you will need some hacks to make it work. See this issue for more details. While it's not fixed, you can use the Vite Plugin Externalize Dependencies.

For Webpack use the externals config option:

  externalsType: 'module',
  externals: /^socket:/,

That's it! Happy hacking!

Community guides