# How to Set Up a Local Development Environment for OpenWork: A Complete Guide

> Learn how to set up a local development environment for OpenWork. Clone the repo, install dependencies, and run OpenWork locally with this complete guide.

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

---

**To set up a local development environment for OpenWork, clone the `different-ai/openwork` repository, install dependencies with `pnpm install`, and execute `pnpm dev` to launch the Electron desktop client with hot-reloading; for the complete stack including the Den backend services, run `pnpm dev:den` while Docker is running.**

OpenWork is an open-source, multi-package desktop application built by **different-ai** that combines an **Electron** client with a **Den** stack for API and inference management. The repository follows a **pnpm-workspace** layout, separating concerns into distinct packages for the desktop client (`@openwork/desktop`), the UI application (`@openwork/app`), and the server-side Den services (`@openwork-ee/den-*`). This guide walks you through the exact commands and configurations found in the source code to get a fully functional development environment running locally.

## Prerequisites

Before cloning the repository, ensure your system meets the following requirements:

- **Node.js** version 20 or higher
- **pnpm** version 11 or higher (install globally via `npm i -g pnpm`)
- **Docker** and Docker Compose (required for the MySQL database and Den services)

## Architecture Overview

Understanding the runtime architecture helps clarify why specific setup steps are necessary. The platform consists of interconnected services:

- **Electron Client**: Runs the desktop UI and exposes a **Chrome DevTools Protocol (CDP)** endpoint (typically on port `9223` or `9825`) for automation.
- **Vite Dev Server**: Provides hot-module replacement (HMR) for the React UI on port `5173`.
- **Den Web**: A Next.js dashboard running on port `3005`.
- **Den API**: A Hono-based API server running on port `8788`.
- **MySQL**: Database service running on port `3306` inside a Docker container.

The client communicates with the Den services over HTTP, while the CDP endpoint allows external tools like Playwright to automate the Electron interface.

## Clone and Install

Start by cloning the repository and switching to the active development branch. Then install the workspace dependencies using pnpm.

```bash
git clone https://github.com/different-ai/openwork.git
cd openwork
git checkout dev

pnpm install

```

