Skip to content

Managing Multi-Platform Dependencies in uv with Platform Markers #5

@rnoro

Description

@rnoro

Summary

This guide demonstrates how to manage dependencies across multiple platforms (Desktop, Mobile, WASM) in uv using environment markers, particularly platform_system and platform_machine.

Context

When building Python projects targeting multiple platforms (Linux, Windows, macOS, iOS, WASM), different platforms may require:

  • Platform-specific packages (e.g., pywin32 for Windows only)
  • Limited package availability (e.g., only pillow has iOS wheels)
  • Platform-appropriate alternatives (e.g., pure Python packages for WASM)

Solution

Use PEP 508 environment markers in pyproject.toml to conditionally install dependencies based on the target platform.

Desktop Platforms (Linux, Windows, macOS)

Most packages work across all desktop platforms with the same version:

[project]
dependencies = [
    # Shared across all desktop platforms
    "numpy>=2.3.0; platform_system in 'Linux Windows Darwin'",
    "pandas>=2.2.3; platform_system in 'Linux Windows Darwin'",
    "requests>=2.32.0; platform_system in 'Linux Windows Darwin'",
    
    # Platform-specific packages
    "psutil>=6.1.0; platform_system == 'Linux'",
    "pywin32>=308; platform_system == 'Windows'",
    "pyobjc-framework-cocoa>=10.3.1; platform_system == 'Darwin'",
]

Mobile Platforms (iOS)

Very limited wheel support - currently only pillow provides official iOS wheels:

dependencies = [
    # iOS arm64 devices only (excludes simulator)
    "pillow>=11.0.0; platform_system == 'iOS' and platform_machine == 'arm64'",
]

WASM/Emscripten

Limited to pure Python packages or Pyodide-compatible packages:

dependencies = [
    "micropip>=0.6.0; platform_system == 'Emscripten'",
    "requests>=2.32.0; platform_system == 'Emscripten'",
    "python-dotenv>=1.0.1; platform_system == 'Emscripten'",
]

Testing

Verify dependencies for different platforms using:

# Desktop platforms
uv tree --python-platform windows
uv tree --python-platform linux
uv tree --python-platform macos

uv tree --python-platform x86_64-unknown-linux-gnu
uv tree --python-platform x86_64-pc-windows-msvc
uv tree --python-platform x86_64-apple-darwin
uv tree --python-platform aarch64-apple-darwin

# Mobile platforms
uv tree --python-platform arm64-apple-ios
uv tree --python-platform x86_64-apple-ios-simulator

# WASM
uv tree --python-platform wasm32-pyodide2024

Key Markers

  • platform_system: 'Linux', 'Windows', 'Darwin', 'iOS', 'Android', 'Emscripten'
  • platform_machine: 'x86_64', 'arm64', 'aarch64', 'wasm32', etc.
  • Operators: ==, !=, in, and, or, ()

Best Practices

  1. Keep it simple: Most desktop platforms can share the same versions
  2. Avoid over-constraining: Let uv resolve compatible versions automatically
  3. Use in operator: Simplifies multiple platform conditions
    # Good
    "numpy>=2.3.0; platform_system in 'Linux Windows Darwin'"
    
    # Verbose
    "numpy>=2.3.0; platform_system == 'Linux' or platform_system == 'Windows' or platform_system == 'Darwin'"
  4. Platform-specific only when necessary: Only add markers for packages that truly need them

References

Metadata

Metadata

Assignees

Labels

help wantedExtra attention is needed

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions