# How to Run OpenWork Locally for Development: A Complete Setup Guide

> Run OpenWork locally for development by cloning the repo and installing dependencies. Follow this setup guide to get started quickly with pnpm and the dev command.

- Repository: [Different AI/openwork](https://github.com/different-ai/openwork)
- Tags: how-to-guide
- Published: 2026-08-14

---

**You can run OpenWork locally by cloning the monorepo, installing `pnpm@11`, running `pnpm install`, and starting the desktop app with `pnpm dev`.**

OpenWork is a multi-platform productivity suite maintained as a monorepo under `different-ai/openwork`. Whether you're contributing to the **Electron desktop app**, the **web UI**, or the **OpenWork Den control plane**, this guide walks you through the canonical development workflow using `pnpm`, environment profiles, and optional Docker-based backend services.

---

## Prerequisites and Initial Setup

Before running any code, ensure you have the core tools installed.

### Install pnpm 11

OpenWork strictly requires `pnpm` version 11 for workspace compatibility. Install it globally:

```bash
npm i -g pnpm@11

```

### Clone and Install Dependencies

```bash
git clone https://github.com/different-ai/openwork.git
cd openwork
pnpm install

```

The `pnpm install` command resolves all workspace packages across the monorepo, including `@openwork/desktop`, `@openwork/app`, and shared libraries.

---

## Running OpenWork Locally: Core Commands

### Start the Desktop App (Default Profile)

The simplest way to **run OpenWork locally for development** is the `dev` script defined in [`package.json`](https://github.com/different-ai/openwork/blob/main/package.json) at line 5:

```bash
pnpm dev

```

This command launches:
- The Electron desktop application (`@openwork/desktop`)
- A **Chrome DevTools Protocol (CDP)** server on default port **9823**
- The default dev profile for user data isolation

Check your console for the banner: `[openwork] dev profile=… cdp=http://127.0.0.1:9823`. Use this URL to attach debugging tools or automation scripts.

### Override the CDP Port

If port 9823 conflicts with another service, set `OPENWORK_ELECTRON_REMOTE_DEBUG_PORT`:

```bash
OPENWORK_ELECTRON_REMOTE_DEBUG_PORT=9229 pnpm dev

```

---

## Advanced Local Development: Worktree Mode

For **parallel development on multiple branches or features**, use **worktree mode**. This configuration is documented in the README at line 91 and defined in [`package.json`](https://github.com/different-ai/openwork/blob/main/package.json).

### What Worktree Mode Configures

| Variable | Purpose |
|----------|---------|
| `OPENWORK_DEV_PROFILE=auto` | Auto-generates a unique profile name per invocation |
| `OPENWORK_ELECTRON_USE_MOCK_KEYCHAIN=1` | Bypasses OS keychain for faster iteration |
| `PORT=0` | Lets the OS assign a free port |

### Run Worktree Mode

```bash
pnpm dev:worktree

```

Or manually with environment variables:

```bash
OPENWORK_DEV_PROFILE=auto \
OPENWORK_ELECTRON_USE_MOCK_KEYCHAIN=1 \
OPENWORK_ELECTRON_REMOTE_DEBUG_PORT=0 \
PORT=0 \
pnpm dev

```

### Launch Multiple Concurrent Instances

Run separate Electron instances side-by-side with distinct profiles:

```bash

# Terminal 1: main development

pnpm dev

# Terminal 2: feature branch testing

OPENWORK_DEV_PROFILE=feature-xyz pnpm dev

```

Each instance maintains isolated user data directories, preventing state collisions.

---

## Optional: Start the Full Den Backend Stack

For **end-to-end local development** with the self-hosted backend, start the Docker-based **OpenWork Den** services.

### Step-by-Step Den Setup

1. **Start MySQL container:**

```bash
pnpm dev:den:mysql

```

Defined in [`package.json`](https://github.com/different-ai/openwork/blob/main/package.json) at line 53, this launches the database via [`packaging/docker/docker-compose.web-local.yml`](https://github.com/different-ai/openwork/blob/main/packaging/docker/docker-compose.web-local.yml).

2. **Push the database schema:**

```bash
pnpm dev:den:db-push

```

3. **Seed demo data:**

```bash
pnpm dev:den:seed-demo

```

### Verify Den Services

| Service | Local URL |
|---------|-----------|
| Desktop UI | `http://localhost:5173` |
| Den API | `http://localhost:3005` |

The `scripts/dev-local.mjs` file orchestrates this workflow, wiring environment variables and service dependencies automatically.

---

## Key Environment Variables Reference

| Variable | Default | Description |
|----------|---------|-------------|
| `OPENWORK_DEV_PROFILE` | (repo name) | Isolates Electron user data; use `auto` for ephemeral profiles |
| `OPENWORK_ELECTRON_REMOTE_DEBUG_PORT` | `9823` | CDP server port for remote debugging |
| `OPENWORK_ELECTRON_USE_MOCK_KEYCHAIN` | `0` | Set to `1` to mock keychain (faster, no OS prompts) |
| `PORT` | `5173` | Web UI development server port |

---

## Key Source Files and Architecture

Understanding these files helps you navigate the codebase when you **run OpenWork locally for development**:

| File | Purpose |
|------|---------|
| [`README.md`](https://github.com/different-ai/openwork/blob/main/README.md) | Quick-start commands and local development section (line 86+) |
| [`package.json`](https://github.com/different-ai/openwork/blob/main/package.json) | All `pnpm` scripts: `dev`, `dev:worktree`, `dev:den:*` |
| `scripts/dev-local.mjs` | Den stack bootstrap and environment orchestration |
| [`packaging/docker/docker-compose.web-local.yml`](https://github.com/different-ai/openwork/blob/main/packaging/docker/docker-compose.web-local.yml) | MySQL and Den container definitions |
| [`.opencode/skills/browser-automation/SKILL.md`](https://github.com/different-ai/openwork/blob/main/.opencode/skills/browser-automation/SKILL.md) | CDP automation documentation |

The monorepo uses `pnpm --filter` to target specific packages. For example, `pnpm --filter @openwork/desktop dev` runs only the desktop package—though the root-level scripts handle this automatically.

---

## Troubleshooting Common Issues

### Port Already in Use

If you see `EADDRINUSE`, either:
- Kill the existing process, or
- Set `PORT=0` and `OPENWORK_ELECTRON_REMOTE_DEBUG_PORT=0` to auto-assign ports

### Keychain Permission Prompts

Set `OPENWORK_ELECTRON_USE_MOCK_KEYCHAIN=1` to eliminate OS keychain dialogs during rapid iteration.

### Profile Conflicts

If state seems corrupted, clear the profile directory or switch to a new `OPENWORK_DEV_PROFILE` value.

---

## Summary

- **Clone and install:** `git clone`, `npm i -g pnpm@11`, `pnpm install`
- **Quick start:** `pnpm dev` launches Electron with CDP on port 9823
- **Parallel work:** `pnpm dev:worktree` or manual profile variables enable multiple instances
- **Full stack:** `pnpm dev:den:mysql`, `dev:den:db-push`, `dev:den:seed-demo` for backend development
- **Key variables:** `OPENWORK_DEV_PROFILE`, `OPENWORK_ELECTRON_USE_MOCK_KEYCHAIN`, `OPENWORK_ELECTRON_REMOTE_DEBUG_PORT`

---

## Frequently Asked Questions

### What is the minimum Node.js version to run OpenWork locally?

The source analysis does not specify a Node.js version, but `pnpm@11` requires Node.js 18 or higher. Verify with `node -v` before proceeding.

### Can I run OpenWork without Docker?

Yes. The desktop app (`pnpm dev`) and web UI run entirely without Docker. Docker is only required for the **Den backend** when you need database persistence or API services.

### Why does my Electron app show keychain permission dialogs?

By default, `OPENWORK_ELECTRON_USE_MOCK_KEYCHAIN` is disabled. Set it to `1` in your environment or use `pnpm dev:worktree` to bypass OS keychain integration during development.

### How do I attach Chrome DevTools to the running Electron instance?

Use the CDP URL printed in your console: `http://127.0.0.1:9823`. Navigate to `chrome://inspect` in Chrome, click "Configure", add the host:port, then select the OpenWork target under "Remote Target".