npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@tomkrcmar/lambda-router

v0.0.6

Published

Abstract route modeling and matching framework with an implementation for AWS Lambda

Readme

@tomkrcmar/lambda-router

npm

A general purpose middleware, route modeling, and route matching framework.

Features:

  • Familiar, express-like interface
  • Nested routers and relative route matching
  • Exact or inexact route matching
  • Route parameter matching
  • Optional routes or route params
  • Extendable, integrate with any server framework like Lambda, express, etc.
  • Comes with an implementation for routing in Lambda functions

Usage:

There is no official documentation, but a good way to see example usage is the unit tests.

Instantiate a Router

import { Router } from '@tomkrcmar/lambda-router';
const router = new Router();

Simple HTTP request

// "get" can also be post, put, patch, delete
router.get('/hello', (req, res) => {
	res.send('Hello, World!');
})

Route parameters

router.get('/thing/:id', (req, res) => {
	const { id } = req.params;
	res.send(`Thing data for thing number ${id}`);
})

Optional route parameters

router.get('/thing/:id?', (req, res) => {
	const { id } = req.params;
	if (id)
		res.send(`Thing data for thing number ${id}`);
	else
		res.send('Thing index for all things');
})

// Regular text routes can also be optional:
router.get('path/to?/something?/maybe?', (req, res) => {
	// This matches path, path/to, path/to/something, and path/to/something/maybe
});

Simple Middleware

router.use((req, res, ctx) => {
	// All 3 arguments have their own `data` property for custom props passed down to subsequent middleware
	req.data.myCustomValueA = 5;
	res.data.myCustomValueB = 6;
	ctx.data.myCustomValueC = 7;

	// Allow subsequent middleware and route matching to continue
	ctx.next();

	// Note: ctx also contains other misc. information about the current router stack and dispatching state.
})

Nested Routers example

const thingRouter = new Router();
thingRouter.get('thing', (req, res) => {
	res.send('Thing data');
})

router.use('/path/to/the', thingRouter);

// At this point, GET /path/to/the/thing will match the handler

Method chaining (set status code, set one header, set multiple headers, send with body)

router.get('/hello', (req, res) => {
	res.status(200)
		.header('Content-type', 'text/plain')
		.setHeaders({
			'X-Header-One': 'ABC',
			'X-Header-Two': '123',
		})
		.send('Hello, World!');
})

CORS middlware example

import { Router } from '@tomkrcmar/lambda-router';

const router = new Router();
export default router;

router.use((req, res, ctx) => {
	res.setHeaders({
		'Access-Control-Allow-Origin': '*',
		'Access-Control-Allow-Methods': 'GET,POST,PUT,PATCH,DELETE',
		'Access-Control-Allow-Credentials': 'true',
		'Access-Control-Allow-Headers': 'Content-Type,Authorization',
	});
	
	if (req.method === 'options')
		res.status(200).send();
	else
		ctx.next();
})

Lambda Handler:

Simply add your routes on a LambdaRouter at the top level and supply it to your handler export in lambda. The rest of your app can be built with Routers and are completely portable, only the top-level router needs to be a LambdaRouter.

There are multiple LambdaRouters available, but the default LambdaRouter will attempt to detect the right version:

  • LambdaRouter - Auto-detect API Gateway API version
  • ApiGatewayLambdaRouter - API Gateway V1 REST APIs
  • ApiGatewayV2LambdaRouter - API Gateway V2 HTTP APIs

Minimal example

import { LambdaRouter } from '@tomkrcmar/lambda-router';
import myAppRouter from './my-app';

export function handler(event, context) {
	return new LambdaRouter().use(myAppRouter).dispatchLambda(event, context);
}

Example of adding our CORS middleware above, and a hello world endpoint directly onto the top-level router:

import { LambdaRouter } from '@tomkrcmar/lambda-router';
import cors from './my-middleware/cors';

const router = new LambdaRouter();

router.use(cors);

router.get('/hello', (req, res) => {
	res.send('Hello, World!');
})

export function handler(event, context) {
	return router.dispatchLambda(event, context);
}

Custom Integration:

In order to integrate your route model into a server framework, there are three steps:

  • Construct a Request
  • Call Router.dispatch(request)
  • Handle the Response

The LambdaRouter above performs all of these steps for you, constructing a Request from your lambda event and context, and converting the Response to the lambda handler response structure that lambda expects.

Minimal example of manually doing this with no conversion:

import { Request, Router } from '@tomkrcmar/lambda-router';

const router = new Router();
router.use('/hello', (req, res) => res.send('Hello, World!'))

const req = new Request();
req.path = '/hello';

const res = await router.dispatch(req);
// res.body should now be populated with 'Hello, World!' with status code 200 and other misc. fields present

Installation

# Install as a runtime dependency
npm install --save @tomkrcmar/lambda-router

# Install as a development dependency if you have your own build or bundling process
npm install --save-dev @tomkrcmar/lambda-router

Building and Testing

Build the module yourself:

npm run build

# Build in watch mode:
npm run build:w

Run unit tests and coverage:

npm run test

# Test in watch mode:
npm run test:w