The plugin-first framework
for building Deno APIs
A plugin-first HTTP framework for Deno. Every route, middleware, and service is a plugin with its own lifecycle, and the same app runs unchanged on Bun, Cloudflare Workers, and Node.js.
$ deno add jsr:@codexa/coreA plugin owns everything it needs
A route, a middleware, a background job, all of it lives inside setup(scope). Another plugin can only reach it through dependsOn and exposeService, so a large application stays predictable as more plugins are added.
import { createApp, definePlugin } from '@codexa/core/http'
const healthPlugin = definePlugin({
name: 'health',
setup(scope) {
scope.route({
method: 'GET',
path: '/health',
handler: (ctx) => ctx.json({ ok: true }),
});
},
});
const app = createApp('api').install(healthPlugin);
// runs the same way on Deno, Bun, and Workers
Deno.serve(app.dispatch);One package, sixteen focused subpaths
Import only what a project uses. A route-only service never loads the MongoDB driver or the Redis client.
Built as small, composable pieces
Every part of the framework is designed to be used on its own or combined into a full backend.
Plugin-first architecture
Every route, middleware, and background job is owned by a plugin with its own name, lifecycle hooks, and metadata.
Typed service exposure
A plugin only reaches another through dependsOn and exposeService, so a growing app stays predictable instead of tangled.
Runtime-neutral dispatch
app.dispatch is a plain (Request) => Promise<Response> function. The same app runs on Deno, Bun, Cloudflare Workers, and Node.js.
Real OpenAPI 3.1 documents
Generate a spec straight from your route metadata, no separate annotation layer or schema duplication.
One storage interface, four providers
Local disk, S3, Cloudinary, and ImageKit behind the same upload, delete, and signed-URL API.
Local or distributed event bus
Start in-process with zero setup, then hand it a Redis client to make emit cross-process without changing call sites.
Radix tree router
Static, param, and wildcard routes resolve through a radix tree, with versioned routes and per-route middleware built in.
A CLI for plugin distribution
Pull a plugin’s source from a pinned Git ref into your project, with full rollback if any step fails.
Faster than Oak and Express
A GET request measured with the same 50-connection load test across frameworks. Full methodology, all three endpoints, and raw Deno.serve as a baseline are in the benchmarks docs.
Three steps to a running server
Define a plugin
A plugin registers everything it owns, routes, middleware, services, in one setup function.
definePluginInstall it into an app
createApp takes as many plugins as your app needs, each isolated behind its own name.
createApp().install(plugin)Ship app.dispatch anywhere
Hand dispatch to Deno.serve, Bun.serve, a Cloudflare Worker, or call it directly in a test.
Deno.serve(app.dispatch)Build your first plugin in three minutes
Published on JSR at @codexa/core, with a JSR score of 100 percent and support confirmed for Deno, Node.js, Bun, and browsers.