Nitro Universal Server Framework
Nitro is a versatile framework for building and deploying universal JavaScript servers, extending existing Vite applications with production-ready server capabilities. The `nitro-nightly` package represents the active development line for Nitro v3, which is currently in beta. Nitro v3 aims for a significantly smaller install size (down to 9MB), near-native runtime performance, and enhanced features like experimental tracing channels and smarter dependency tracing. While the stable release series remains v2, `nitro-nightly` provides access to cutting-edge features and improvements for upcoming major versions. Nitro focuses on a "run anywhere" philosophy, abstracting deployment complexities, and often offers a zero-configuration experience for common use cases. New `nitro-nightly` releases are frequent, reflecting active development and testing against real-world projects.
Common errors
-
Error: Cannot find module 'h3'
cause The h3 dependency, while used by Nitro, might not be correctly resolved or installed, especially in complex monorepos or with non-standard package managers.fixEnsure 'h3' is listed as a direct or transitive dependency. Run 'npm install h3' or 'yarn add h3' if it's missing, or check your lock file for correct resolution. -
TypeError: eventHandler is not a function
cause This usually happens when eventHandler (or defineEventHandler) is not correctly imported as a named export from 'nitro' or '#imports' during server build/runtime.fixVerify the import statement: 'import { eventHandler } from 'nitro';'. Also, ensure Nitro's auto-imports are correctly configured in your project (e.g., in nuxt.config.ts if used with Nuxt). -
Cannot read properties of undefined (reading 'runtimeConfig')
cause Attempting to access useRuntimeConfig() outside of a Nitro event handler context, or before the Nitro app's configuration has been properly initialized.fixEnsure useRuntimeConfig() is called within a defineEventHandler or eventHandler function. Verify that your Nitro configuration (nitro.config.ts) is properly set up with a 'runtimeConfig' object. -
Rollup failed to resolve import '...'
cause Nitro's build process, powered by Rollup, could not find an imported module. This often happens with third-party dependencies that are not properly bundled or externalized.fixCheck your 'nitro.config.ts' for 'externals' or 'rollup' options. You might need to add the failing module to 'rollup.options.external' or ensure it's correctly installed and available in your build environment.
Warnings
- breaking Nitro v3 (represented by nitro-nightly) introduces significant architectural changes and API adjustments compared to the stable v2 series. Existing v2 projects will require migration efforts.
- gotcha The 'nitro-nightly' package is a pre-release channel for Nitro v3 development. It is not intended for production use due to potential instabilities, frequent API changes, and lack of long-term support.
- breaking Multiple h3 security fixes have been released, particularly in h3 versions 1.15.5 and 1.15.9. Older Nitro versions might be vulnerable if using an unpatched h3 dependency.
- gotcha New experimental features, such as tracing channels, are introduced in Nitro v3. These features may change significantly or be removed in future pre-releases without prior notice.
Install
-
npm install nitro-nightly -
yarn add nitro-nightly -
pnpm add nitro-nightly
Imports
- defineEventHandler
import { defineEventHandler } from 'h3';import { defineEventHandler } from 'nitro'; - eventHandler
import eventHandler from 'nitro';
import { eventHandler } from 'nitro'; - useRuntimeConfig
import { useRuntimeConfig } from '#app';import { useRuntimeConfig } from 'nitro';
Quickstart
import { defineEventHandler, createApp, toNodeListener, useRuntimeConfig } from 'nitro';
import { listen } from 'listhen';
// Define a simple server route
const helloHandler = defineEventHandler(() => {
const message = 'Hello from Nitro!';
const date = new Date().toISOString();
// Example of using runtime config (though not explicitly set here)
const secretKey = process.env.MY_SECRET_KEY ?? 'default_secret';
console.log(`Request received at ${date}. Using secret: ${secretKey}`);
return { api: message, timestamp: date, secretUsed: secretKey };
});
const userHandler = defineEventHandler((event) => {
const name = event.context.params?.name || 'Guest';
return { message: `Hello, ${name}!` };
});
// Create a Nitro application
const app = createApp();
// Add routes to the app
app.router.get('/', helloHandler);
app.router.get('/api/hello/:name', userHandler);
app.router.get('/api/config', defineEventHandler(() => {
const config = useRuntimeConfig(); // Access runtime config
return {
public: config.public,
serverSecret: config.serverSecret // Example of a server-only secret
};
}));
// Define configuration for the server
const serverConfig = {
host: process.env.HOST || '0.0.0.0',
port: parseInt(process.env.PORT || '3000')
};
// Start the server
async function startServer() {
const listener = toNodeListener(app);
console.log(`Nitro server running on http://${serverConfig.host}:${serverConfig.port}`);
await listen(listener, serverConfig);
}
startServer().catch((error) => {
console.error('Failed to start Nitro server:', error);
process.exit(1);
});