⚡️ Getting Started with Vite for React and Elm

I feel like everywhere I look I’m seeing the super fancy Vite logo. I thought it would be fun to take a look at Vite for my first time today and share my experience with it. Vite is a front-end build tool that comes out-of-the-box with a dev server and hot module reloading. I don’t know a lot beyond it yet, other than the claims of an “optimized build” and “rich features” from their GitHub.

Honestly, my hope going into this is that it can be like Webpack, but with a lot less headache. I primarily work with React and Elm for the front-end, so I would like to get both of those working with hot module replacement. With that in mind, let’s take a look at that gorgeous logo and get started!

Vite logo
The Vite Logo.

👩‍🔬 Development

The Getting Started page on their website tells us to run the following command:

npm create vite@latest

Upon running this command, we are prompted with a choice to pick our framework. I’m going to pick React to get things going quickly. After this I choose to use React without TypeScript, because I’m feeling a little wild today 🐅.

Selecting the front-end framework with Vite
Selecting the front-end framework with Vite.

And… done? I’ll run a cd first-class-vite and then run npm i. After packages are installed, we see that Vite came with three scripts in package.json: dev, build, preview. Assuming dev is the one we’ll use to dev, let’s run that. At this point we’re shown a message saying the Vite app is running at localhost:3000. Go there and take a look!

The Vite + React default page
The Vite + React default page.

With a few less steps than create-react-app, we have a React project up and running. This one even comes with Hot-Module Replacement. Sweet! At this point, I’m going to change out the default app for my own. Wordle is super popular right now, which reminds me of the game Mastermind that I played as a kid. I wrote up a similar game I’ll be calling Mistermind. I did everything using local react state with useState hooks. I’ll push this up to this GitHub repo so you can check it out!

Elm

I adore Elm. I needed to get that off of my chest. It’s great and I need to be able to use it with Vite, if I’m going to use it! Luckily, this repo, hmsk/vite-plugin-elm promises to provide Elm support. I’ll start by running the install command.

npm i -D vite-plugin-elm

After running this, I’ll update vite.config.js to include the new elm plugin. This leaves the vite config looking as follows:

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import elm from 'vite-plugin-elm';

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react(), elm()],
});

At this point, I would like to use an Elm to hold some of the app state for the app. This is a bit contrived, since I’m only going to be moving past guesses/turns in there. If you want to learn more about using React & Elm in tandem, I just wrote a post about it! In our main.jsx, I’ll import the Elm component I created and pass the ports to the React app below.

const appState = Elm.AppState.init({
  node: document.getElementById('elm-root'),
});

ReactDOM.render(
  <App ports={appState.ports} />,
  document.getElementById('root')
);

Then back in the React component, we’ll hook it up and save. Now for the moment of truth. We have to stop and run npm run dev again to pick up the plugin changes. After that we have a clean console and can go back to localhost:3000.

Mistermind demo with React app and Elm holding state.

Sweet! Without any more work than installing and turning on the plugins, we have React and Elm working in tandem. And with that, let’s take a turn towards deployment.

🚀 Build & Deployment

First, let’s just build the static site using the npm run build command included with Vite. After running this, a dist folder is created containing the static assets for our Vite app. Nice. 😌

npm run build

The Vite website has a guide on deploying to Github pages, which is what I’m shooting to do. However, rather than run a deploy script, I’m just going to run the build and set GitHub pages to point to the /docs folder in settings. You can see this up and running here! Although this worked pretty much right out-of-the-box, I did hit one snag with the base URL. Even though they mention it, I forgot to set the base option in my Vite config.

I’m hosting the app at abshierjoel.github.io/mistermind. Knowing that, I only need to set the base option to that directory to get that to work. To do that, open up vite.config.js one more time and update the defineConfig call to look like this:

export default defineConfig({
  base: '/mistermind/',
  plugins: [react(), elm()],
});

🎉 Conclusion

In conclusion, Vite is sick. Obviously this has been a fairly simple example of a static site, but I find myself creating a lot of those. But after this, I’ll definitely be spending more time with Vite to see if it can fully replace Webpack for me and save time configuring. I do hope my first swing at this has been helpful to anyone else wanting to take a look at what Vite has to offer. I’m excited to learn more, so if you’re a little further along on your Vite journey than I am, I’d love to hear from you down below.

Thanks for reading,

– Joel Abshier