Skip to main content
Deno 2 is finally here πŸŽ‰οΈ
Learn more

Routup banner

Routup πŸ§™β€

npm version main codecov Known Vulnerabilities Conventional Commits

Routup is a minimalistic, runtime-agnostic HTTP routing framework for Node.js, Bun, Deno, and Cloudflare Workers. Handlers return values directly β€” routup converts them to Web Response objects automatically.

Table of Contents

Installation

npm install routup --save

Features

  • πŸš€ Runtime agnostic β€” Node.js, Bun, Deno, Cloudflare Workers
  • πŸ“ Return-based handlers β€” return strings, objects, streams, or Response directly
  • ✨ Async middleware β€” onion model with event.next()
  • πŸ“Œ Lifecycle hooks β€” request, response, error for cross-cutting concerns
  • πŸ”Œ Plugin system β€” extend with reusable, installable plugins
  • 🧰 Tree-shakeable helpers β€” import only what you use
  • πŸ“ Nestable routers β€” modular route composition
  • πŸ‘• TypeScript first β€” fully typed API with generics
  • 🀏 Minimal footprint β€” small core, no bloat

Documentation

To read the docs, visit https://routup.net

Usage

Handlers

Handlers receive an event and return a value. Routup converts the return value to a Web Response automatically.

Shorthand

import { Router, defineCoreHandler, defineErrorHandler, serve } from 'routup';

const router = new Router();

router.get('/', defineCoreHandler(() => 'Hello, World!'));
router.get('/greet/:name', defineCoreHandler((event) => `Hello, ${event.params.name}!`));
router.use(defineErrorHandler((error) => ({ error: error.message })));

serve(router, { port: 3000 });

Verbose

import { Router, defineCoreHandler, serve } from 'routup';

const router = new Router();

router.use(defineCoreHandler({
    path: '/',
    method: 'GET',
    fn: () => 'Hello, World!',
}));

router.use(defineCoreHandler({
    path: '/greet/:name',
    method: 'GET',
    fn: (event) => `Hello, ${event.params.name}!`,
}));

serve(router, { port: 3000 });

Return Values

Return type Response
string text/plain
object / array application/json
Response Passed through as-is
ReadableStream Streamed to client
Blob Sent with blob’s content type
null Empty response (status from event.response)

Middleware

Middleware calls event.next() to continue the pipeline:

router.use(defineCoreHandler(async (event) => {
    console.log(`${event.method} ${event.path}`);
    return event.next();
}));

Runtimes

Routup runs on Node.js, Bun, Deno, and Cloudflare Workers. In most cases, import from routup:

import { Router, defineCoreHandler, serve } from 'routup';

const router = new Router();
router.get('/', defineCoreHandler(() => 'Hello, World!'));
serve(router, { port: 3000 });

For runtime-specific APIs (e.g. toNodeHandler), use the corresponding entrypoint like routup/node.

Plugins

Routup is minimalistic by design. Plugins extend the framework with additional functionality.

Name Description
assets Serve static files from a directory
basic Bundle of body, cookie, and query plugins
body Read and parse the request body
cookie Read and parse request cookies
decorators Class, method, and parameter decorators
prometheus Collect and serve Prometheus metrics
query Parse URL query strings
rate-limit Rate limit incoming requests
rate-limit-redis Redis adapter for rate-limit
swagger Serve Swagger/OpenAPI docs

Benchmarks

Note: These benchmarks were recorded with routup v4 (Node.js 18, Sep 2023). Updated v5 benchmarks will follow.

Package Requests/s Latency (ms) Throughput/MB
http 61062 15.87 10.89
fastify 59679 16.26 10.70
koa 45763 21.35 8.16
routup 44588 21.91 9.02
hapi 41374 23.67 7.38
express 13376 74.18 2.39

To run benchmarks yourself, see the benchmarks repository.

Contributing

Before starting to work on a pull request, it is important to review the guidelines for contributing and the code of conduct. These guidelines will help to ensure that contributions are made effectively and are accepted.

License

Made with πŸ’š

Published under MIT License.