Skip to main content
Blaze’s middleware system gives you a familiar Express-style (req, res, next) pipeline that runs inside a Cloudflare Worker. Every piece of middleware you’ve written for Express works unchanged in Blaze, and the 12 built-in modules cover the most common API needs — authentication, CORS, caching, rate limiting, and more — without adding a single npm dependency.

How middleware works

When a request arrives, Blaze walks a Layer stack — an ordered array of middleware and route Layers registered at startup. Each Layer has a path (derived from the first argument of app.use()) and a handle function.
  • app.use(fn) appends a global Layer that matches every path.
  • app.use('/prefix', fn) appends a Layer that only matches paths starting with /prefix.
  • Inside each Layer, calling next() hands control to the next matching Layer.
  • If a Layer throws synchronously, or an async handler rejects, Blaze catches the error and routes it to the nearest 4-arg error handler.
Middleware registered earlier in your code runs first. Load global concerns — request IDs, loggers, CORS — before route-specific middleware and your route handlers.
When a Layer calls res.json(), res.send(), or res.html(), it resolves the internal response promise and the cycle ends — downstream Layers are not called.

Writing custom middleware

Synchronous middleware

Async middleware

Forwarding errors with next(err)

When something goes wrong inside middleware, pass the error to next instead of letting it propagate unhandled. Blaze routes it to the nearest downstream error handler.

Error handlers (4-argument signature)

An error handler is a middleware function that accepts four arguments: (err, req, res, next). Blaze identifies it by arity and only invokes it when an error has been forwarded.

All built-in middleware

cors

Set Access-Control-* headers and handle OPTIONS preflight. Supports dynamic origins, credentials, and maxAge.

logger

Log method, path, status, response time, and Cloudflare colo to console.log. Supports short, long, and custom formats.

bearerAuth

Validate Authorization: Bearer <token> headers against a static token or an async validator function.

basicAuth

Decode and verify Authorization: Basic <base64> credentials using timing-safe comparison.

jwtAuth

Verify JWTs using Web Crypto (crypto.subtle). Supports HS256 and RS256. Sets decoded payload on req.user.

rateLimit

Sliding-window rate limiting backed by Cloudflare KV. Configurable per-route with custom key functions.

cache

Cache responses via the Cloudflare Cache API. Respects existing Cache-Control headers. Only caches GET by default.

compress

Compress response bodies with gzip or deflate via CompressionStream. Checks Accept-Encoding automatically.

requestId

Attach a UUID to req.id and echo it as the X-Request-Id response header. Reuses incoming ID if present.

etag

Generate weak ETags from response bodies using a fast djb2 hash. Handles If-None-Match → 304 automatically.

timeout

Race the downstream handler chain against a timer. Calls next(err) with a 408 error if the timer fires first.

secureHdrs

Set CSP, HSTS, X-Frame-Options, Referrer-Policy, Permissions-Policy, and CORP/COEP/COOP on every response.

Middleware scope

You control exactly which requests a middleware runs for by where and how you register it.

Global — every request

Path-scoped — a URL prefix only

Route-level inline stack

Pass middleware directly as extra arguments to any route method. They run only for that route, in order, before the final handler.

Sub-router scope

Mount a Router as middleware to apply a shared stack to a group of routes without polluting the global Layer stack.