| icon | ri:plug-line |
|---|
Use plugins to extend Nitro's runtime behavior.
::warning Nitro v3 Alpha docs are a work in progress — expect updates, rough edges, and occasional inaccuracies. ::
Nitro plugins will be executed once during server startup in order to allow extending Nitro's runtime behavior.
They receive nitroApp context, which can be used to hook into Nitro lifecycle events.
Plugins are auto-registered from plugins/ directory and run synchronously (by order of file name) on the first Nitro initialization.
Example:
import { definePlugin } from "nitro";
export default definePlugin((nitroApp) => {
console.log('Nitro plugin', nitroApp)
})If you have plugins in another directory, you can use the plugins option:
import { defineNitroConfig } from "nitro/config";
export default defineNitroConfig({
plugins: ['my-plugins/hello.ts']
})You can use Nitro hooks to extend the default runtime behaviour of Nitro by registering custom (async or sync) functions to the lifecycle events within plugins.
Example:
import { definePlugin } from "nitro";
export default definePlugin((nitro) => {
nitro.hooks.hook("close", async () => {
// Will run when nitro is being closed
});
})"request", (event) => {}- Called when a request is received. Available in all presets."error", (error, { event? }) => {}- Called when an error is captured. Available in all presets."response", (response, event) => {}- Called when a response is sent. Available in all presets."close", () => {}- Called when the server receives a shutdown signal (SIGTERMorSIGINT). Only available in long-running server presets (Node.js, Bun, Deno). Not called in serverless or edge environments.
You can use plugins to capture all application errors.
import { definePlugin } from "nitro";
export default definePlugin((nitro) => {
nitro.hooks.hook("error", async (error, { event }) => {
console.error(`${event.path} Application error:`, error)
});
})On long-running server presets (node-server, node-cluster, bun, deno-server), the close hook fires when the process receives SIGTERM or SIGINT, allowing plugins to run async cleanup before exit.
import { definePlugin } from "nitro";
export default definePlugin((nitro) => {
nitro.hooks.hook("close", async () => {
await flushTelemetry();
await db.close();
});
})Serverless and edge runtimes (Cloudflare Workers, AWS Lambda, Vercel, Netlify, Deno Deploy) do not have a shutdown signal–the platform terminates the execution context without notice. The close hook will not fire in these environments.
For per-request cleanup that works across all presets, use the "response" hook or request.waitUntil() instead:
import { definePlugin } from "nitro";
export default definePlugin((nitro) => {
nitro.hooks.hook("response", async (response, event) => {
await flushRequestTelemetry(event);
});
})You can use plugins to register a hook that can run on request lifecycle:
import { definePlugin } from "nitro";
export default definePlugin((nitroApp) => {
nitroApp.hooks.hook("request", (req) => {
console.log("on request", req.url);
});
});