Serving Vite + React with Hono
Serving Vite + React with Hono
Hono is a lightweight, ultrafast web framework built on web standards, designed to work seamlessly across various JavaScript runtimes like Cloudflare Workers, Fastly, Deno, Bun, and Node.js. It offers a delightful developer experience with built-in middleware, first-class TypeScript support, and a clean API12.
Vite, on the other hand, is a modern build tool that provides a fast and lean development experience for web projects. It features a dev server with rich enhancements like Hot Module Replacement (HMR) and a build command that bundles code with Rollup for optimized production output. Vite is highly extensible and supports various frameworks, including React34.
Combining Hono with Vite and React allows developers to create efficient, high-performance web applications with a streamlined development workflow.
Repo
github.com/KrisNathan/vite-react-signal-hono
Create Vite + React App
npm create vite@latest
- Select React
- Select Typescript
Build Vite + React
npm run build
Create Hono App
npm create hono@latest
- This time we will select NodeJS, but you can use Bun or Deno if you want, they are mostly the same code wise
I also recommend setting up workspace but it’s not necessary.
Structure
.
├── hono
│ ├── package.json
│ ├── README.md
│ ├── src
│ │ └── index.ts
│ └── tsconfig.json
├── package.json
├── package-lock.json
└── react
├── eslint.config.js
├── index.html
├── package.json
├── public
│ └── vite.svg
├── README.md
├── src
│ ├── App.css
│ ├── App.tsx
│ ├── assets
│ │ └── react.svg
│ ├── index.css
│ ├── Layout.tsx
│ ├── main.tsx
│ ├── pages
│ │ └── Home.tsx
│ └── vite-env.d.ts
├── tsconfig.app.json
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.ts
Working with Hono
Import the following modules:
// hono/src/index.ts
import { serve } from "@hono/node-server";
import { serveStatic } from "@hono/node-server/serve-static";
Serve the entire dist directory. This would include all the necessary js and assets.
// hono/src/index.ts
app.use(
"*",
serveStatic({
root: "../react/dist",
})
);
Serve all other routes to index.html. This way if a user tries to directly access a page managed by react router it would not return a 404.
// hono/src/index.ts
app.use("/*", serveStatic({ root: "../react/dist", path: "index.html" }));
Final Code
Heres the final code if we use hono nodejs.
// hono/src/index.ts
import { Hono } from "hono";
import { serve } from "@hono/node-server";
import { serveStatic } from "@hono/node-server/serve-static";
const app = new Hono();
app.use(
"*",
serveStatic({
root: "../react/dist",
})
);
app.use("/*", serveStatic({ root: "../react/dist", path: "index.html" }));
const port = 3000;
console.log(`Server is running on http://localhost:${port}`);
serve({
fetch: app.fetch,
port,
});
Trying it out
Simply run:
npm run dev