# What Internal Events Are Emitted by the Cordis Framework? Complete Reference Guide

> Discover the eight internal events emitted by the Cordis framework, including plugin lifecycle and service registration. Understand Cordis event coordination with this complete reference.

- Repository: [Cordiverse/cordis](https://github.com/cordiverse/cordis)
- Tags: api-reference
- Published: 2026-08-24

---

**Cordis emits eight internal events—including `internal/plugin`, `internal/status`, and `internal/service`—to coordinate plugin lifecycle, service registration, and configuration updates through the `EventsService` class according to the `cordiverse/cordis` source code.**

Cordis defines a specialized set of **internal events** that power the framework's core orchestration layer. These events, declared in the `Events` interface of the core package, enable the system to manage plugin lifecycles, track status changes, and handle service registration. While plugin authors typically interact with the public API, understanding these internal events emitted by the Cordis framework provides deep insight into its event-driven architecture.

## What Are Cordis Internal Events?

Cordis internal events are framework-level hooks defined in [`packages/core/src/events.ts`](https://github.com/cordiverse/cordis/blob/main/packages/core/src/events.ts) that coordinate core operations. Unlike public plugin events, these are emitted by the framework itself through the `EventsService` class to manage internal state transitions.

The `Events` interface declares these events at lines 69-78, providing TypeScript definitions that ensure type safety when emitting or listening to lifecycle changes. These events use the `internal/` namespace to distinguish them from user-defined plugin events.

## Complete List of Internal Events Emitted by Cordis

The Cordis framework emits eight distinct internal events, each serving a specific coordination purpose:

### internal/plugin

Emitted when a plugin is loaded, receiving the plugin's `Fiber` instance. This event fires during the initialization phase in [`packages/core/src/fiber.ts`](https://github.com/cordiverse/cordis/blob/main/packages/core/src/fiber.ts), allowing the framework to track active plugin instances.

### internal/status

Triggered when a plugin's status changes, providing both the `Fiber` instance and its previous `FiberState`. This enables the framework to manage state transitions and cleanup operations.

### internal/service

Fired when a service is added to a `Context`, passing the service name and value. The [`packages/core/src/service.ts`](https://github.com/cordiverse/cordis/blob/main/packages/core/src/service.ts) file triggers this event during service registration to notify the dependency injection system.

### internal/update

Emitted during configuration updates, allowing listeners to intercept and modify the update flow. The callback receives the config object, a `noSave` flag, and a `next` function to continue processing.

### internal/get

Triggered when a property is accessed on a `Context`, enabling custom getter logic. This supports the proxy-based property access system.

### internal/set

Emitted when a property is set on a `Context`, allowing custom setter behavior and validation before assignment.

### internal/listener

Fired when a listener is registered via `ctx.on()` or `ctx.once()`. The framework uses this internally to handle special-case listeners, such as those monitoring configuration updates.

### internal/dispatch

Emitted whenever any event is dispatched, providing metadata including the dispatch mode, event name, arguments, and optional `this` argument. This serves as a meta-event for monitoring the event system itself.

## How Internal Events Are Implemented

The event dispatching mechanism centers on the `EventsService` class defined in [`packages/core/src/events.ts`](https://github.com/cordiverse/cordis/blob/main/packages/core/src/events.ts). This service resolves listeners and executes them through several dispatch strategies:

- **`emit`**: Standard synchronous emission
- **`parallel`**: Concurrent execution of listeners
- **`serial`**: Sequential execution awaiting each listener
- **`bail`**: Stops at the first non-undefined return value
- **`waterfall`**: Passes return values between listeners

The `Context` class in [`packages/core/src/context.ts`](https://github.com/cordiverse/cordis/blob/main/packages/core/src/context.ts) exposes these methods (`emit`, `parallel`, `serial`, `bail`, `waterfall`, `on`, `once`) as the public API, routing all calls through the underlying `EventsService`. When `ctx.emit()` is called, it ultimately triggers `internal/dispatch` before executing the target listeners.

## Practical Examples: Listening to Internal Events

While primarily intended for framework internals, developers can listen to these events for debugging or advanced extension:

```typescript
import { Context } from 'cordis'

// Monitor plugin loading
ctx.on('internal/plugin', (fiber) => {
  console.log('Plugin loaded with fiber:', fiber.id)
})

// Track status transitions
ctx.on('internal/status', (fiber, oldState) => {
  console.log(`Plugin ${fiber.id} changed from ${oldState} → ${fiber.state}`)
})

// Intercept configuration updates
ctx.on('internal/update', (config, noSave, next) => {
  config.customFlag = true
  next() // Continue the update flow
})

```

### Accessing Context Properties

The `internal/get` and `internal/set` events enable custom property behavior:

```typescript
ctx.on('internal/get', (name, value) => {
  console.log(`Property ${name} accessed, current value:`, value)
})

ctx.on('internal/set', (name, value) => {
  console.log(`Property ${name} set to:`, value)
})

```

## Key Source Files

The internal event system spans several core files in the `cordiverse/cordis` repository:

| File | Description |
|------|-------------|
| [`packages/core/src/events.ts`](https://github.com/cordiverse/cordis/blob/main/packages/core/src/events.ts) | Declares the `Events` interface and implements `EventsService` for event dispatching |
| [`packages/core/src/context.ts`](https://github.com/cordiverse/cordis/blob/main/packages/core/src/context.ts) | Extends `Context` with public methods (`emit`, `on`, `once`, etc.) that route through `EventsService` |
| [`packages/core/src/fiber.ts`](https://github.com/cordiverse/cordis/blob/main/packages/core/src/fiber.ts) | Manages plugin `Fiber` lifecycles and triggers `internal/plugin` and `internal/status` events |
| [`packages/core/src/service.ts`](https://github.com/cordiverse/cordis/blob/main/packages/core/src/service.ts) | Registers services and fires `internal/service` during dependency injection |

## Summary

- Cordis emits **eight internal events** prefixed with `internal/` to coordinate framework operations.
- The `Events` interface in [`packages/core/src/events.ts`](https://github.com/cordiverse/cordis/blob/main/packages/core/src/events.ts) defines these event signatures at lines 69-78.
- `internal/plugin` and `internal/status` track plugin lifecycle through the `Fiber` class.
- `internal/service` monitors service registration in the dependency injection container.
- `internal/update`, `internal/get`, and `internal/set` enable interception of configuration and property operations.
- The `EventsService` class handles dispatch via strategies including `parallel`, `serial`, `bail`, and `waterfall`.
- While exposed through `ctx.on()`, these events are intended for framework internals and advanced debugging scenarios.

## Frequently Asked Questions

### Can plugin authors use internal events in production code?

While technically accessible via `ctx.on()`, internal events are designed for framework-level coordination rather than application logic. Plugin authors should use the public API (`ctx.emit`, `ctx.on`) for custom events, as internal events may change between versions of `cordiverse/cordis` without notice.

### How does Cordis handle event listener errors?

The `EventsService` implementation in [`packages/core/src/events.ts`](https://github.com/cordiverse/cordis/blob/main/packages/core/src/events.ts) manages error handling based on the dispatch mode. For `parallel` and `serial` modes, errors typically propagate to the caller, while `bail` stops execution at the first error or return value. The `internal/dispatch` event allows monitoring of all dispatches for error tracking.

### What is the difference between `internal/update` and regular configuration events?

The `internal/update` event fires during the configuration update process itself, allowing listeners to modify the config object before it is saved by calling `next()`. This is lower-level than plugin-defined configuration events and operates on the raw configuration object rather than validated settings.

### Where are the internal event types defined for TypeScript?

All internal event type definitions reside in the `Events` interface within [`packages/core/src/events.ts`](https://github.com/cordiverse/cordis/blob/main/packages/core/src/events.ts), specifically around lines 69-78. This interface maps event names to their handler signatures, ensuring type safety when using `ctx.on('internal/plugin', ...)` or similar listeners.