How to Configure OpenWork Profiles for Development: A Complete Guide

OpenWork uses a hierarchy of environment variables—OPENWORK_ELECTRON_USERDATA, OPENWORK_ELECTRON_APP_IDENTIFIER, and OPENWORK_DEV_PROFILE—to isolate Electron user data directories, allowing multiple independent development instances to run without interfering with production data.

OpenWork is an open-source Electron desktop application maintained at different-ai/openwork. During development, you need isolated OpenWork profiles to prevent test data from corrupting your production installation. The application implements a cascading configuration system that determines the profile directory through environment variables resolved at runtime in apps/desktop/electron/main.mjs.

Understanding the OpenWork Profile Hierarchy

The profile resolution logic is implemented in apps/desktop/electron/main.mjs (lines 38–44), where the resolveAppIdentifier function evaluates environment variables in strict precedence order:

  1. OPENWORK_ELECTRON_USERDATA – Directly specifies the exact file system path to the profile directory.
  2. OPENWORK_ELECTRON_APP_IDENTIFIER – Provides the base identifier used to construct the profile folder name.
  3. OPENWORK_DEV_PROFILE – Available only in unpacked development builds; accepts a short slug (e.g., auto, feature-x) that gets sanitized into the identifier.
  4. Legacy identifier – Fallback when no environment variables are set.

Configuring Development Profiles

Default Shared Profile

Running pnpm dev with no additional environment variables reuses the existing shared development profile. According to the dev/README.md (lines 86–98), this is the fastest way to start coding but offers no isolation between worktrees.

Isolated Worktree with Auto-Generated Profiles

Use the built-in dev:worktree script defined in package.json (line 7) to automatically configure an isolated profile:

pnpm dev:worktree

This executes OPENWORK_DEV_PROFILE=auto pnpm dev, generating a unique profile directory that prevents conflicts with other development instances.

Named Profiles for Reproducible Testing

For deterministic test environments, assign a specific profile name. The value is sanitized into a valid identifier to ensure a separate userData directory:

OPENWORK_DEV_PROFILE=my-feature pnpm dev

Mock Keychain Configuration

By default, OpenWork development profiles use a mock keychain to avoid macOS system prompts that block the Electron main loop. Control this behavior with OPENWORK_ELECTRON_USE_MOCK_KEYCHAIN (default: 1):

OPENWORK_ELECTRON_USE_MOCK_KEYCHAIN=0 pnpm dev

Setting this to 0 forces the app to use the real system keychain for authentication testing.

Remote Debugging Configuration

The development server exposes a Chrome DevTools Protocol (CDP) endpoint. Force a specific port or let Electron choose automatically:

OPENWORK_ELECTRON_REMOTE_DEBUG_PORT=0 pnpm dev

Upon startup, the application prints a banner like [openwork] dev profile=… cdp=http://127.0.0.1:9223 (as documented in dev/README.md lines 98–100), enabling direct CDP tooling integration.

Headless Web Development Mode

For browser-based testing without Electron overhead, use the headless web launcher:

pnpm dev:headless-web

This creates tmp/headless-server.json and tmp/dev-headless-web.json containing URLs, tokens, and CDP addresses while respecting the same profile isolation logic and mock keychain settings.

Practical Configuration Examples

Run multiple configuration scenarios using these tested command patterns:


# Built-in worktree helper with auto-generated profile

pnpm dev:worktree

# Stable named profile with auto-selected debug port

OPENWORK_DEV_PROFILE=feature-xyz \
OPENWORK_ELECTRON_REMOTE_DEBUG_PORT=0 \
pnpm dev

# Real keychain testing with isolated profile

OPENWORK_ELECTRON_USE_MOCK_KEYCHAIN=0 \
OPENWORK_DEV_PROFILE=auth-test \
pnpm dev

# Headless UI with captured CDP endpoint

pnpm dev:headless-web

Summary

  • OpenWork profiles are resolved through a four-level hierarchy in apps/desktop/electron/main.mjs, with OPENWORK_ELECTRON_USERDATA taking highest precedence.
  • Use pnpm dev for shared profiles or pnpm dev:worktree for automatic isolation via OPENWORK_DEV_PROFILE=auto.
  • Named profiles (OPENWORK_DEV_PROFILE=my-feature) create deterministic, isolated user data directories.
  • The mock keychain (OPENWORK_ELECTRON_USE_MOCK_KEYCHAIN=1) prevents macOS login prompts during development.
  • Headless web mode (pnpm dev:headless-web) supports profile isolation without Electron.

Frequently Asked Questions

What is the difference between OPENWORK_DEV_PROFILE and OPENWORK_ELECTRON_USERDATA?

OPENWORK_DEV_PROFILE accepts a short slug that gets sanitized into a profile identifier, useful for quick worktree isolation. OPENWORK_ELECTRON_USERDATA requires an absolute file system path and bypasses all identifier generation logic, offering direct control over the Electron userData directory location.

How do I prevent development builds from accessing my production OpenWork data?

Always set OPENWORK_DEV_PROFILE to a unique value (or use pnpm dev:worktree) before running pnpm dev. According to the source code in apps/desktop/electron/main.mjs, this ensures the app resolves a distinct userData path, completely isolating development state from production installations.

Why does OpenWork use a mock keychain by default in development?

The mock keychain prevents the native macOS "Login" dialog from blocking the Electron main loop during automated testing and rapid iteration. Set OPENWORK_ELECTRON_USE_MOCK_KEYCHAIN=0 only when specifically testing system keychain integration, as implemented around lines 100–107 of apps/desktop/electron/main.mjs.

Can I use OpenWork profiles when running the headless web mode?

Yes. The pnpm dev:headless-web command respects the same environment variables including OPENWORK_DEV_PROFILE and OPENWORK_ELECTRON_USE_MOCK_KEYCHAIN, creating isolated temporary JSON files in tmp/ while maintaining profile separation from production data.

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 →