Skip to content

routup/routup

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
  • 🌐 Web-standard APIs — built on Request / Response for portability
  • 📝 Return-based handlers — return strings, objects, streams, or Response directly
  • Async middleware — onion model with event.next()
  • 📌 Lifecycle hooksrequest, 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.

Templates

Scaffold a new project from any starter in routup/templates with degit:

npx degit routup/templates/node-api my-app
Template Runtime Highlights
node-api Node.js >=22 JSON API with @routup/body
cloudflare-worker Cloudflare Workers Configured with wrangler
bun-decorators Bun Class-based routing via @routup/decorators

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
cors Cross-Origin Resource Sharing (CORS) middleware
decorators Class, method, and parameter decorators
i18n Translation and internationalization
logger HTTP request logger with morgan-compatible tokens and presets
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-ui Mount swagger-ui-dist on any path

Comparison

How routup stacks up against other popular Node.js routing frameworks. This is a best-effort summary; check each project's docs for the full picture.

routup Hono Express Fastify
Runtimes Node, Bun, Deno, Cloudflare, Service Worker Node, Bun, Deno, Cloudflare, Lambda, Vercel Node Node
Web-standard Request / Response
Return-based handlers
TypeScript-first community types
Tree-shakeable helpers
Onion middleware (next()) linear next() lifecycle hooks
Class-based routes (decorators) ✅ via plugin
Express middleware bridge fromNodeHandler n/a limited
Per-handler timeout + AbortSignal server-level
Schema validation built-in

Benchmarks

Recorded with routup v5.1 on Node.js 24, May 2026. autocannon -c 100 -d 40 -p 10 (40s warm-up, 40s measure).

Package Requests/s Latency (ms) Throughput/MB
http 167021 5.47 29.79
fastify 152567 6.02 27.35
hono 137181 6.81 22.50
koa 136575 6.79 24.36
hapi 118206 7.99 21.08
express 104533 9.06 18.64
routup 95979 9.93 18.67

Routup currently trails on raw req/s for the trivial GET / case — the focus of v5 has been runtime portability and ergonomics rather than micro-optimization. Throughput is competitive with express. To re-run the suite 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.

Sponsor this project

 

Packages

 
 
 

Contributors