# How to Set Up Environment Variables for OpenWork Development

> Easily set up environment variables for OpenWork development. Create a .env.dev file and run pnpm dev to inject OPENWORK_* variables into your processes.

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

---

**Create a `.env.dev` file at the repository root, populate it with `OPENWORK_*` variables, and run `pnpm dev` to automatically inject them into the Electron and headless web processes.**

Setting up environment variables for OpenWork development is the first step to running the desktop app, headless web UI, and local tooling without leaking global user state. The `different-ai/openwork` repository relies on a root `.env.dev` file and per-package `.env.example` templates to configure the dev workflow. All configuration keys use the `OPENWORK_*` prefix and are consumed by the Node-based dev scripts before spawning Electron or Vite processes.

## How OpenWork Loads Environment Variables

When you run any development command such as `pnpm dev`, `pnpm dev:headless-web`, or `pnpm dev:worktree`, the wrapper scripts first look for a file named `.env.dev` at the repository root. If that file exists, the scripts source the values directly into the current environment. According to the `different-ai/openwork` source code, if `.env.dev` is missing, the scripts fall back to package-specific `.env.example` files—such as `ee/apps/den-api/.env.example`—and use them as a starting point for local configuration.

Once loaded, these values are injected into `process.env` for the Node-based tooling. They are also forwarded to the Electron process via the `env:` field of `child_process.spawn`, ensuring the desktop shell and any forked workers share the same dev context.

## Core Environment Variables for OpenWork Development

The `OPENWORK_*` namespace controls Electron behavior, headless web launching, logging paths, and port allocation. Below are the variables referenced across the codebase, grouped by subsystem.

### Electron and Desktop Flags

These variables configure the Electron shell, protocol registration, and debug ports.

