# How to Contribute to Cordis: Complete Guide to the Monorepo Workflow

> Contribute to Cordis with our complete monorepo workflow guide. Fork, install dependencies, code in packages, test with Vitest, and submit a pull request to join the project.

- Repository: [Cordiverse/cordis](https://github.com/cordiverse/cordis)
- Tags: how-to-guide
- Published: 2026-09-13

---

**To contribute to Cordis, fork the repository, install dependencies using Yarn Berry, implement changes within the appropriate package under `packages/`, verify your work with the Vitest test suite, and open a pull request targeting the `main` branch.**

Cordis is a **meta-framework for spatiotemporal composability** maintained under the `cordiverse` organization on GitHub. The project lives in a monorepo that organizes functionality into discrete packages. Familiarity with this architecture allows contributors to add code efficiently and ensure tests land in the correct locations.

## Understanding the Cordis Monorepo Structure

The repository splits functionality across several logical packages. Each package maintains its own source entry point under `src/` and corresponding tests under `tests/`.

### Core Runtime and Plugin System

**`@cordis/core`** provides the runtime, event system, fiber handling, and public API. The primary entry point is [[`packages/core/src/index.ts`](https://github.com/cordiverse/cordis/blob/main/packages/core/src/index.ts)](https://github.com/cordiverse/cordis/blob/main/packages/core/src/index.ts), with tests located at [`packages/core/tests/**/*.spec.ts`](https://github.com/cordiverse/cordis/tree/main/packages/core/tests).

**`@cordis/loader`** handles dynamic plugin loading for both CommonJS and ES modules, isolating plugins at runtime. Source code resides in [[`packages/loader/src/index.ts`](https://github.com/cordiverse/cordis/blob/main/packages/loader/src/index.ts)](https://github.com/cordiverse/cordis/blob/main/packages/loader/src/index.ts), with tests at [`packages/loader/tests/**/*.spec.ts`](https://github.com/cordiverse/cordis/tree/main/packages/loader/tests).

### Utilities and CLI Tools

**`@cordis/timer`** manages timed callbacks and heartbeat loops. Access the source at [[`packages/timer/src/index.ts`](https://github.com/cordiverse/cordis/blob/main/packages/timer/src/index.ts)](https://github.com/cordiverse/cordis/blob/main/packages/timer/src/index.ts).

**`@cordis/logger-console`** implements the default console logging backend. Modify this package at [[`packages/logger-console/src/index.ts`](https://github.com/cordiverse/cordis/blob/main/packages/logger-console/src/index.ts)](https://github.com/cordiverse/cordis/blob/main/packages/logger-console/src/index.ts).

**`@cordis/create`** powers the CLI scaffolding tool invoked via `cordis create`. The generator logic lives in [[`packages/create/src/index.ts`](https://github.com/cordiverse/cordis/blob/main/packages/create/src/index.ts)](https://github.com/cordiverse/cordis/blob/main/packages/create/src/index.ts), while CLI argument parsing resides in [`packages/create/src/bin.ts`](https://github.com/cordiverse/cordis/blob/main/packages/create/src/bin.ts).

**`@cordis/include`** processes YAML-based plugin inclusion configurations. Source files are in [[`packages/include/src/index.ts`](https://github.com/cordiverse/cordis/blob/main/packages/include/src/index.ts)](https://github.com/cordiverse/cordis/blob/main/packages/include/src/index.ts).

**`@cordis/group`** provides logical namespace grouping for plugins. The entry point is [[`packages/group/src/index.ts`](https://github.com/cordiverse/cordis/blob/main/packages/group/src/index.ts)](https://github.com/cordiverse/cordis/blob/main/packages/group/src/index.ts).

## Step-by-Step Workflow to Contribute to Cordis

### Setting Up Your Development Environment

Clone your fork and enable the correct package manager:

```bash
git clone https://github.com/<your-username>/cordis.git
cd cordis
corepack enable
yarn install

```

Build specific packages if needed:

```bash
yarn workspace @cordis/core build

```

Run the full Vitest suite to establish a baseline:

```bash
yarn test

```

### Making and Testing Changes

Create a feature branch and implement your modifications:

```bash
git checkout -b my-feature

```

Keep changes localized to the relevant `packages/<name>/` directory. Follow the existing ESLint configuration at the repository root and maintain TypeScript strictness. Add or update unit tests in the corresponding `packages/<name>/tests/` folder.

Verify type safety and code style:

```bash
yarn lint
yarn tsc --noEmit
yarn test

```

### Submitting Your Contribution

Commit your changes and push to your fork. Open a pull request against the `main` branch, completing the PR template and linking related issues (e.g., "Closes #42"). Address reviewer feedback promptly. The GitHub Actions CI pipeline must report all checks green before maintainers merge.

## Practical Examples: Contributing Code

### Creating a New Plugin

To add a plugin that logs every second, create a file using the `definePlugin` API from `@cordis/core`:

```typescript
// plugins/hello-world.ts
import { definePlugin } from '@cordis/core';

export default definePlugin('hello-world', (ctx) => {
  ctx.timer.setInterval(() => console.log('tick'), 1000);
});

```

Test the plugin locally:

```typescript
import { createApp } from '@cordis/core';
import helloWorld from '../plugins/hello-world';

const app = createApp();
app.plugin(helloWorld);
app.start();

```

Add corresponding tests in [`packages/loader/tests/hello-world.spec.ts`](https://github.com/cordiverse/cordis/blob/main/packages/loader/tests/hello-world.spec.ts) to assert timer behavior.

### Extending the CLI Generator

To add a new scaffold option in `@cordis/create`, modify [[`packages/create/src/index.ts`](https://github.com/cordiverse/cordis/blob/main/packages/create/src/index.ts)](https://github.com/cordiverse/cordis/blob/main/packages/create/src/index.ts):

```typescript
export async function generateProject(options: CreateOptions) {
  if (options.useConsoleLogger) {
    pkg.dependencies['@cordis/logger-console'] = '^1.0.0';
  }
  // existing generation logic
}

```

Update CLI flags in [`packages/create/src/bin.ts`](https://github.com/cordiverse/cordis/blob/main/packages/create/src/bin.ts) and the help text to expose the new option.

## Summary

- **Fork and clone** the `cordiverse/cordis` repository, then run `corepack enable && yarn install` to configure Yarn Berry.
- **Locate the correct package** under `packages/` (core, loader, timer, logger-console, create, include, or group) for your specific contribution.
- **Run tests** using `yarn test` (Vitest) and ensure type safety with `yarn tsc --noEmit` before committing.
- **Submit PRs** against the `main` branch with complete test coverage and adherence to ESLint rules.

## Frequently Asked Questions

### Do I need to build packages before running tests?

No. While you can build individual packages with `yarn workspace @cordis/core build`, most scripts compile on-the-fly during development. Running `yarn test` executes Vitest across the monorepo without requiring a manual build step.

### Which package should I modify for timer-related features?

Implement timer logic in **`@cordis/timer`**. The source resides at [`packages/timer/src/index.ts`](https://github.com/cordiverse/cordis/blob/main/packages/timer/src/index.ts) and provides utilities for `setInterval` and heartbeat loops used throughout the framework.

### How do I test plugin loading mechanisms?

Add specs in `packages/loader/tests/`. The loader package handles dynamic imports and isolation for both CommonJS and ES modules. Use the `createApp` function from `@cordis/core` to bootstrap test applications that load your plugin.

### What coding standards does Cordis enforce?

The repository uses **TypeScript** with strict type checking and **ESLint** configuration at the root. Run `yarn lint` to check style and `yarn tsc --noEmit` to verify types. All contributions must include unit tests in the corresponding `packages/<name>/tests/` directory.