Below is a complete, single-project setup for a full‑stack app:
- Backend: Hono
- Frontend: Vue 3 + vue-router
- Tooling: Vite + pnpm
- One Node process that runs both backend and frontend in dev (no
concurrently). - SSR for SEO.
- All in JavaScript, single
package.json, no pnpm workspaces. - Build with one command.
mkdir hono-vue-ssr
cd hono-vue-ssr
pnpm init -yMake sure to edit the package.json and add "type": "module" so we can use import in Node if needed.
pnpm add hono vue vue-router @vue/server-rendererpnpm add -D vite @vitejs/plugin-vue cross-envNode 18+ is required for Vite 5 (and for the built-in fetch/Request/Response we use in Node).
See vite.config.js at the project root.
See index.html in the project root.
Note: <!--app-html--> is where server-rendered HTML will be injected.
Create structure:
mkdir -p src/pages src/routerSee src/main.js.
// src/router/index.js
import Home from '../pages/Home.vue'
import About from '../pages/About.vue'
export default [
{ path: '/', component: Home },
{ path: '/about', component: About },
]See src/App.vue.
See src/pages/Home.vue
See src/pages/About.vue.
See src/entry-client.js
See src/entry-server.js.
We’ll run a single Node process that:
- Serves Hono API routes on
/api/*. - Integrates Vite in dev mode for bundling/HMR.
- Renders Vue on the server (SSR) for all other routes.
- Serves static built assets in production.
See server.js.
Notes:
- In dev, Vite runs in middlewareMode, providing HMR and transforming your SSR entry. Only one Node process is started.
- In prod, we never start Vite; the server uses
dist/client/index.htmland the server bundle indist/server/entry-server.js.
See package.json.
pnpm dev– starts one Node process that:- runs Hono backend on
/api - uses Vite in middleware mode
- SSR-renders Vue pages
- runs Hono backend on
pnpm build– builds client + server bundles for the whole app indist/.pnpm preview– runs the same Node server in production mode using the built assets.
No pnpm workspace, no concurrently – everything is controlled from a single server.js.
pnpm devOpen: http://localhost:3000/
/is SSR-rendered Vue Home page./aboutis SSR-rendered About page./api/hellois a JSON endpoint served by Hono.
pnpm build
pnpm preview
# or: PORT=8080 pnpm previewNow the app uses the pre-built bundles, still with SSR, and can be deployed anywhere that can run node server.js (Render, Railway, Fly, Heroku-style, plain VPS, etc.).