- **`OPENWORK_DEV_MODE`** — Enables a dev-mode flag that isolates OpenWork state from the user’s global config. Referenced in [`scripts/dev-headless-web.ts`](https://github.com/different-ai/openwork/blob/main/scripts/dev-headless-web.ts).
- **`OPENWORK_ELECTRON_REMOTE_DEBUG_PORT`** — Defines the Chrome DevTools Protocol (CDP) port used when the Electron shell starts. Referenced in [`scripts/openwork-debug.sh`](https://github.com/different-ai/openwork/blob/main/scripts/openwork-debug.sh).
- **`OPENWORK_ELECTRON_USE_MOCK_KEYCHAIN`** — When set to `1`, Electron uses a mock keychain so that local development does not trigger real macOS keychain dialogs. Referenced in `scripts/dev-two-electron-demo.mjs`.
- **`OPENWORK_ELECTRON_DISABLE_PROTOCOL_REGISTRATION`** — Prevents the custom `openwork://` protocol from being registered on the host machine, which is useful for isolated CI runs. Referenced in `scripts/dev-two-electron-demo.mjs`.

### Headless Web and Remote Access

These settings control the browser-based UI launcher and remote agent connectivity.

- **`OPENWORK_REMOTE_ACCESS`** — Enables remote access to the Electron CDP endpoint from another machine. Referenced in [`scripts/dev-headless-web.ts`](https://github.com/different-ai/openwork/blob/main/scripts/dev-headless-web.ts).
- **`OPENWORK_PUBLIC_HOST`** — The hostname that the headless web UI advertises for remote agents. Referenced in [`scripts/dev-headless-web.ts`](https://github.com/different-ai/openwork/blob/main/scripts/dev-headless-web.ts).
- **`OPENWORK_WORKSPACE`** — Absolute path of the workspace directory that the UI should open on launch. Referenced in [`scripts/dev-headless-web.ts`](https://github.com/different-ai/openwork/blob/main/scripts/dev-headless-web.ts).
- **`OPENWORK_DEV_HEADLESS_WEB_DETACHED`** — Internal flag used by the headless web launcher to indicate a detached child process. Referenced in [`scripts/dev-headless-web.ts`](https://github.com/different-ai/openwork/blob/main/scripts/dev-headless-web.ts).
- **`OPENWORK_DEV_HEADLESS_WEB_REPLACE`** — When set to `1`, forces the headless web UI to replace any existing instance. Referenced in [`scripts/dev-headless-web.ts`](https://github.com/different-ai/openwork/blob/main/scripts/dev-headless-web.ts).

### Dev Script, Logging, and Port Configuration

These variables manage log file destinations, pnpm daemon tracking, and Vite server ports.

- **`OPENWORK_DEV_LOG_FILE`** — Path where the dev process writes its log output. Referenced in [`scripts/openwork-debug.sh`](https://github.com/different-ai/openwork/blob/main/scripts/openwork-debug.sh).
- **`OPENWORK_PNPM_DEV_LOG`** — File that captures the `pnpm` daemon log. Referenced in [`scripts/openwork-debug.sh`](https://github.com/different-ai/openwork/blob/main/scripts/openwork-debug.sh).
- **`OPENWORK_PNPM_DEV_PID`** — PID file for the `pnpm` daemon, enabling graceful shutdowns. Referenced in [`scripts/openwork-debug.sh`](https://github.com/different-ai/openwork/blob/main/scripts/openwork-debug.sh).
- **`OPENWORK_WAIT_HEALTHY_SECS`** — Seconds to wait for the server to become healthy before the script proceeds. Referenced in [`scripts/openwork-debug.sh`](https://github.com/different-ai/openwork/blob/main/scripts/openwork-debug.sh).
- **`OPENWORK_APP_PORT`** — Port of the Vite dev server, defaulting to `5173`. Referenced in `scripts/dev-local.mjs`.
- **`OPENWORK_EXTRA_APP_PORTS`** — Comma-separated list of extra ports used when running multiple instances in the same worktree. Referenced in `scripts/dev-local.mjs`.

## Step-by-Step: Creating Your `.env.dev` File

Follow these steps to configure your local development environment.

1. **Copy an example file.** If a root `.env.dev` does not exist, copy a package-level `.env.example` to the repository root as `.env.dev`.
2. **Edit the values.** Fill in the placeholders for your machine, such as enabling mock keychain support or setting a custom CDP port.
3. **Run the dev command.** Execute `pnpm dev` so the scripts in `scripts/dev-local.mjs` automatically load the file.

```bash

# Copy a package example if you do not have a root .env.dev

cp ee/apps/den-api/.env.example .env.dev

# Edit the file

nano .env.dev

# Start the default developer profile

pnpm dev

```

You can also override values ad hoc by exporting them before the command:

```bash
export OPENWORK_ELECTRON_REMOTE_DEBUG_PORT=9830
export OPENWORK_ELECTRON_USE_MOCK_KEYCHAIN=1
pnpm dev:headless-web

```

## Example `.env.dev` Configuration

Below is a practical `.env.dev` template that covers the most common OpenWork development scenarios.

```bash

# Isolate OpenWork state from your global user config

OPENWORK_DEV_MODE=1

# Electron CDP debug port (use any free high port)

OPENWORK_ELECTRON_REMOTE_DEBUG_PORT=9823

# Avoid macOS keychain prompts during local development

OPENWORK_ELECTRON_USE_MOCK_KEYCHAIN=1

# Prevent protocol registration for CI-like isolation

OPENWORK_ELECTRON_DISABLE_PROTOCOL_REGISTRATION=1

# Log file destinations

OPENWORK_DEV_LOG_FILE="$HOME/.openwork/debug/openwork-dev.log"
OPENWORK_PNPM_DEV_LOG="/tmp/openwork-test/pnpm-dev.log"
OPENWORK_PNPM_DEV_PID="/tmp/openwork-test/pnpm-dev.pid"

# Headless web settings

OPENWORK_PUBLIC_HOST=localhost
OPENWORK_WORKSPACE=/absolute/path/to/your/workspace

# Vite dev server port

OPENWORK_APP_PORT=5173

```

## Summary

- OpenWork development variables all share the **`OPENWORK_*`** prefix and live in a root `.env.dev` file.
- The dev scripts in `scripts/dev-local.mjs`, [`scripts/dev-headless-web.ts`](https://github.com/different-ai/openwork/blob/main/scripts/dev-headless-web.ts), and [`scripts/openwork-debug.sh`](https://github.com/different-ai/openwork/blob/main/scripts/openwork-debug.sh) source this file automatically when you run `pnpm dev` or related commands.
- **Electron flags** like `OPENWORK_ELECTRON_USE_MOCK_KEYCHAIN` and `OPENWORK_ELECTRON_REMOTE_DEBUG_PORT` control desktop shell behavior and debugging.
- **Headless web flags** like `OPENWORK_PUBLIC_HOST` and `OPENWORK_WORKSPACE` configure the browser-based UI launcher.
- **Logging and port variables** such as `OPENWORK_DEV_LOG_FILE` and `OPENWORK_APP_PORT` manage output paths and the Vite server.

## Frequently Asked Questions

### What file does OpenWork use for development environment variables?

OpenWork reads a root `.env.dev` file. If it is missing, the dev scripts fall back to package-specific `.env.example` files—such as `ee/apps/den-api/.env.example`—to generate a starting template. You can create this file manually or let the tooling copy an example for you.

### How do I avoid macOS keychain prompts while developing OpenWork?

Set `OPENWORK_ELECTRON_USE_MOCK_KEYCHAIN=1` in your `.env.dev` file. This tells the Electron process to use a mock keychain instead of the real OS credential store, as implemented in `scripts/dev-two-electron-demo.mjs`. The setting is especially helpful when running multiple local profiles or automated tests.

### Can I run OpenWork on a custom Vite port?

Yes. Define `OPENWORK_APP_PORT` in `.env.dev` to change the Vite dev server port from its default of `5173`. If you are running multiple instances in the same worktree, supply additional ports via the `OPENWORK_EXTRA_APP_PORTS` variable in `scripts/dev-local.mjs`.

### Is it possible to disable the `openwork://` protocol during development?

Yes. Set `OPENWORK_ELECTRON_DISABLE_PROTOCOL_REGISTRATION=1` in your `.env.dev` file. This prevents the custom protocol from being registered on your host machine, which is especially useful for isolated testing or CI environments.