Published on JSR · @codexa/core

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.

16
focused subpaths
4
runtimes supported
100%
JSR score
$ deno add jsr:@codexa/core
Runs wherever the Fetch API runs
DenoBunCloudflare WorkersNode.js

A 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.

Read about plugins
main.ts
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

@codexa/core/http@codexa/core/openapi@codexa/core/config@codexa/core/bus@codexa/core/store@codexa/core/cache@codexa/core/storage@codexa/core/providers@codexa/core/logger@codexa/core/crypto@codexa/core/hash@codexa/core/device@codexa/core/ttl@codexa/core/response@codexa/core/query@codexa/core/cli

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.

Codexa Corefastest
25,134 req/s
Oak (Deno)
20,972 req/s
Express (Node)
13,297 req/s

Three steps to a running server

01

Define a plugin

A plugin registers everything it owns, routes, middleware, services, in one setup function.

definePlugin
02

Install it into an app

createApp takes as many plugins as your app needs, each isolated behind its own name.

createApp().install(plugin)
03

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.