Skip to content

rtritto/vike-node

Repository files navigation

npm version

vike-node

Node integration for Vike.

With this extension, your server-side code is transpiled with Vite.
In development, the server process is restarted when a change is detected in some of your server files.

Installation
Standalone build
External packages
Caching and compression
Custom pageContext
Framework examples
Migration guide


Installation

  1. npm install vike-node express

  2. Extendvite.config.js:

    // vite.config.js
    
    importvikeNodefrom'vike-node/plugin'
    
    exportdefault{
    //...
    plugins:[vikeNode('server/index.js')]
    }
  3. Createserver/index.js:

    // server/index.js
    
    importexpressfrom'express'
    importvikefrom'vike-node/connect'
    
    startServer()
    
    functionstartServer(){
    constapp=express()
    app.use(vike())
    constport=process.env.PORT||3000
    app.listen(port,()=>console.log(`Server running at http://localhost:${port}`))
    }

Standalone build:

You can enable standalone builds by settingstandalonetotrue.
After build, the outputdistfolder will contain everything for a deployment.
With standalone mode, the production environment only needs thedistfolder to be present.
Example start script:NODE_ENV=production node dist/server/index.mjs

// vite.config.js

importvikeNodefrom'vike-node/plugin'

exportdefault{
//...
plugins:[
vikeNode({
entry:'server/index.js',
standalone:true
})
]
}

External packages:

Packages that import native binaries/custom assets need to be added toexternal.
When building withstandaloneenabled,externalpackages and their assets are copied to the outputdistdirectory.
By default, theexternalsetting includes:

  • sharp
  • @prisma/client
  • @node-rs/*
// vite.config.js

importvikeNodefrom'vike-node/plugin'

exportdefault{
//...
plugins:[
vikeNode({
entry:'server/index.js',
standalone:true,
external:['my-rust-package']
})
]
}

Caching and compression:

In production,vike-node:

  • compresses all Vike responses
  • caches the compressed static assets(.js,.css).

On a request, if the asset(.js,.css) is not in the cache,vike-nodecompresses it with a fast compression level, sends it in the response, then recompresses it with a high compression level and finally caches the compressed data.
You can disable compression/caching:

app.use(
vike({
compress:false,
static:{
cache:false
}
})
)

You can define custompageContextproperties:

app.use(
vike({
pageContext:(req)=>({
user:req.user
})
})
)

Framework examples:

vike-nodeincludes middlewares for the most popular web frameworks:

  • Express
  • Fastify
  • Hono
  • H3
  • Elysia (Bun)

Express:

// server/index.js

importexpressfrom'express'
importvikefrom'vike-node/connect'

startServer()

functionstartServer(){
constapp=express()
app.use(vike())
constport=process.env.PORT||3000
app.listen(port,()=>console.log(`Server running at http://localhost:${port}`))
}

Fastify:

// server/index.js

importfastifyfrom'fastify'
importvikefrom'vike-node/fastify'

startServer()

functionstartServer(){
constapp=fastify()
app.register(vike())
constport=+(process.env.PORT||3000)
app.listen({port},()=>console.log(`Server running at http://localhost:${port}`))
}

Hono:

// server/index.js

import{serve}from'@hono/node-server'
import{Hono}from'hono'
importvikefrom'vike-node/hono'

startServer()

functionstartServer(){
constapp=newHono()
app.use(vike())
constport=+(process.env.PORT||3000)
serve(
{
fetch:app.fetch,
port
},
()=>console.log(`Server running at http://localhost:${port}`)
)
}

H3:

// server/index.js

import{createApp,toNodeListener}from'h3'
import{createServer}from'http'
importvikefrom'vike-node/h3'

startServer()

asyncfunctionstartServer(){
constapp=createApp()
app.use(vike())
constport=process.env.PORT||3000
constserver=createServer(toNodeListener(app)).listen(port)
server.on('listening',()=>{
console.log(`Server running at http://localhost:${port}`)
})
}

Elysia (Bun):

// server/index.js

import{Elysia}from'elysia'
importvikefrom'vike-node/elysia'

startServer()

functionstartServer(){
constapp=newElysia()
app.use(vike())
constport=+(process.env.PORT||3000)
app.listen(port,()=>console.log(`Server running at http://localhost:${port}`))
}

Migration guide:

// server/index.js

-import { renderPage } from 'vike/server'
+import { vike } from 'vike-node/connect'

-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": {
-"dev": "node./server",
+"dev": "vite",
}

About

🔨 Node integration for Vike

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • TypeScript 99.3%
  • Other 0.7%