Warning
This package is in beta and will have relatively frequent breaking changes.
Server integration for Vike.
With this extension, your server is transpiled with Vite. So that you don't need ts-node
/tsx
anymore.
In development, the server process is restarted when a change is detected.
Installation
Custom pageContext
Standalone build
Compression
Version history
Overview
Add to existing server
Supported servers
Example of adding vike-node
and Express.js to a Vike app that doesn't use a server yet.
Note
- See Add to existing server if you already have a server.
- See Supported servers for installing
vike-node
with a server other than Express.js.
npm install vike-node express
- Extend
vite.config.js
:// vite.config.js import vikeNode from 'vike-node/plugin' export default { // ... plugins: [vikeNode('server/index.js')] }
- Create
server/index.js
:// server/index.js import express from 'express' import vike from 'vike-node/express' startServer() function startServer() { const app = express() app.use(vike()) const port = 3000 app.listen(port, () => console.log(`Server running at http://localhost:${port}`)) }
- Add production
script
:// package.json "scripts": { "dev": "vike", "build": "vike build", + "prod": "NODE_ENV=production node dist/server/index.mjs" }
If you already have a server:
// server/index.js
- import { renderPage } from 'vike/server'
+ import vike from 'vike-node/express'
- if (isProduction) {
- app.use(express.static(`${root}/dist/client`))
- } else {
- const vite = await import('vite')
- const viteDevMiddleware = (
- await vite.createServer({
- root,
- server: { middlewareMode: true }
- })
- ).middlewares
- app.use(viteDevMiddleware)
- }
- app.get('*', async (req, res, next) => {
- const pageContextInit = {
- urlOriginal: req.originalUrl
- }
- const pageContext = await renderPage(pageContextInit)
- const { httpResponse } = pageContext
- if (!httpResponse) {
- return next()
- } else {
- const { statusCode, headers } = httpResponse
- headers.forEach(([name, value]) => res.setHeader(name, value))
- res.status(statusCode)
- httpResponse.pipe(res)
- }
- })
+ app.use(vike())
// package.json
"scripts": {
"build": "vike build",
- "dev": "node ./server/index.js",
+ "dev": "vite",
- "prod": "NODE_ENV=production node ./server/index.js"
+ "prod": "NODE_ENV=production node dist/server/index.mjs"
}
vike-node
includes middlewares for all commonly used server frameworks.
See complete list of supported servers.
// server/index.js
import express from 'express'
import vike from 'vike-node/express'
startServer()
function startServer() {
const app = express()
app.use(vike())
const port = 3000
app.listen(port, () => console.log(`Server running at http://localhost:${port}`))
}
// server/index.js
import fastify from 'fastify'
import vike from 'vike-node/fastify'
startServer()
function startServer() {
const app = fastify()
app.all('/*', vike())
const port = 3000
app.listen({ port }, () => console.log(`Server running at http://localhost:${port}`))
}
// server/index.js
import { serve } from '@hono/node-server'
import { Hono } from 'hono'
import vike from 'vike-node/hono'
startServer()
function startServer() {
const app = new Hono()
app.use(vike())
const port = 3000
serve(
{
fetch: app.fetch,
port
},
() => console.log(`Server running at http://localhost:${port}`)
)
}
// server/index.js
import { createApp, toNodeListener } from 'h3'
import { createServer } from 'http'
import vike from 'vike-node/h3'
startServer()
async function startServer() {
const app = createApp()
app.use(vike())
const port = 3000
const server = createServer(toNodeListener(app)).listen(port)
server.on('listening', () => {
console.log(`Server running at http://localhost:${port}`)
})
}
// server/index.js
import { Elysia } from 'elysia'
import vike from 'vike-node/elysia'
startServer()
function startServer() {
const app = new Elysia()
app.get('/*', vike())
const port = 3000
app.listen(port, () => console.log(`Server running at http://localhost:${port}`))
}
You can define custom pageContext properties:
import { type RuntimeAdapter } from 'vike-node/express';
app.use(
vike({
pageContext(runtime: RuntimeAdapter) {
return {
user: runtime.req.user
}
}
})
)
Note
See RuntimeAdapter
(vike-node
uses universal-middleware under the hood).
Note
The runtime
object is also available at pageContext.runtime
so that, even without the custom pageContext
function above,
you can retrieve pageContext.runtime.req.user
in Vike hooks and UI components (with usePageContext()
).
With standalone: true
, the build output directory (dist/
) contains everything needed for deployment. This means that, in production, only dist/
is required (i.e. you can remove node_modules/
and skip npm install
).
// vite.config.js
import vikeNode from 'vike-node/plugin'
export default {
plugins: [
vikeNode({
entry: 'server/index.js',
standalone: true
})
]
}
Options:
vikeNode({
external: ['my-rust-package'],
standalone: {
esbuild: {
minify: true,
// ... or any other esbuild option
}
}
})
If an npm package uses native binaries / custom assets then it needs to be added to external
. (Its assets will then be copied to dist/
.)
Note
The following are external
by default:
sharp
@prisma/client
@node-rs/*
PR welcome to add other packages known to have a native dependency.
vike-node
uses esbuild for bundling server code; you can use standalone.esbuild
to set esbuild options.
In production, vike-node
compresses all Vike responses.
You can disable it:
app.use(
vike({
compress: false
})
)