CodexaCodexa

Overview

How a Codexa Core application is created, started, and stopped, and the rules that govern plugin installation.

An application starts with createApp, which returns an object you install plugins into. Nothing runs until the app is booted, either explicitly or on its first request.

What the HTTP module gives you

import { createApp } from '@codexa/core/http';

const app = createApp('orders-api');

The name passed to createApp is optional. Use it to tell multiple apps apart in logs, in a process that runs more than one.

Installing plugins

install accepts a plugin and, if the plugin declares a config type, a matching config value as the second argument.

import { ordersPlugin } from './plugins/orders.ts';
import { paymentsPlugin } from './plugins/payments.ts';

const app = createApp('orders-api')
  .install(ordersPlugin)
  .install(paymentsPlugin, { provider: 'stripe' });

install enforces a handful of rules around naming, install order, and dependsOn, all checked immediately rather than deferred to boot time, covered in full on the Plugins page. The short version: a plugin name is unique, dependencies must already be installed before the plugin that needs them, and setup(scope, config) must run synchronously, never async.

Starting and stopping

await app.boot();

Deno.serve(app.dispatch);

// later, during shutdown
await app.shutdown();
await app.whenStopped();
  • boot() runs any async setup you passed it, compiles the route table, and moves the app into the ready phase. Calling it more than once is safe, since it returns the same result every time.
  • dispatch is the request handler. It boots the app automatically on its first call if nothing has booted it yet.
  • shutdown() runs every registered shutdown hook and stops the app from accepting new work.
  • whenStopped() resolves once shutdown has fully finished. Use it when something other than your own code triggers shutdown(), such as a process signal handler, and your entry point needs to wait for cleanup before the process exits.

The full request handling path, including how a route is matched and how hooks fire around it, is covered in Dispatch & Lifecycle.

Reading the app back

A handful of read only methods let you check what is installed, without touching the request path.

app.hasPlugin('orders');
app.hasService('orders', 'createOrder');
app.installedPlugins();
app.getPhase();
app.size;

getPhase() returns one of idle, booting, ready, shutting_down, or stopped, useful for guarding an async installer function against running after shutdown has already started. size returns the number of routes currently registered.

What else an app exposes

Beyond install, boot, dispatch, and shutdown, the app carries the same response helpers available on ctx, service access through getService and getServices, tag based inspection, and app level hooks.

On this page