This command installs all dependencies across the monoreco packages defined in the root [`package.json`](https://github.com/different-ai/openwork/blob/main/package.json) ([source](https://github.com/different-ai/openwork/blob/dev/package.json)).

## Development Workflow Options

The root [`package.json`](https://github.com/different-ai/openwork/blob/main/package.json) defines several npm scripts tailored to different development scenarios. Choose the workflow that matches your current task.

### Quick Start: Desktop Client Only

Run the following command to start the Electron client in development mode with Vite hot-reloading:

```bash
pnpm dev

```

This script sets `OPENWORK_DEV_MODE=1` and prints a banner to your terminal containing the CDP URL, such as `cdp=http://127.0.0.1:9223`. You can use this WebSocket URL to connect automation tools directly to the running Electron instance.

### Isolated Worktree Development

When working across multiple git branches or worktrees, use the isolated profile command to prevent configuration conflicts:

```bash
pnpm dev:worktree

```

This script automatically sets `OPENWORK_DEV_PROFILE=auto`, creating a unique profile directory for each worktree. It also enables `OPENWORK_ELECTRON_USE_MOCK_KEYCHAIN=1` to bypass macOS keychain permission prompts during development. If you require the actual system keychain, override the variable:

```bash
OPENWORK_ELECTRON_USE_MOCK_KEYCHAIN=0 pnpm dev:worktree

```

### Launch the Den Stack

To start the backend services (MySQL, Den API, and Den Web UI), ensure Docker is running and execute:

```bash
pnpm dev:den

```

This command invokes `scripts/dev-local.mjs` ([source](https://github.com/different-ai/openwork/blob/dev/scripts/dev-local.mjs)), which orchestrates the Docker containers and sets the necessary environment variables. For finer control, you can start services individually:

```bash
pnpm dev:den:mysql    # Start only the database container

pnpm dev:den:db-push  # Push the database schema

pnpm dev:den:api      # Start only the API service

```

### Full Stack Development (Client + Den)

To run the complete application stack—both the Electron client and the Den backend services—use the combined command:

```bash
pnpm dev:web-local

```

Alternatively, you can run `pnpm dev` and `pnpm dev:den` in separate terminal windows. The desktop client will connect to `http://localhost:3005` (Den Web) and `http://localhost:8788` (Den API).

## Advanced Development Workflows

### Daytona Sandbox Environment

For reproducible CI environments or isolated testing, OpenWork supports a Daytona dev-container setup that runs the entire stack inside a cloud sandbox with VNC access:

```bash
pnpm dev:sandbox

```

This launches the Electron application inside a container with noVNC exposed on port `6080` and the CDP endpoint on port `9825`. Access the desktop environment via your browser at `http://localhost:6080`. Detailed configuration options are documented in [`.devcontainer/README.md`](https://github.com/different-ai/openwork/blob/main/.devcontainer/README.md) ([source](https://github.com/different-ai/openwork/blob/dev/.devcontainer/README.md)).

### Automation with Chrome DevTools Protocol

The Electron client exposes a CDP endpoint for automated testing and AI-driven interactions. Connect via Playwright using the URL printed in the terminal banner:

```javascript
import { chromium } from 'playwright';

(async () => {
  const browser = await chromium.connectOverCDP('ws://127.0.0.1:9223');
  const page = await browser.newPage();
  await page.goto('http://localhost:3005');
  // Perform automated actions...
  await browser.close();
})();

```

## Key Configuration Files and Scripts

Understanding these specific files helps when debugging or customizing your environment:

- **[`package.json`](https://github.com/different-ai/openwork/blob/main/package.json)** ([source](https://github.com/different-ai/openwork/blob/dev/package.json)): Defines all workspace scripts including `dev`, `dev:worktree`, and `dev:den`.
- **`scripts/dev-local.mjs`** ([source](https://github.com/different-ai/openwork/blob/dev/scripts/dev-local.mjs)): Entry point for the Den stack initialization; handles Docker container management.
- **[`.devcontainer/README.md`](https://github.com/different-ai/openwork/blob/main/.devcontainer/README.md)** ([source](https://github.com/different-ai/openwork/blob/dev/.devcontainer/README.md)): Documentation for the Daytona sandbox setup and VNC configuration.

## Summary

- Use **`pnpm dev`** to start the Electron client with Vite HMR for UI development.
- Use **`pnpm dev:worktree`** when working on multiple branches to create isolated profiles and avoid port conflicts.
- Use **`pnpm dev:den`** to start the Dockerized backend services (MySQL, Den API, Den Web).
- Use **`pnpm dev:sandbox`** for a reproducible cloud-based development environment with VNC access.
- The Electron client exposes a CDP endpoint on startup, enabling automated browser control for testing.

## Frequently Asked Questions

### What is the minimum Node.js version required for OpenWork?

OpenWork requires **Node.js version 20 or higher** and **pnpm version 11 or higher**. These versions ensure compatibility with the workspace scripts and the Electron build toolchain as defined in the root [`package.json`](https://github.com/different-ai/openwork/blob/main/package.json).

### Why does OpenWork use a mock keychain in development?

The `pnpm dev:worktree` command sets `OPENWORK_ELECTRON_USE_MOCK_KEYCHAIN=1` to prevent repetitive macOS system keychain permission prompts during frequent app restarts. This mock stores credentials in memory or a temporary file, speeding up the development cycle. Disable this by setting the variable to `0` if you need to test actual secure storage integration.

### Can I run OpenWork without Docker?

No, Docker is mandatory for local development if you intend to run the **Den stack** (API, Web UI, and MySQL). The `pnpm dev:den` script relies on Docker Compose to orchestrate these services. However, you can develop the Electron client independently using `pnpm dev` without Docker, though functionality requiring the backend will be unavailable.

### How do I connect to the Electron client for automated testing?

The Electron client exposes a **Chrome DevTools Protocol (CDP)** endpoint on startup, typically on port `9223` or `9825`, which is printed in the terminal banner. You can connect automation tools like Playwright, Puppeteer, or Chrome MCP to this WebSocket URL to programmatically control the desktop interface.