@web-ts-toolkit/access-router-runtime
Config-driven wrapper around @web-ts-toolkit/access-router and @web-ts-toolkit/express-runtime.
This package is for the case where you want the generated resource REST API from access-router, but you do not want to hand-wire:
- Mongoose model registration
- global
access-routeroptions - root and OpenAPI routers
- Express app setup
- local dev vs. serverless runtime entry modules
Instead, you describe the API in one TypeScript config file and let the package assemble the app and CLI entrypoints.
Installation
- npm
- Yarn
- pnpm
- Bun
npm install @web-ts-toolkit/access-router-runtime @web-ts-toolkit/access-router @web-ts-toolkit/express-runtime express mongoose
yarn add @web-ts-toolkit/access-router-runtime @web-ts-toolkit/access-router @web-ts-toolkit/express-runtime express mongoose
pnpm add @web-ts-toolkit/access-router-runtime @web-ts-toolkit/access-router @web-ts-toolkit/express-runtime express mongoose
bun add @web-ts-toolkit/access-router-runtime @web-ts-toolkit/access-router @web-ts-toolkit/express-runtime express mongoose
What It Exposes
Main entrypoint:
defineRuntimeConfig(...)createAccessRouterRuntime(config)createAccessRouterRuntimeApp(config)createAccessRouterRuntimeServerlessHandler(config, options?)loadAccessRouterRuntime(path, options?)loadAccessRouterRuntimeConfigSync(path)
Published extras:
@web-ts-toolkit/access-router-runtime/tsconfig.jsonfor a reusable strict TypeScript config base when authoring runtime config modules
CLI binary:
wtt-access-router-runtime devwtt-access-router-runtime buildwtt-access-router-runtime startwtt-access-router-runtime build-serverlesswtt-access-router-runtime start-serverless
Quick Start
import mongoose from 'mongoose';
import { defineRuntimeConfig } from '@web-ts-toolkit/access-router-runtime';
const OPEN_ACCESS = { list: true, read: true, create: true, update: true, delete: true } as const;
const UserSchema = new mongoose.Schema({
name: { type: String, required: true },
role: { type: String, default: 'user' },
});
export default defineRuntimeConfig({
db: {
url: process.env.MONGODB_URI,
},
globalOptions: {
globalPermissions() {
return [];
},
},
models: [
{
name: 'User',
schema: UserSchema,
router: {
basePath: '/api/users',
operationAccess: OPEN_ACCESS,
permissionSchema: {
name: OPEN_ACCESS,
role: OPEN_ACCESS,
},
},
customRoutes: [
{
method: 'get',
path: '/:id/profile',
handler: async (req) => ({ id: req.params.id, profile: true }),
},
],
},
],
rootRouter: {
basePath: '/api/root',
operationAccess: true,
},
openApi: {
title: 'Example API',
version: '1.0.0',
jsonPath: '/api/openapi.json',
},
});
For a fuller in-repo starter, see packages/access-router-runtime/examples/basic/access-router.config.ts.
CLI
The runtime CLI mirrors the express-runtime commands, but starts from a config file instead of a hand-wired app module.
Local dev
wtt-access-router-runtime dev ./src/access-router.config.ts --env .env --port 3000
Build a local runtime bundle
wtt-access-router-runtime build ./src/access-router.config.ts --out-dir dist
Build a serverless bundle
wtt-access-router-runtime build-serverless ./src/access-router.config.ts --out-dir netlify/functions
Start built artifacts
These are pass-through wrappers to wtt-express-runtime:
wtt-access-router-runtime start ./dist/app.js --port 3000
wtt-access-router-runtime start-serverless ./netlify/functions/handler.js --port 9000
Relationship To The Lower-Level Packages
access-router-runtime does not replace the two core packages. It composes them.
@web-ts-toolkit/access-routerstill owns router generation, permissions, hooks, validation, and OpenAPI metadata.@web-ts-toolkit/express-runtimestill owns the Express app factory, local server lifecycle, serverless wrapper, and bundling CLI behavior.@web-ts-toolkit/access-router-runtimeadds a config layer so those two packages can be used with less application boilerplate.
If you want full low-level control over app wiring, use the two core packages directly. If your API is mostly generated model/data/root routes, this package is the shorter path.
Loading A Runtime Instance
If you want a fully constructed runtime from a config file path, use loadAccessRouterRuntime(...) instead of loading the config and wiring the runtime separately.
import { loadAccessRouterRuntime } from '@web-ts-toolkit/access-router-runtime';
const runtime = loadAccessRouterRuntime('./src/access-router.config.ts');
export const app = runtime.app;
export const handler = runtime.createServerlessHandler();
Programmatic Runtime Creation
If your app already owns the config object in code, create the runtime directly:
import config from './access-router.config';
import { createAccessRouterRuntime } from '@web-ts-toolkit/access-router-runtime';
const runtime = createAccessRouterRuntime(config);
export const app = runtime.app;
export const handler = runtime.createServerlessHandler();
TypeScript Config Helper
The package also publishes @web-ts-toolkit/access-router-runtime/tsconfig.json.
Use it when you want a small shared baseline for runtime-config files:
{
"extends": "@web-ts-toolkit/access-router-runtime/tsconfig.json"
}
Config Shape
The config object can describe:
db: MongoDB connection URL andmongoose.connect(...)optionsglobalOptions: globalaccess-routeroptionsdefaultModelOptions: shared model-router defaultsmodels: model-backed resource routers fromschemaor existingmodelmodels[].customRoutes: extra model-scoped routes mounted through the model router'sJsonRouterdata: in-memory data routersrootRouter: grouped root batch routeopenApi: generated JSON and Swagger UI routesextraRoutes: extra Express/access-router routes to mount alongside generated routersexpress: Express middleware, parser, and error-handler optionsinit/shutdown: runtime lifecycle hooks
Model definitions can use either:
model: an already-created Mongoose modelschema: a schema plusname, so the runtime registers the model for you
Model definitions can also include customRoutes when you need model-specific endpoints alongside the generated CRUD routes.
customRoutes[].pathis relative to the model routerbasePathcustomRoutes[].methodsupportsall,get,post,put,patch,delete,head, andoptionscustomRoutes[].handleruses@web-ts-toolkit/express-json-routersemantics, so returning plain data works
Example:
customRoutes: [
{
method: 'get',
path: '/:id/profile',
handler: async (req) => ({ id: req.params.id, profile: true }),
},
];
With basePath: '/api/users', that route mounts at /api/users/:id/profile.
In-Repo Example
A copyable starter config lives in the package source:
packages/access-router-runtime/examples/basic/access-router.config.ts
That example shows one model router, one data router, a root router, OpenAPI setup, a model-level custom route, global permissions, and Express finalize/error handling.
When To Use It
Use access-router-runtime when you want:
- generated resource REST endpoints with minimal application wiring
- one config file as the source of truth for DB, routers, and runtime behavior
- both local and serverless execution without maintaining separate app entry files
- to keep using
access-routeroptions for global, root, model, and data routes
If your app has highly custom Express composition or only uses a small part of access-router, the lower-level packages may still be a better fit.