How to Add a New Package to the OpenWork Monorepo: A Step-by-Step Guide

OpenWork uses a pnpm workspace that automatically links any directory matching the packages/* and apps/* globs declared in pnpm-workspace.yaml, so adding a new package only requires creating a properly scoped package.json and running pnpm install.

The different-ai/openwork repository is a TypeScript monorepo orchestrated by pnpm and Turbo. To add a new package to the OpenWork monorepo, you follow a repeatable, convention-based workflow that keeps builds, tests, and CI pipelines intact. Every new package lives under the packages/ or apps/ directories and inherits shared tooling defined at the repository root.

Step-by-Step Guide to Adding a New Package

1. Create the Package Directory

Create a folder under packages/<my-package> for a library or apps/<my-app> for an application. The folder must match one of the glob patterns defined in pnpm-workspace.yaml so pnpm recognizes it as a workspace member.

2. Add a package.json with the OpenWork Scope

Inside the new folder, add a package.json that uses the @openwork/ scope and sets private: true to prevent accidental publishing. As demonstrated in packages/ui/package.json, you should define entry points, types, and standard scripts.

{
  "name": "@openwork/my-package",
  "version": "0.1.0",
  "private": true,
  "main": "src/index.ts",
  "types": "src/index.d.ts",
  "scripts": {
    "build": "tsc",
    "test": "pnpm test"
  },
  "dependencies": {}
}

3. Configure TypeScript

Create a local tsconfig.json that extends the root configuration. This keeps compiler options aligned with the rest of the monorepo and ensures consistent output directories, following the pattern used by packages/ui/tsconfig.react.json.

{
  "extends": "../../tsconfig.base.json",
  "compilerOptions": {
    "outDir": "dist"
  },
  "include": ["src"]
}

4. Run pnpm install from the Root

Navigate to the repository root and execute pnpm install. pnpm will discover the new package, resolve its dependencies, and wire the appropriate node_modules symlinks automatically.

5. Register the Package in turbo.json

If the new package must participate in build, lint, or test pipelines, update the root turbo.json. Add the package to the relevant pipeline so Turbo includes it in caching and parallel execution. The default build pipeline uses "dependsOn": ["^build"] and "outputs": ["dist/**"].

Complete Scaffolding Example

Run the following from the repository root to generate a minimal package skeleton:


# 1. Create the directory

mkdir -p packages/my-tool
cd packages/my-tool

# 2. Write package.json

cat > package.json <<'EOF'
{
  "name": "@openwork/my-tool",
  "version": "0.1.0",
  "private": true,
  "main": "src/index.ts",
  "types": "src/index.d.ts",
  "scripts": {
    "build": "tsc",
    "test": "pnpm test"
  },
  "dependencies": {}
}
EOF

# 3. Add a basic TypeScript entry point

mkdir src
cat > src/index.ts <<'EOF'
export function hello(name: string): string {
  return `Hello, ${name}!`;
}
EOF

# 4. Extend the root TS config

cat > tsconfig.json <<'EOF'
{
  "extends": "../../tsconfig.base.json",
  "compilerOptions": {
    "outDir": "dist"
  },
  "include": ["src"]
}
EOF

# 5. Install workspace dependencies from root

cd ../..
pnpm install

Consuming the Package Inside the Workspace

To use the new package from another workspace member, reference it with the workspace:* protocol in the dependent's package.json. This tells pnpm to link the local version instead of fetching from a registry.

{
  "name": "@openwork/another-package",
  "private": true,
  "dependencies": {
    "@openwork/my-tool": "workspace:*"
  }
}

Key Files That Power the OpenWork Monorepo

  • pnpm-workspace.yaml: Declares the packages/* and apps/* globs that define workspace boundaries. Any folder matching these patterns is automatically linked during installation.
  • turbo.json: Drives CI/CD pipelines, caching, and parallel task execution across workspace members.
  • tsconfig.base.json: Central TypeScript configuration that individual packages extend to stay aligned on compiler options.
  • Root package.json: Houses workspace-wide dev dependencies and shared scripts used across the monorepo.

Summary

  • Create a directory under packages/ or apps/ that matches the globs in pnpm-workspace.yaml.
  • Write a scoped, private package.json using the @openwork/ namespace to prevent accidental publishing.
  • Extend ../../tsconfig.base.json for consistent TypeScript settings.
  • Run pnpm install from the root to link the new package into the workspace graph.
  • Update turbo.json when the package needs custom build, lint, or test pipeline behavior.

Frequently Asked Questions

Does OpenWork use npm or yarn for its monorepo?

No. According to the source configuration in different-ai/openwork, the monorepo relies on pnpm workspaces for dependency linking and task execution. The root pnpm-workspace.yaml and lockfile behavior confirm this choice.

What naming convention should new packages follow?

New packages should use the @openwork/ scope in their name field and set "private": true to avoid accidental publishing. This convention is consistent with existing packages such as packages/ui/package.json.

Do I need to manually edit pnpm-workspace.yaml for every new package?

No. The root pnpm-workspace.yaml uses directory globs such as packages/* and apps/*. As long as your new folder matches those patterns, pnpm will discover it automatically during the next pnpm install.

How does Turbo know to build a new package?

Turbo reads the root turbo.json pipeline definitions. If your new package exposes a build, test, or lint script that must participate in the monorepo CI, ensure the pipeline configuration covers that task so Turbo can cache and parallelize it correctly.

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 →