<Marc Qualie/>

Vite + React Quickstart

Photo of Marc Qualie

I've been setting up a lot of quick experiments and prototypes lately to prove concepts. For these kind of apps I don't need a full stack like NextJS, but I also want to be able to use React + TypeScript for various reasons such as component testing or debugging. The aim is also to avoid hosted solutions like Code Sandbox or Stackblitz so I can use the code offline and also pull in local packages that aren't public.

It's surprisingly simple to get a working react app locally now with Vite and a few lines of html/jsx. I like this approach because it's a "close to the metal" as possible with react avoids complex build steps.

It's worth noting this is in-fact raw react and isn't designed for production use. Many layers will be needed on top for things like routing, SSR, hot reloading, etc but I don't need any of those for my quick throw away tests.

Dependencies

yarn add react react-dom
yarn add -D @types/react @types/react-dom vite

Yes, I'm still using yarn since my primary work toolchain is based around it but you can replace yarn with pnpm or npm to get the same result.

Files

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>React + Vite Prototype</title>
  <script src="/app.tsx" type="module"> </script>
</head>
<body>

</body>
</html>

app.tsx

import React, { type FC, StrictMode } from 'react'
import { createRoot } from 'react-dom/client'

export const App: FC = () => {
  return (
    <div>Hello, world!</div>
  )
}

document.addEventListener('DOMContentLoaded', () => {
  createRoot(document.body).render(
    <StrictMode>
      <App />
    </StrictMode>,
  )
})

Running

vite dev

You can now access the app on http://localhost:5173 (default port). You should see "Hello, world!" in your browser if everything worked.

Conclusion

This is mainly here for my own reference so I can quickly copy + paste this when setting up a new experiment. The goal is to have as basic of a setup as possible to avoid conflicts with any dependencies then replicate the behaviour from the experiment into other projects.

If you have any questions about this post, or anything else, you can get in touch on Bluesky or browse my code on Github.