Isolated Development with Flox
Contents
This guide explains how to create isolated PostHog development environments using Flox and Git worktrees for seamless branch switching.
Key Benefits:
- Work on multiple branches simultaneously with isolated environments
- Each worktree has its own Flox environment and Python dependencies
- Quick switching between features, bug fixes, and PR reviews
- Standard
bin/startcommand works in each worktree
[!IMPORTANT] Important: Only one PostHog instance (
bin/start) can run at a time since they all use the same ports. The workflow focuses on quickly stopping one instance and starting another.
Prerequisites
- Flox installed: https://flox.dev/docs/install-flox/
- Git worktrees support (Git 2.5+)
- GitHub CLI (for PR checkout):
brew install gh - jq (for PR JSON parsing):
brew install jq - direnv (recommended):
brew install direnv
Configuration
Worktree Location
By default, worktrees are created in ~/.worktrees/posthog/. You can customize this location by setting the POSTHOG_WORKTREE_BASE environment variable:
For example:
Worktree Location Management
The phw list and phw remove commands work with all your PostHog worktrees, regardless of where they were created. This is helpful if you:
- Changed your
POSTHOG_WORKTREE_BASEsetting after creating some worktrees - Have worktrees in multiple locations
- Want to clean up old worktrees from previous setups
Example scenario:
This uses Git's native worktree tracking (git worktree list) rather than trying to guess paths.
Quick Start
1. One-Time Setup
In all these examples, replace ~/dev/posthog/posthog with your local path to the PostHog repo.
2. Daily Workflow with phw
After setup, use the phw command for everything:
Create a NEW branch
Work on EXISTING branch
Switch to EXISTING worktree
Review a Pull Request
Real-World Example
Common Workflows
Switching Between Worktrees
Since you can only run one PostHog instance at a time, the workflow focuses on quickly switching between isolated environments:
Managing Your Worktrees
Quick Reference
Commands
Workflow Benefits
- Isolated environments: Each worktree has its own Flox environment and Python dependencies
- Quick switching: Move between branches without losing work or rebuilding dependencies
- Clean separation: Different features, bug fixes, and PR reviews stay completely separate
- Standard tools: Uses familiar
bin/startcommand in each worktree
How It Works
- direnv +
.envrc: Automatically activates Flox when you enter any worktree directory - Flox Environment: Each worktree gets its own
.flox/env/manifest.tomland Python venv - UV Caching: Flox's
uv syncuses its own caching, so dependencies are efficiently shared - Git Worktrees: Each branch lives in its own directory with isolated Git state
phwfunction: Provides auto-cd functionality and smart tab completion- Git-native Management:
phw listandphw removeuse Git's authoritative worktree tracking, working with worktrees from any location
The Magic Flow
Interactive Environment Switching
When you switch between worktrees while already in a Flox environment, you'll see an interactive prompt to prevent unexpected nested environments:
Your options:
- Press Enter or 'n' (recommended): Skips activation. Run
exitfirst to cleanly switch environments - Type 'y': Proceeds with nested activation (you'll need multiple
exitcommands later) - Ctrl+C: Cancels direnv entirely so you can run
exitand retry
Best practice: When switching between worktrees, exit your current Flox environment first:
Tips and Tricks
Tab Completion
The phw function includes smart tab completion:
phw create <TAB>- Suggests "haacked/" prefixphw checkout <TAB>- Shows all available branchesphw remove <TAB>- Shows removable worktrees
Resource Management
Debugging
Troubleshooting
direnv not activating
Flox activation fails
phw command not found
Dependencies out of sync
Interactive Flox prompt behavior
Problem: You see the interactive prompt every time you switch directories
Solution: This is expected behavior when switching between worktrees. Choose the best approach:
Clean Up
Quick Setup Script
For a complete one-time setup, run:
After setup, you're ready to use commands like:
phw create haacked/feature(create from master)phw create haacked/feature my-branch(create from my-branch)phw checkout my-branchphw pr 12345