How to Create a New Cordis Context: Instantiation and Configuration Guide

To create a new Cordis context, instantiate the Context class from @cordis/core using new Context(), which initializes a reactive proxy environment with built-in services and lifecycle management.

The cordiverse/cordis framework uses the Context class as the central runtime container for managing services, events, and plugins. When you create a new Cordis context, you establish a self-contained execution environment that supports reactive property access and hierarchical service isolation. This guide walks through the instantiation process based on the actual source implementation in the Cordis repository.

Basic Context Instantiation

To create a new Cordis context, import the Context class and call its constructor:

import { Context } from '@cordis/core'
const ctx = new Context()

This single line initializes a complete runtime environment. According to the source code in packages/core/src/context.ts (lines 36-48), the constructor performs several critical setup operations internally before returning the instance.

Internal Initialization Steps

When you invoke new Context(), the constructor executes a specific sequence defined in the source:

  1. Initializes isolation and intercept maps to support scoped service lookups and configuration overrides.
  2. Wraps the instance in a Proxy using ReflectService.handler to enable reactive features.
  3. Stores a root context reference by setting this.root = self, establishing the hierarchy root.
  4. Creates a Fiber that manages disposal and asynchronous effects through packages/core/src/fiber.ts.
  5. Instantiates core services including ReflectService, RegistryService, EventsService, and LoggerService.

After these steps complete, the context is ready to register plugins, handle effects, and manage service lifecycles.

Extending Contexts with Custom Properties

You can create child contexts that inherit from a parent while adding custom properties using the extend method:

const child = ctx.extend({ foo: 'bar' })
console.log(child.foo) // → 'bar'

This approach creates a new context that maintains the parent's service registry while overlaying additional properties. The extended context shares the same root but can carry its own isolated state for specific plugin scopes.

Isolating Sub-Contexts for Scoped Plugins

For scenarios requiring strict separation of service instances, use the isolate method to create a shadow context with a unique isolation label:

const isolated = ctx.isolate('myIsolate')

The isolated context receives its own isolation map, preventing service lookups from leaking into parent scopes. This mechanism, implemented in the core context logic, is essential for sandboxing plugins or creating tenant-specific environments within the same application.

Intercepting and Configuring Services

You can override built-in service configurations at context creation time using the intercept method:

const intercepted = ctx.intercept('logger', { level: 'debug' })

This creates a new context where the logger service operates with modified parameters without affecting the parent context's configuration. The intercept mechanism works through the internal intercept map initialized during construction.

Using Contexts in Plugins

Once created, contexts serve as the primary argument to plugin functions:

ctx.plugin(async (ctx) => {
  ctx.logger.info('plugin loaded')
})

The plugin receives the context instance and can access all registered services including the event system (packages/core/src/events.ts), registry (packages/core/src/registry.ts), and reflection utilities (packages/core/src/reflect.ts).

Summary

  • Import Context from @cordis/core and call new Context() to create a new Cordis context with full service support.
  • The constructor initializes five core components: isolation maps, reactive proxy wrapping, root reference assignment, Fiber creation, and core service instantiation.
  • Extend contexts using ctx.extend() to add custom properties while maintaining service inheritance.
  • Isolate contexts using ctx.isolate() to create sandboxed environments with separate service lookups.
  • Intercept services using ctx.intercept() to override configurations without mutating parent contexts.
  • Key source files include packages/core/src/context.ts for the main class, packages/core/src/fiber.ts for lifecycle management, and packages/core/src/reflect.ts for proxy handling.

Frequently Asked Questions

What is the difference between ctx.extend() and ctx.isolate() in Cordis?

ctx.extend() creates a child context that inherits all services and properties from the parent while allowing you to add custom properties. ctx.isolate() creates a shadow context with a separate isolation label, giving it its own service lookup map that prevents inheritance from parent scopes. Use extend for adding data, and isolate for creating strict service boundaries.

How does the Cordis Context constructor manage lifecycle and disposal?

The constructor creates a Fiber instance (managed in packages/core/src/fiber.ts) that drives the context's lifecycle, handling asynchronous effects and disposal operations. This Fiber ensures that when a context is disposed, all associated resources, event listeners, and service instances are properly cleaned up through coordinated teardown logic.

Can I create a Cordis context without the default core services?

No, the Context constructor always instantiates the four core services (ReflectService, RegistryService, EventsService, LoggerService) as defined in packages/core/src/context.ts lines 36-48. These services are essential for the reactive proxy system, service registration, event handling, and logging functionality. However, you can override their configurations using ctx.intercept() to customize behavior.

What is the role of the Proxy wrapper in a new Cordis context?

The Proxy wrapper (applied via ReflectService.handler during initialization) enables the reactive property access system that allows Cordis to track service dependencies and trigger updates when service states change. This mechanism, defined in packages/core/src/reflect.ts, is what makes the context's property access interceptable and enables the framework's dependency injection capabilities.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →