How to Navigate the Openship Codebase: A Complete Guide to the Monorepo Structure

Openship is a pnpm workspace monorepo organized into apps/ for executables and packages/ for shared libraries, with core business logic residing in packages/core, database schemas in packages/db, and Docker integrations in packages/adapters.

Openship is a self-hostable deployment platform that ships as a TypeScript monorepo. Knowing how to navigate the Openship codebase efficiently is essential for contributing to the web dashboard, CLI, or core service routing logic. This guide maps the repository structure from root configuration to individual source files, helping you locate specific functionality quickly.

Understanding the Monorepo Layout

The repository follows a standard pnpm workspace structure defined in the root package.json.

Root Configuration

The top-level directory contains workspace orchestration and infrastructure definitions. The package.json declares both apps/* and packages/* as workspaces, enabling cross-package imports with @repo/ prefixes.

{
  "workspaces": [
    "apps/*",
    "packages/*"
  ]
}

The build system uses Turborepo to run commands across workspaces. For example, npm run build triggers turbo run build --filter=@repo/api --filter=@repo/dashboard as defined in the root scripts.

Apps Directory

The apps/ folder contains full-stack executables that run the control plane or user interfaces:

  • apps/web/ – React dashboard served via source.config.ts
  • apps/desktop/ – Electron client with entry at build/run.mjs
  • apps/cli/ – Command-line interface invoked via bun run --cwd apps/cli cli
  • apps/api/ – Express-style REST/MCP server at src/index.ts
  • apps/email/ – SMTP server for inbound mail routing at src/index.ts

Packages Directory

Reusable libraries live under packages/ and implement domain-specific logic:

  • packages/core/ – Platform-wide utilities including service routing and version resolution
  • packages/adapters/ – Docker, OpenResty, and cloud provider integrations
  • packages/db/ – Drizzle ORM schemas and database configuration
  • packages/ui/ – Shared React components for web and desktop
  • packages/onboarding/ – User setup flows for SSH and API keys

Understanding the packages/ subdirectory is key to modifying Openship's behavior.

Core Package Architecture

All platform-wide logic exports from packages/core/src/index.ts. Key modules include:

  • src/service-routing.ts – Resolves how project services map to URLs and reverse-proxy rules
  • src/updates/ – Handles version resolution, semver checking, and upgrade advisories
  • src/metadata/ – Renders deployment metadata for Vercel, Railway, and the internal UI

When tracing how a deployment gets routed, start at packages/core/src/service-routing.ts to see the resolveServiceRouting function implementation.

Adapters and Toolchain

The packages/adapters directory contains concrete infrastructure implementations:

  • src/toolchain/installer.ts – Builds containers and prepares host environments
  • test/*.test.ts – Validates edge routing, TLS handling, and resource limits

This package translates high-level core commands into Docker and OpenResty configurations.

Database Schema

packages/db manages persistence using Drizzle ORM:

Import schema definitions directly to query the PostgreSQL backend:

import { db } from '@repo/db';
import { project } from '@repo/db/src/schema/project';

const projects = await db.select().from(project);
console.log(projects);

UI and Onboarding Components

Shared presentation logic resides in:

  • packages/ui/src/lib/cn.ts – Utility functions for component styling
  • packages/onboarding/ – Flows for project creation and credential setup

Working with Application Entry Points

Each app in apps/ has a distinct entry point that determines its runtime behavior.

App Entry File Purpose
Web Dashboard apps/web/source.config.ts Serves React UI and proxies API requests
Desktop apps/desktop/build/run.mjs Electron wrapper for local control plane
CLI apps/cli/cli Node.js binary for deployment commands
API apps/api/src/index.ts Orchestrates builds and exposes REST endpoints
Email apps/email/src/index.ts Processes inbound SMTP traffic

To run the CLI locally during development, use the command referenced in the source:

bun run --cwd apps/cli cli

Build System and Release Process

The repository uses Turborepo for task running and includes automated release management.

Docker Composition

Self-hosted deployments rely on docker/docker-compose.yml, which defines the complete runtime stack:

services:
  postgres: ...
  redis: ...
  api: ...
  dashboard: ...
  edge: ...

This file spins up PostgreSQL, Redis, the API server, dashboard, and OpenResty edge proxy.

Release Automation

scripts/release.ts packages the CLI, generates changelogs, and publishes Docker images. The script coordinates version bumps across all workspace packages before creating distributable artifacts.

Practical Navigation Examples

Resolving Service Routing

To understand how Openship maps services to URLs, import the core routing resolver:

// src/example.ts
import { resolveServiceRouting } from '@repo/core/src/service-routing';

const project = {
  name: 'my-app',
  ports: [{ internal: 3000, external: 80 }],
};

const routing = resolveServiceRouting(project);
console.log(routing);
// → { host: 'my-app.openship.dev', path: '/', targetPort: 3000 }

Building Containers Programmatically

Interact with the toolchain adapter to build Docker images:

import { buildContainer } from '@repo/adapters/src/toolchain/installer';

await buildContainer({
  context: './my-app',
  dockerfile: 'Dockerfile',
  tags: ['my-app:latest'],
});

Running CLI Commands

The CLI entry point at apps/cli/cli supports standard deployment workflows:


# Initialize a project in the current directory

openship init

# Deploy and trigger the CI/CD pipeline

openship deploy

Summary

  • Openship uses pnpm workspaces with two main directories: apps/ for executables and packages/ for shared libraries.
  • Core business logic lives in packages/core/src/, particularly service-routing.ts for URL resolution.
  • Database schemas are defined in packages/db/src/schema/ using Drizzle ORM.
  • Infrastructure automation is handled by packages/adapters/src/toolchain/installer.ts for Docker operations.
  • Application entry points vary by platform: apps/api/src/index.ts for the server, apps/cli/cli for the command line, and apps/web/source.config.ts for the dashboard.
  • Local development requires running docker/docker-compose.yml for the full stack and using Turborepo for builds.

Frequently Asked Questions

Where is the main API server code located in Openship?

The main API server is located at apps/api/src/index.ts. This Express-style server exposes the REST and MCP API endpoints and coordinates build processes across the platform. It imports logic from packages/core and packages/adapters to handle routing and container operations.

How do I find the database schema definitions in the Openship codebase?

Database schemas are located in packages/db/src/schema/. The Drizzle ORM configuration in packages/db/drizzle.config.ts points to these files. For example, the projects table is defined in packages/db/src/schema/project.ts, which you can query using the @repo/db import alias.

What is the purpose of the packages/core directory?

packages/core/ contains the platform's business logic that is shared across all applications. It handles service routing (src/service-routing.ts), version updates (src/updates/), and deployment metadata rendering. This package has no UI or infrastructure dependencies, making it pure domain logic.

How do I run the Openship CLI from the source code?

Navigate to the repository root and run bun run --cwd apps/cli cli (or use npm/pnpm with the appropriate --cwd flag). The CLI entry point is the apps/cli/cli file, which parses commands and communicates with the API server defined in apps/api/src/index.ts.

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 →