Simple HTTP Router
router-http is a lightweight (1.3 kB min+gzipped) and performant HTTP router for Node.js, currently at stable version 2.0.6. It aims to provide an Express-like middleware API while offering significantly better and more predictable performance than Express's regex-based router. Unlike Express, router-http utilizes a trie-based routing algorithm, specifically find-my-way, which guarantees near O(1) lookup time regardless of the number of registered routes. This makes it particularly suitable for applications with a large number of routes where consistent performance is critical. The package is actively maintained with frequent dependency updates and recent major version releases, supporting Node.js version 18 and above.
Common errors
-
TypeError: next is not a function
cause A middleware function was declared without the `next` argument or `next()` was called on a non-function.fixEnsure your middleware functions are defined with `(req, res, next)` as parameters, and `next()` is correctly invoked. Example: `router.use((req, res, next) => { /* ... */ next() })`. -
Cannot GET /some/path (or similar HTTP 404 Not Found response)
cause The requested URL path does not match any defined route, or route matching options (case sensitivity, trailing slashes) are causing a mismatch.fixVerify that the route path is correctly defined and matches the incoming request, considering case sensitivity and trailing slashes. Check the `createRouter` options for `caseSensitive` and `ignoreTrailingSlash`. Example: `createRouter(finalHandler, { caseSensitive: false, ignoreTrailingSlash: true })`. -
TypeError: Cannot read properties of undefined (reading 'id') for req.params.id
cause Attempting to access `req.params` for a route that does not have dynamic segments, or the dynamic segment name in the route definition doesn't match the one accessed in `req.params`.fixEnsure your route is defined with dynamic segments (e.g., `/users/:id`) if you intend to access `req.params`. Double-check that the parameter name used in `req.params.name` matches the `:name` in your route definition.
Warnings
- breaking Version 2.0.0 introduced a fundamental shift from a likely regex-based routing engine to a trie-based implementation via `find-my-way`. While the external API aims for compatibility, this change can lead to subtle behavioral differences in route matching, parameter parsing, or route prioritization, especially in complex routing scenarios or edge cases, potentially breaking assumptions made on previous versions.
- gotcha router-http is a CommonJS module, meaning `import` syntax is not natively supported for the package itself without transpilation or specific Node.js configuration (`"type": "module"` in your project's `package.json` and a default CommonJS module would cause issues). The `require()` syntax must be used to load the `createRouter` function.
- gotcha Middleware functions require an explicit `next()` call to pass control to subsequent middleware or the final route handler. Failing to call `next()` will cause the request to hang unless `res.end()` or `res.statusCode` is explicitly set within the middleware.
- breaking The package explicitly requires Node.js version 18 or higher. Running on older Node.js environments will result in errors or unexpected behavior due to unsupported language features or API changes.
Install
-
npm install router-http -
yarn add router-http -
pnpm add router-http
Imports
- createRouter
import createRouter from 'router-http'
const createRouter = require('router-http') - router.get
import { get } from 'router-http'; get('/', (req, res) => { /* ... */ })router.get('/', (req, res) => { /* ... */ }) - MiddlewareFunction
router.use(async (req, res) => { /* ... */ })router.use((req, res, next) => { /* ... */ next() })
Quickstart
const http = require('http')
const createRouter = require('router-http')
const finalHandler = (error, req, res) => {
if (error) {
res.statusCode = error.statusCode || 500
res.end(error.message)
} else {
res.statusCode = 404
res.end('Not Found')
}
}
const router = createRouter(finalHandler, { caseSensitive: false, ignoreTrailingSlash: true })
// Global middleware (runs on every request)
router.use((req, res, next) => {
req.timestamp = Date.now()
next()
})
router
.get('/', (req, res) => res.end(`Hello World at ${req.timestamp}`))
.post('/users', (req, res) => res.end('User created'))
.put('/users/:id', (req, res) => res.end(`User ${req.params.id} updated`))
.delete('/users/:id', (req, res) => res.end(`User ${req.params.id} deleted`))
.all('/ping', (req, res) => res.end('pong'))
const server = http.createServer((req, res) => {
router(req, res)
})
server.listen(3000, () => {
console.log('Server listening on http://localhost:3000')
console.log('Try visiting / or /users/123, or POST to /users')
})