Tweaked for high throughput, low overhead, and maximum flexibility. The router that doesn't get in your way — now with a dependency-free trie engine that resolves static routes in ~80ns.
A framework designed for developers who want speed without ceremony.
One of the fastest Node.js web frameworks. The new trie router resolves static routes in ~80ns and keeps dynamic routes flat as your API grows — no regex per route, no cache to size.
Swap routers, servers, and customize every behavior. You're in full control of the stack.
Express-like chain with full async/await support. Global or route-specific — your call.
Three runtime dependencies. Zero bloat. Every line is optimized for raw throughput — smaller surface, fewer vectors, more speed.
Modular architecture with nested routers, on both engines. Mount prefixes are stripped from the path only, so a query string can never become a nested route.
Safe-by-default error handler, prototype pollution protection, and secure routing. Built for the real world.
Everything you need, nothing you don't.
0http lets you define the router implementation you prefer. Three engines are supported out of the box.
A dependency-free segment-trie engine with the same API, middleware chain, nested routers and error containment as the default router. Static routes resolve through a compile-on-demand table in constant time; dynamic routes walk the trie with no regex per route, so lookup cost stays flat whether you register 5 routes or 500.
/static, /:param, /:param?, /:name.ext, trailing /* and RegExp with named groupsrequire('0http/lib/router/trie')()Extended trouter with middleware, nested routers, and regex matching. Uses internal LRU cache for blazing-fast repeated lookups.
Integration with find-my-way, a radix-tree router for maximum static path performance.
Optimized for both performance and flexibility. Global middleware, route-level middleware, and full async/await support — all in a minimal execution loop.
Organize your application with modular nested routers. 0http optimizes static nested routes with direct slicing — zero regex overhead where it counts.
Server-agnostic. Use standard http.Server, https.Server, or your own implementation. 0http just needs an event emitter.
One command and you're running.
$ npm install 0http
Copied!
Common patterns to get you moving fast.
const trie = require('0http/lib/router/trie')
const { router, server } = require('0http')({
router: trie()
})
router.get('/users/:id', (req, res) => {
res.end(req.params.id)
})
router.get('/files/*', (req, res) => {
res.end(req.params['*'])
})
server.listen(3000)
const { router, server } = require('0http')()
router.get('/hello', (req, res) => {
res.end('Hello World!')
})
server.listen(3000)
router.get('/api/users', (req, res) => {
res.setHeader('Content-Type', 'application/json')
res.end(JSON.stringify({
users: [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }]
}))
})
// Global logger
router.use((req, res, next) => {
console.log(`${req.method} ${req.url}`)
return next()
})
// Route-level auth
router.get('/admin', auth, (req, res) => {
res.end('Welcome, admin')
})
router.get('/users/:id', async (req, res) => {
const user = await db.findById(req.params.id)
if (!user) {
res.statusCode = 404
return res.end('Not found')
}
res.setHeader('Content-Type', 'application/json')
res.end(JSON.stringify(user))
})
const { router: api } = require('0http')()
api.get('/users', getUsers)
api.post('/users', createUser)
// Mount at /api
router.use('/api', api)
const { router, server } = require('0http')({
errorHandler: (err, req, res) => {
console.error(err)
res.statusCode = 500
res.end('Internal Server Error')
}
})
router.get('/broken', () => {
throw new Error('Oops!')
})
Pass an options object to zero(config) — everything is optional.
| Option | Description | Default |
|---|---|---|
| router | Custom router instance | sequential() |
| server | Custom server instance | http.createServer() |
| defaultRoute | Handler for 404 Not Found | 404 + res.end() |
| errorHandler | Global error handler | Safe-by-default (v5.0+) |
| prioRequestsProcessing | Use setImmediate for priority processing | true |
| cacheSize | Sequential router: LRU cache size (0=off, <0=unlimited) | −1 |
| caseSensitive | Trie router: match paths case-sensitively | true |
| ignoreTrailingSlash | Trie router: treat /users/ and /users alike | true |