Skip to content

@vite-deploy/node

This adapter allows you to deploy your Vite project to hosts which support Node.js (and more), as well as prerender your project to get pure static files. Learn how in our Node deployment guide.

Node.js is a JavaScript runtime for server-side code. This adapter can be used to produce a standalone server, middleware for other HTTP servers, or anything you want.

  1. Download a basic template for your favorite host:

    Terminal window
    npx giget@latest gh:web-runes/vite-deploy/examples/node-server
  2. Install dependencies:

    Terminal window
    npm install
  3. Start the development server:

    Terminal window
    npm run dev
  1. Add @vite-deploy/node to your project’s dependencies using your preferred package manager:

    Terminal window
    npm install @vite-deploy/node
  2. Add the plugin to your Vite config file:

    vite.config.js
    import node from "@vite-deploy/node";
    import { defineConfig } from "vite";
    export default defineConfig({
    plugins: [node({
    output: "static",
    handlerEntrypoint: "./src/handler.ts",
    })]
    });
  3. Update your TypeScript config file to include necessary types:

    tsconfig.json
    {
    "compilerOptions": {
    "types": [
    "vite/client",
    "@vite-deploy/node/types"
    ]
    },
    }
  4. Create the handler entrypoint:

    src/handler.ts
    import type { ExportedHandler } from "@vite-deploy/node";
    export default {
    fetch(request) {
    const url = new URL(request.url);
    return new Response(`Running ${url.pathname} in ${navigator.userAgent}!`);
    },
    } satisfies ExportedHandler;
  5. Start the development server:

    Terminal window
    npm run dev

The Node adapter accepts output related options. It also accepts the following:

Type: string | URL

Specifies what module should be used. It accepts:

  • Paths relative to Vite’s root: ./src/handler.ts.
  • Absolute paths: /foo/handler.ts.
  • Package specifiers: @my-pkg/handler.
  • URLs: new URL("./src/handler.ts", import.meta.url).
vite.config.js
import node from "@vite-deploy/node";
import { defineConfig } from "vite";
export default defineConfig({
plugins: [node({
// ...
handlerEntrypoint: "./src/handler.ts",
})]
});

The module must return a ExportedHandler, which handles requests:

src/handler.ts
import type { ExportedHandler } from "@vite-deploy/node";
export default {
fetch(request, context) {
const url = new URL(request.url);
return new Response(`Running ${url.pathname} in ${navigator.userAgent}!`);
},
} satisfies ExportedHandler;

Alternatively, you can export a Node request handler:

src/handler.ts
import type { ExportedHandler } from "@vite-deploy/node";
export default {
handler(req, res) {
res.end(`Running ${req.url} in ${navigator.userAgent}!`);
},
} satisfies ExportedHandler;

Type: string | URL | undefined
Default: undefined

Required if output is set to "server" or "hybrid". Specifies what module should be used. It accepts:

  • Paths relative to Vite’s root: ./src/server.ts.
  • Absolute paths: /foo/server.ts.
  • Package specifiers: @my-pkg/server.
  • URLs: new URL("./src/server.ts", import.meta.url).
vite.config.js
import node from "@vite-deploy/node";
import { defineConfig } from "vite";
export default defineConfig({
plugins: [node({
// ...
serverEntrypoint: "./src/server.ts",
})]
});

The module can contain anything. You need to implement what you’ll need for your production server needs, including serving static assets. For example using a simple Node server:

"src/server.ts
import mod from "./handler";
import * as http from "node:http";
import sirv from "sirv";
import { fileURLToPath } from "node:url";
const server = http.createServer((req, res) =>
sirv(fileURLToPath(new URL("../client/", import.meta.url)), { dev: true })(
req,
res,
() => {
mod.handler(req, res);
},
),
);
server.listen(3000, () => {
console.log("Ready at http://localhost:3000");
});

Once built, you can then run node ./dist/server/index.mjs.

Type: "silent" | "info" | undefined
Default: "info"

Specifies if requests are logged in the terminal. It can be disabled you already handle logging at runtime:

vite.config.js
import node from "@vite-deploy/node";
import { defineConfig } from "vite";
export default defineConfig({
plugins: [node({
// ...
requestLoggingLevel: "silent"
})]
});