Fast & minimalist
REST framework for Node.js
Blazing fast, tiny, and secure-by-default. Express-inspired API with serverless support, nested routers, and zero bloat.
Safer APIs, clearer operations
Restana 6.1 strengthens production behavior without trading away routing performance.
Reliable lifecycle
service.start() now rejects cleanly on socket and port conflicts, making startup failures observable and recoverable.
Explicit trust
Error details are opt-in for local debugging, while forwarded TLS headers require an explicitly trusted proxy.
Stronger API contracts
Boolean bodies, array-valued headers, cache disabling, and TypeScript declarations now match documented behavior.
Performance guarded
Response and routing benchmarks now run with CI budgets, including a direct router-integration overhead check.
Why restana?
A framework designed for speed, simplicity, and production safety.
Blazing Fast
Lightweight routing with minimal overhead. The sequential router uses internal caching for repeated lookups — tuned for raw throughput.
Secure by Default
Default error masking, header injection protection, security headers, TRACE disabled, and isolated config snapshots — all on by default.
Middleware Engine
Express-compatible middleware with full async/await support. Global, prefix, and route-level — you choose the scope.
Nested Routers
Modular architecture with nested routers via service.newRouter(). Mount under prefixes and compose cleanly.
Serverless Ready
Native integration with AWS Lambda via serverless-http and Google Cloud Functions for Firebase. Deploy anywhere.
Minimal Footprint
Three runtime dependencies. Zero bloat. The res.send() method handles null, strings, buffers, objects, streams, and promises — all in one call.
Safe Out of the Box
restana v6.1 ships with hardened security defaults. No extra packages needed.
Safe Error Masking
Error details are hidden in every environment by default. Local development can explicitly opt in with debugErrors: true; production always masks details.
Header Injection Protection
Security-sensitive and hop-by-hop headers (transfer-encoding, content-length, connection, set-cookie, etc.) are silently dropped from res.send(). Invalid header characters are caught, not crashed.
Default Security Headers
Every response gets X-Content-Type-Options: nosniff, X-Frame-Options: DENY, and X-XSS-Protection: 0. HSTS is set for direct TLS or explicitly trusted proxies.
TRACE Disabled by Default
Eliminates Cross-Site Tracing (XST) attack surface. Re-enable for debugging with enableTrace: true — not recommended in production.
Immutable Configuration
getConfigOptions() returns an isolated snapshot. Nested plain objects and arrays are cloned and frozen so middleware cannot mutate framework options.
Stream & Promise Safety
Stream errors are handled gracefully (connection terminates, no leak). Promise resolution is capped at depth 3 to prevent event loop starvation.
Quick Start
Common patterns to get you moving fast.
const restana = require('restana')
const service = restana()
service.get('/hi', (req, res) => res.send('Hello World!'))
service.start(3000)
const https = require('https')
const restana = require('restana')
const service = restana({
server: https.createServer({
key: keys.serviceKey,
cert: keys.certificate
})
})
service.get('/hi', (req, res) => res.send('Hello World!'))
service.start(3000)
service.get('/api/users', (req, res) => {
res.send({ users: [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
]})
})
service.get('/users/:id', async (req, res) => {
const user = await db.findById(req.params.id)
if (!user) {
res.statusCode = 404
return res.send('Not found')
}
res.send(user)
})
const nestedRouter = service.newRouter()
nestedRouter.get('/hello', (req, res) => {
res.send('Hello World!')
})
// Mount under /v1
service.use('/v1', nestedRouter)
// Global logger
service.use((req, res, next) => {
console.log(`${req.method} ${req.url}`)
return next()
})
// Route-level auth
service.get('/admin', auth, (req, res) => {
res.send('Welcome, admin')
})
Core Capabilities
Everything you need, nothing you don't.
1. HTTP Routing
restana supports all standard HTTP methods with a clean, chainable API.
- GET, DELETE, PUT, PATCH, POST, HEAD, OPTIONS — plus
service.all()for universal handlers - TRACE is disabled by default (re-enable with
enableTrace: true) - Route matching uses an internal LRU cache —
routerCacheSizecontrols cache depth (default: 2000)
2. The res.send() Method
One method handles every response type. No res.json(), res.text(), or res.stream() needed.
null/undefined— empty responseBoolean— application/jsonString— text/plainBuffer— application/octet-streamObject— application/jsonStream— piped with graceful error handlingPromise— resolved recursively (depth cap: 3)
Full signature: res.send(data, statusCode, headers, callback). You can also send just a status code: res.send(401).
3. Middleware Support
All middlewares using the (req, res, next) signature are compatible — including Express middleware from npm.
Global Middleware
Applies to every route. Use for logging, CORS, authentication.
Prefix Middleware
Scoped to a path prefix. service.use('/admin', authMiddleware)
Route-Level Middleware
Multiple callbacks per route, including arrays of middleware functions.
Async Middleware (v3.3+)
Full async/await support. Catch uncaught exceptions in the request processing flow with try/catch wrappers.
4. Custom Servers & Events
Server-agnostic. Use standard http.Server, https.Server, or your own implementation.
service.start(port)— returns a Promise with the server instanceservice.close()— graceful shutdownservice.callback()— standard(req, res)handler for third-party integrationsservice.events.BEFORE_ROUTE_REGISTER— hook into route registration
Get Started
One command and you're running.
Configuration Options
Pass an options object to restana(config) — everything is optional.
| Option | Description | Default |
|---|---|---|
| server | Custom HTTP server instance | http.createServer() |
| prioRequestsProcessing | Use setImmediate for priority processing | true |
| defaultRoute | Handler for unmatched routes (404) | res.send(404) |
| errorHandler | Global error handler function | Safe by default |
| routerCacheSize | Route match cache size | 2000 |
| enableTrace | Enable TRACE HTTP method | false |
| securityHeaders | Set default security headers on every response | true |
| trustProxy | Trust forwarded protocol for HSTS | false |
| debugErrors | Expose local error details (never in production) | false |
const service = restana({
errorHandler(err, req, res) {
console.error(`Error: ${err.message}`)
res.send({ error: 'Internal Server Error' }, 500)
}
})
const https = require('https')
const fs = require('fs')
const service = restana({
server: https.createServer({
key: fs.readFileSync('key.pem'),
cert: fs.readFileSync('cert.pem')
})
})
service.start(443)
const service = restana({
defaultRoute(req, res) {
res.statusCode = 404
res.send({ path: req.url, error: 'Not Found' })
}
})
const service = restana({
routerCacheSize: 0 // disable LRU cache
})
// Or: unlimited cache (useful for many static routes)
// routerCacheSize: -1
const service = restana({
enableTrace: true
})
service.trace('/debug', (req, res) => {
res.send('Echo: ' + req.url)
})
// ⚠️ Not recommended in production
const service = restana({
securityHeaders: false
})
// Use when you manage headers yourself
// (e.g. with Helmet or for non-browser clients)
const service = restana({
trustProxy: true
})
// Enable only when your proxy replaces
// client-supplied forwarded headers.
const service = restana({
debugErrors: process.env.NODE_ENV === 'development'
})
// Production always masks error details.
Deploy Anywhere
restana works wherever Node.js runs — from serverless functions to dedicated servers.
☁️ AWS Lambda
Compatible with serverless-http. Wrap your service in a single handler and deploy as a Lambda function.
🔥 Cloud Functions for Firebase
Use service.callback() with functions.https.onRequest() for zero-config Firebase deployment.
📊 Elastic APM
Built-in routes naming plugin for Elastic APM. Instrument your service with restana/libs/elastic-apm.
📈 New Relic APM
Built-in routes naming plugin for New Relic. Attach before registering routes with restana/libs/newrelic-apm.
📄 Swagger / OpenAPI
Validate requests against OpenAPI specs with restana-swagger-validator. Available on npm.
📁 Static Files
Serve static assets with restana-static — a dedicated Docker container for frontend serving.