Vite as Node.js runtime that enables on-demand evaluation with full ESM and TypeScript support
npx @tessl/cli install tessl/npm-vite-node@3.2.0Vite Node is a Node.js runtime that leverages Vite's pipeline, plugins, resolvers, and transformers to execute JavaScript and TypeScript files on-demand. It provides the engine that powers Vitest testing framework and Nuxt 3 Dev SSR, offering features like on-demand evaluation, out-of-box ESM and TypeScript support, hot module replacement (HMR), and separate server/client architecture.
npm install vite-nodeimport { ViteNodeRunner } from "vite-node/client";
import { ViteNodeServer } from "vite-node/server";
import { installSourcemapsSupport } from "vite-node/source-map";For CommonJS:
const { ViteNodeRunner } = require("vite-node/client");
const { ViteNodeServer } = require("vite-node/server");import { createServer } from "vite";
import { ViteNodeRunner } from "vite-node/client";
import { ViteNodeServer } from "vite-node/server";
import { installSourcemapsSupport } from "vite-node/source-map";
// Create vite server
const server = await createServer({
optimizeDeps: {
disabled: true, // Recommended for vite-node
},
});
// Create vite-node server
const node = new ViteNodeServer(server);
// Install source map support for better error traces
installSourcemapsSupport({
getSourceMap: source => node.getSourceMap(source),
});
// Create vite-node runner
const runner = new ViteNodeRunner({
root: server.config.root,
base: server.config.base,
fetchModule(id) {
return node.fetchModule(id);
},
resolveId(id, importer) {
return node.resolveId(id, importer);
},
});
// Execute a TypeScript file
await runner.executeFile('./example.ts');
// Close the server
await server.close();Vite Node is built around a server/client architecture with several key components:
ViteNodeServer handles module transformation, resolution, and caching using Vite's pipelineViteNodeRunner executes transformed modules with proper isolation and context managementts-nodeCore module execution engine that runs transformed JavaScript/TypeScript code with proper context isolation and dependency management.
class ViteNodeRunner {
constructor(options: ViteNodeRunnerOptions);
executeFile(file: string): Promise<any>;
executeId(rawId: string): Promise<any>;
}
interface ViteNodeRunnerOptions {
root: string;
fetchModule: FetchFunction;
resolveId?: ResolveIdFunction;
createHotContext?: CreateHotContextFunction;
base?: string;
moduleCache?: ModuleCacheMap;
interopDefault?: boolean;
requestStubs?: Record<string, any>;
debug?: boolean;
}Server-side integration with Vite that handles module transformation, resolution, and caching through Vite's plugin system.
class ViteNodeServer {
constructor(server: ViteDevServer, options?: ViteNodeServerOptions);
fetchModule(id: string, transformMode?: 'web' | 'ssr'): Promise<FetchResult>;
resolveId(id: string, importer?: string, transformMode?: 'web' | 'ssr'): Promise<ViteNodeResolveId | null>;
getSourceMap(source: string): EncodedSourceMap | null;
}
interface ViteNodeServerOptions {
sourcemap?: 'inline' | boolean;
deps?: DepsHandlingOptions;
transformMode?: {
ssr?: RegExp[];
web?: RegExp[];
};
debug?: DebuggerOptions;
}Path handling, module resolution, and platform utilities for working with file systems and import paths.
function normalizeModuleId(id: string): string;
function isNodeBuiltin(id: string): boolean;
function toFilePath(id: string, root: string): { path: string; exists: boolean };
function slash(str: string): string;Complete HMR implementation with event handling, module invalidation, and hot context management for development workflows.
function createHotContext(
runner: ViteNodeRunner,
emitter: HMREmitter,
files: string[],
ownerPath: string
): HotContext;
function handleMessage(
runner: ViteNodeRunner,
emitter: HMREmitter,
files: string[],
payload: HMRPayload
): Promise<void>;Inline source map support for debugging with accurate stack traces in transformed code.
function installSourcemapsSupport(options: InstallSourceMapSupportOptions): void;
function withInlineSourcemap(result: TransformResult, options: {
root: string;
filepath: string;
noFirstLineMapping?: boolean;
}): TransformResult;
interface InstallSourceMapSupportOptions {
getSourceMap: (source: string) => EncodedSourceMap | null | undefined;
}Command-line interface for executing JavaScript and TypeScript files directly with Vite's transformation pipeline.
# Execute a TypeScript file
npx vite-node index.ts
# Watch mode with automatic restart
npx vite-node --watch index.ts
# Script mode for hashbang usage
npx vite-node --script script.ts
# With configuration
npx vite-node --config vite.config.ts index.tsFile type constants and regular expressions for asset detection and CSS language identification.
const KNOWN_ASSET_TYPES: string[];
const KNOWN_ASSET_RE: RegExp;
const CSS_LANGS_RE: RegExp;Import:
import { KNOWN_ASSET_TYPES, KNOWN_ASSET_RE, CSS_LANGS_RE } from "vite-node/constants";type Nullable<T> = T | null | undefined;
type Arrayable<T> = T | Array<T>;
type Awaitable<T> = T | PromiseLike<T>;
type FetchFunction = (id: string) => Promise<FetchResult>;
type ResolveIdFunction = (id: string, importer?: string) => Awaitable<ViteNodeResolveId | null | undefined | void>;
type CreateHotContextFunction = (runner: ViteNodeRunner, url: string) => HotContext;
interface FetchResult {
code?: string;
externalize?: string;
map?: EncodedSourceMap | null;
}
interface ViteNodeResolveId {
external?: boolean | 'absolute' | 'relative';
id: string;
meta?: Record<string, any> | null;
moduleSideEffects?: boolean | 'no-treeshake' | null;
syntheticNamedExports?: boolean | string | null;
}
interface ModuleCache {
promise?: Promise<any>;
exports?: any;
evaluated?: boolean;
resolving?: boolean;
code?: string;
map?: EncodedSourceMap;
importers?: Set<string>;
imports?: Set<string>;
}
interface DepsHandlingOptions {
external?: (string | RegExp)[];
inline?: (string | RegExp)[] | true;
inlineFiles?: string[];
moduleDirectories?: string[];
cacheDir?: string;
fallbackCJS?: boolean;
}
interface DebuggerOptions {
dumpModules?: boolean | string;
loadDumppedModules?: boolean;
}