# Openship Contributing Guide: From Setup to Pull Request

> Contribute to Openship by cloning the monorepo, installing with Bun, and submitting a pull request. Follow our guide for a smooth contribution process.

- Repository: [oblien/openship](https://github.com/oblien/openship)
- Tags: getting-started
- Published: 2026-07-31

---

**To contribute to Openship, clone the monorepo, install dependencies with Bun, run `bun dev` to start the full development stack, follow the one-change-per-PR rule, and ensure tests pass before submitting.**

Openship is a self-hostable deployment platform that bundles CI/CD, routing, TLS, mail, and backups behind a single control-plane. This **Openship contributing guide** walks you through the monorepo architecture, development setup, and submission standards required to submit high-quality pull requests to the `oblien/openship` repository.

## Understanding the Monorepo Architecture

Openship organizes its codebase into distinct workspaces and shared packages that implement a full-stack system for building, running, and exposing applications.

### Control-Plane Applications

The repository contains five primary applications in the `apps/` directory:

- **`apps/api`** – A Hono-based REST/MCP API running on port 4000. The entry point in [`apps/api/src/app.ts`](https://github.com/oblien/openship/blob/main/apps/api/src/app.ts) sets up the Hono server, mounts shared modules, and gates cloud-only routes.
- **`apps/dashboard`** – A Next.js admin UI served on port 3001, with its entry point located at [`apps/dashboard/src/pages/index.tsx`](https://github.com/oblien/openship/blob/main/apps/dashboard/src/pages/index.tsx).
- **`apps/desktop`** – An Electron wrapper that launches the local control-plane and provides a native GUI, configured via [`apps/desktop/forge.config.js`](https://github.com/oblien/openship/blob/main/apps/desktop/forge.config.js).
- **`apps/web`** – The marketing site running on port 3009.
- **`apps/email`** – A Zero-mail server and client for handling inbound and outbound mail.

### Shared Packages

Reusable logic lives in the `packages/` directory and is imported by multiple apps:

- **`packages/core`** – Centralizes types, constants, utilities, and error definitions in [`packages/core/src/index.ts`](https://github.com/oblien/openship/blob/main/packages/core/src/index.ts) for use across the repo.
- **`packages/adapters`** – Implements runtime adapters including Docker container orchestration ([`packages/adapters/src/dockerAdapter.ts`](https://github.com/oblien/openship/blob/main/packages/adapters/src/dockerAdapter.ts)) and bare-host runtimes.
- **`packages/db`** – Manages database connections using Drizzle ORM, with schema definitions in [`packages/db/src/schema.ts`](https://github.com/oblien/openship/blob/main/packages/db/src/schema.ts).
- **`packages/ui`** – Provides Tailwind-styled React components shared by the dashboard and desktop UI, including the `cn` utility in [`packages/ui/src/lib/cn.ts`](https://github.com/oblien/openship/blob/main/packages/ui/src/lib/cn.ts).

All workspaces inherit the root [`tsconfig.base.json`](https://github.com/oblien/openship/blob/main/tsconfig.base.json), ensuring consistent TypeScript configuration. The project requires **Bun 1.3.10**, **Node.js 22+**, and Docker when using the Compose stack.

## Development Setup and Workflow

Contributors interact with the codebase using Bun-based commands standardized across the monorepo.

### Clone and Install

Start by cloning the repository and installing frozen dependencies:

```bash
git clone https://github.com/oblien/openship.git
cd openship
bun install --frozen-lockfile

```

### Running the Development Stack

Use the following commands to run the environment according to your needs:

- **Full stack** – Launches the API, dashboard, web, desktop, and email services simultaneously:

  ```bash
  bun dev
  ```

- **Individual workspace** – Targets a specific app for focused debugging:

  ```bash
  bun dev:api
  ```

## Code Contribution Standards

Openship enforces strict quality gates to maintain stability across its deployment pipeline.

### Testing Requirements

Every change must include test coverage. Tests live alongside implementation code in `*.test.ts` files within each workspace. Ensure a failing test exists before your change and passes after implementing the fix. Run tests for a specific workspace using:

```bash
bun run --cwd apps/api test

```

### Linting and Formatting

Before opening a pull request, execute the full verification suite:

```bash
bun run test && bun run --cwd apps/api lint && bun format

```

All checks must succeed. Follow the **one-change-per-PR** rule, keeping diffs scoped to only the files necessary for the specific fix or feature.

## Build and Deploy Pipeline

Understanding the five-stage pipeline helps contributors debug deployment issues:

1. **Detect** – Reads [`package.json`](https://github.com/oblien/openship/blob/main/package.json), lockfiles, [`docker-compose.yml`](https://github.com/oblien/openship/blob/main/docker-compose.yml), or [`openship.json`](https://github.com/oblien/openship/blob/main/openship.json) to infer stack, build, and start commands.
2. **Build** – Generates a Docker image (Compose mode) or a bare binary (bare mode) and snapshots the configuration for reproducible rollbacks.
3. **Run** – Starts the artifact as either a container (isolated) or a supervised host process.
4. **Route and Secure** – The OpenResty edge writes reverse-proxy vhosts and obtains Let's Encrypt certificates automatically.
5. **Push-to-Deploy** – GitHub webhooks trigger the pipeline on every push, rebuilding only changed services.

## Summary

- **Architecture**: Openship splits functionality between control-plane apps (`apps/api`, `apps/dashboard`, etc.) and shared packages (`packages/core`, `packages/db`, etc.).
- **Setup**: Use `bun install --frozen-lockfile` and `bun dev` to initialize the development environment.
- **Standards**: Follow the one-change-per-PR rule, write tests in `*.test.ts` files, and pass `bun run test`, lint, and format checks before submitting.
- **Key Files**: Critical paths include [`apps/api/src/app.ts`](https://github.com/oblien/openship/blob/main/apps/api/src/app.ts) for the API server, [`packages/adapters/src/dockerAdapter.ts`](https://github.com/oblien/openship/blob/main/packages/adapters/src/dockerAdapter.ts) for container logic, and [`packages/db/src/schema.ts`](https://github.com/oblien/openship/blob/main/packages/db/src/schema.ts) for database definitions.

## Frequently Asked Questions

### What version of Bun does Openship require?

Openship requires **Bun 1.3.10** and **Node.js 22+** according to the development environment specifications. Ensure your local installation matches these versions before running `bun install` to avoid compatibility issues with the monorepo's build scripts.

### How do I run only the API for debugging?

Use the workspace-specific dev command `bun dev:api` to start only the Hono-based API on port 4000. This is useful when you need to isolate backend changes without launching the full desktop application, dashboard, or email services.

### Where are the database schemas defined?

Database schemas are defined using Drizzle ORM in [`packages/db/src/schema.ts`](https://github.com/oblien/openship/blob/main/packages/db/src/schema.ts). This file exports the Postgres schema used by the control-plane to manage projects, deployments, and user data across the platform.

### What is the one-change-per-PR rule?

The one-change-per-PR rule requires contributors to scope each pull request to a single logical change, updating only files necessary for that specific fix or feature. This practice simplifies code review, reduces merge conflicts, and maintains a clean Git history in the `oblien/openship` repository.