Telaio
Server

Plugins

Opt-in Fastify plugins for CORS, cookies, compression, multipart uploads, WebSocket, SSE, and route autoloading.

Plugins

.withPlugins(options) registers a set of Fastify plugins. Every plugin is guarded by a dynamic import() -- if the peer dependency is not installed, the plugin is silently skipped. The app starts without error.

Plugin table

OptionPeer DependencyDescription
cors@fastify/corsAdds CORS headers. Defaults: credentials: true, methods GET POST PUT PATCH DELETE OPTIONS, maxAge: 86400
helmet@fastify/helmetAdds security headers via Helmet. CSP is configured to include the Scalar CDN by default
cookie@fastify/cookieParses and signs cookies. Pass { secret: '...' } to enable signed cookies
compress@fastify/compressCompresses responses with gzip/brotli. Set global: true to compress all responses
multipart@fastify/multipartHandles multipart form data. Default limits: fileSize: 10 MB, files: 1
websocket@fastify/websocketEnables WebSocket upgrade support
ssefastify-sse-v2Adds Server-Sent Events support
autoload@fastify/autoloadDiscovers and loads routes from src/routes/

Registration order

Plugins are registered in this fixed order regardless of how you declare them in the options object:

SSE -> Cookie -> WebSocket -> Compress -> CORS -> Helmet -> Multipart -> Autoload

This order is intentional. CORS and security headers must apply before route handlers run. Cookie parsing must be available before auth hooks fire.

Usage

const app = await createApp({ config })
  .withPlugins({
    cors: true,                // default CORS settings
    cookie: { secret: process.env.COOKIE_SECRET },
    compress: { global: true },
    multipart: {
      limits: {
        fileSize: 50 * 1024 * 1024,  // 50 MB
        files: 5,
      },
    },
    autoload: {
      dir: 'src/routes',
      routeParams: true,
      cascadeHooks: true,
    },
  })
  .build();

CORS options

Pass true to use all defaults, or an object to override specific fields.

OptionDefaultDescription
credentialstrueAllow cookies and Authorization headers in cross-origin requests
allowedHeaders--Restrict which request headers are permitted
methodsGET POST PUT PATCH DELETE OPTIONSAllowed HTTP methods
maxAge86400Preflight cache TTL in seconds
origins--Allowed origins. Omit to reflect the request origin
.withPlugins({
  cors: {
    origins: ['https://app.example.com', 'https://admin.example.com'],
    allowedHeaders: ['Content-Type', 'Authorization'],
  },
})

Helmet options

OptionTypeDescription
enableCSPNoncesbooleanAttach a CSP nonce to every request
contentSecurityPolicyobjectRaw CSP directives to merge with Telaio's defaults

Multipart limits

OptionDefaultDescription
fieldNameSize--Max field name length in bytes
fieldSize--Max field value size in bytes
fields--Max number of non-file fields
fileSize10 MBMax file size in bytes
files1Max number of files per request

Temp file support

Call .withTempFiles() on the builder to enable automatic temp file management. This adds three decorators to every request object.

const app = await createApp({ config })
  .withTempFiles()
  .withPlugins({ multipart: true })
  .build();
DecoratorDescription
req.tempFilesArray of temp file paths registered for this request
req.addTempFile(path)Register a file path for automatic cleanup
req.getTempFile(opts?)Generate a unique temp file path and auto-register it

req.getTempFile accepts an optional { extension } option to append a file extension to the generated path.

All registered temp files are deleted automatically after the response is sent, including on error paths.

fastify.post('/upload', async (req, reply) => {
  const data = await req.file();
  const tmpPath = req.getTempFile({ extension: '.jpg' });

  // Write the uploaded file to the temp path
  await pipeline(data.file, fs.createWriteStream(tmpPath));

  // Process the file...
  const result = await processImage(tmpPath);

  // tmpPath is deleted automatically after reply is sent
  return result;
});

req.getTempFile() generates the path and registers it immediately. You do not need to call req.addTempFile() separately for files created via req.getTempFile().

If you write to a path obtained from req.getTempFile() but the write fails partway through, the partial file is still cleaned up automatically. The cleanup runs unconditionally after each response.

On this page