# How to Deploy Cordis Applications: A Complete Production Guide

> Deploy Cordis applications easily with this production guide. Learn to scaffold, compile, and configure your applications for successful deployment.

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

---

**Deploy Cordis applications by scaffolding with `create-cordis`, compiling TypeScript sources, and executing [`packages/core/bin.js`](https://github.com/cordiverse/cordis/blob/main/packages/core/bin.js) alongside a [`cordis.yml`](https://github.com/cordiverse/cordis/blob/main/cordis.yml) configuration file.**

Cordis is a meta-framework for building modular, spatiotemporal applications using a plugin-based architecture. To deploy Cordis applications in production, you must follow a three-stage workflow: scaffolding the project structure, bundling the TypeScript source code, and running the service with the dynamic plugin loader. This guide walks through the exact implementation details found in the Cordis source code to get your application running on any Linux host, container, or serverless platform.

## Scaffold the Project with create-cordis

The deployment process begins with the `create-cordis` CLI tool located in `packages/create`. This scaffolder generates a predefined directory layout and initializes the project configuration.

Install the scaffolder globally and generate a new project:

```bash
npm i -g @cordisjs/create-cordis
create-cordis my-app

```

The CLI implementation in [`packages/create/src/index.ts`](https://github.com/cordiverse/cordis/blob/main/packages/create/src/index.ts) performs several critical operations:

- Resolves the template from the npm registry via tarball extraction
- Stages a Yarn binary if the caller uses Yarn (`stageYarnBin`)
- Writes the [`package.json`](https://github.com/cordiverse/cordis/blob/main/package.json) with the selected project name (`writePackageJson`)
- Optionally initializes a Git repository

This creates the foundation needed before you can deploy Cordis applications to production environments.

## Build and Compile TypeScript Sources

After scaffolding, install dependencies and compile the TypeScript source code. The repository includes a root [`tsconfig.json`](https://github.com/cordiverse/cordis/blob/main/tsconfig.json) that maps each internal package (e.g., `@cordisjs/plugin-loader`, `@cordisjs/plugin-hmr`) to its source directory.

Run the build process:

```bash
cd my-app
npm install
npx tsc

```

The compiler outputs JavaScript files to the `dist/` directory (or as configured). For optimized deployment, you can bundle these files using tools like Vite or esbuild to create a single-file artifact, though this is optional for standard deployments.

## Configure the cordis.yml Manifest

Before you can deploy Cordis applications, you must define a [`cordis.yml`](https://github.com/cordiverse/cordis/blob/main/cordis.yml) configuration file at the project root. This manifest declares which plugins the loader should dynamically resolve.

Create a [`cordis.yml`](https://github.com/cordiverse/cordis/blob/main/cordis.yml) with your required plugins:

```yaml
plugins:
  - '@cordisjs/plugin-loader'
  - '@cordisjs/plugin-hmr'
  - '@cordisjs/plugin-logger-console'

```

The loader plugin reads this file via [`packages/loader/src/resolve.ts`](https://github.com/cordiverse/cordis/blob/main/packages/loader/src/resolve.ts), which handles automatic creation of `.cordis/resolve.mjs` and manages the `.gitignore` exclusions. When you start the application, [`packages/core/bin.js`](https://github.com/cordiverse/cordis/blob/main/packages/core/bin.js) reads this configuration and initializes the plugin context.

## Production Deployment Strategies

You can deploy Cordis applications using Docker containers or process managers like PM2. Both methods execute [`packages/core/bin.js`](https://github.com/cordiverse/cordis/blob/main/packages/core/bin.js) as the entry point.

### Docker Deployment

Create a multi-stage Dockerfile to minimize image size:

```dockerfile
FROM node:20-alpine AS builder
WORKDIR /app
COPY . .
RUN npm ci && npm run build

FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY cordis.yml .
CMD ["node", "dist/packages/core/bin.js"]

```

Build and run:

```bash
docker build -t my-cordis-app .
docker run -d -p 3000:3000 --name cordis my-cordis-app

```

This approach ships only the compiled `dist/` directory and the [`cordis.yml`](https://github.com/cordiverse/cordis/blob/main/cordis.yml) manifest, with all plugins bundled as regular dependencies.

### PM2 and systemd Deployment

For traditional server deployments, use PM2 to manage the Cordis process:

```bash
npm i -g pm2
pm2 start packages/core/bin.js --name cordis
pm2 startup
pm2 save

```

This configuration keeps the application alive, automatically restarts it on failure, and exposes log management. The [`packages/core/bin.js`](https://github.com/cordiverse/cordis/blob/main/packages/core/bin.js) entry point handles the dynamic plugin loading based on your [`cordis.yml`](https://github.com/cordiverse/cordis/blob/main/cordis.yml) configuration.

## Summary

- **Scaffold** using `create-cordis` (source: [`packages/create/src/index.ts`](https://github.com/cordiverse/cordis/blob/main/packages/create/src/index.ts)) to generate the project structure and initialize [`package.json`](https://github.com/cordiverse/cordis/blob/main/package.json)
- **Build** TypeScript sources using the repository's [`tsconfig.json`](https://github.com/cordiverse/cordis/blob/main/tsconfig.json), which maps `@cordisjs/*` packages to their source directories
- **Configure** a [`cordis.yml`](https://github.com/cordiverse/cordis/blob/main/cordis.yml) manifest that the loader (source: [`packages/loader/src/resolve.ts`](https://github.com/cordiverse/cordis/blob/main/packages/loader/src/resolve.ts)) uses to resolve plugins dynamically
- **Execute** [`packages/core/bin.js`](https://github.com/cordiverse/cordis/blob/main/packages/core/bin.js) to start the application context with the loaded configuration
- **Deploy** using Docker multi-stage builds or PM2 for production process management

## Frequently Asked Questions

### What is the entry point for deploying Cordis applications?

The entry point is [`packages/core/bin.js`](https://github.com/cordiverse/cordis/blob/main/packages/core/bin.js). This script reads the [`cordis.yml`](https://github.com/cordiverse/cordis/blob/main/cordis.yml) configuration file and initializes the Cordis context with the dynamically loaded plugins specified in the manifest. You can execute it directly with Node.js or manage it through a process manager.

### How does Cordis handle plugin resolution during deployment?

The loader plugin ([`packages/loader/src/resolve.ts`](https://github.com/cordiverse/cordis/blob/main/packages/loader/src/resolve.ts)) automatically resolves plugin entry points based on the [`cordis.yml`](https://github.com/cordiverse/cordis/blob/main/cordis.yml) configuration. It creates a `.cordis/resolve.mjs` file that maps plugin names to their actual module locations, enabling dynamic loading without requiring static imports in your application code.

### Can I deploy Cordis applications without Docker?

Yes. You can deploy Cordis applications directly on any Linux host using Node.js and a process manager like PM2 or systemd. Simply compile your TypeScript sources, ensure [`cordis.yml`](https://github.com/cordiverse/cordis/blob/main/cordis.yml) is present in the working directory, and execute `node packages/core/bin.js`. The application requires only the compiled code, the configuration file, and the installed npm dependencies.

### What build tools are recommended for Cordis applications?

While Cordis ships with a root [`tsconfig.json`](https://github.com/cordiverse/cordis/blob/main/tsconfig.json) for standard TypeScript compilation, you can optionally use Vite or esbuild to bundle your application into a single file for optimized deployments. The standard `npm run build` workflow using `tsc` is sufficient for most production deployments.