Problem
Building emdash requires Python for node-gyp to compile native modules (sqlite3, node-pty, keytar). The current setup has friction points:
- Inconsistent Python detection: Users with pyenv or multiple Python installations hit errors like "Python is not set from command line or npm configuration"
- Manual configuration: Developers must manually set
PYTHON=/usr/bin/python3 or configure npm globally
- CI maintenance: Each CI job must install and configure Python separately (see lines 46-54 in release.yml)
- Onboarding friction: New contributors on different systems (Windows/Linux/macOS) have unpredictable Python setup experiences
Proposed Solution: Use uv
uv is a Python package and project manager written in Rust. It solves the Python environment problem elegantly:
- Reads
.python-version or pyproject.toml to pin Python version
- Auto-installs the specified Python version if missing
- Overrides system Python for the project, eliminating conflicts
- Works identically across Windows, Linux, macOS
- 10-100x faster than pip for CI builds
Implementation
-
Add uv to the bootstrap process:
# For Linux/macOS
curl -LsSf https://astral.sh/uv/install.sh | sh
# For Windows (Powershell)
powershell -ExecutionPolicy BypassUser -c "irm https://astral.sh/uv/install.ps1 | iex"
-
Create .python-version:
-
Update release.yml:
- name: Install uv
uses: astral-sh/setup-uv@v2
with:
version: "0.4.x"
- name: Set up Python
run: uv python install
- name: Install dependencies
run: uv pip install -r requirements.txt
-
Create requirements.txt (minimal, just for node-gyp):
-
Update local development docs to mention uv as the recommended Python setup.
Benefits
- Single source of truth for Python version (
.python-version)
- Eliminates
npm config set python workarounds
- CI becomes faster and more reliable
- New contributors have a consistent experience
- Aligns with industry trends (uv is adopted by major projects: Ruff, Astral tools, etc.)
Industry Adoption
Major projects have adopted uv for Python management:
- Ruff (Python linter)
- Anthropic's various Python projects
- Increasing adoption in JavaScript/Electron projects that need Python build tools
Backwards Compatibility
This is additive and transparent:
- Developers who already have Python set up won't see changes
- Developers without Python get a clear setup path
- CI becomes more deterministic
Questions for Discussion
- Should we pin Python 3.11 (current CI version) or allow flexibility?
- Do we want to manage additional Python dependencies beyond node-gyp, or keep it minimal?
- Should this be documented in CONTRIBUTING.md alongside other setup instructions?
Problem
Building emdash requires Python for node-gyp to compile native modules (sqlite3, node-pty, keytar). The current setup has friction points:
PYTHON=/usr/bin/python3or configure npm globallyProposed Solution: Use uv
uv is a Python package and project manager written in Rust. It solves the Python environment problem elegantly:
.python-versionorpyproject.tomlto pin Python versionImplementation
Add
uvto the bootstrap process:Create
.python-version:Update
release.yml:Create
requirements.txt(minimal, just for node-gyp):Update local development docs to mention
uvas the recommended Python setup.Benefits
.python-version)npm config set pythonworkaroundsIndustry Adoption
Major projects have adopted uv for Python management:
Backwards Compatibility
This is additive and transparent:
Questions for Discussion