Flox Environments

affaan-m/ECC/skills/flox-environments

作者 affaan-mef648e01899ba3e8dc6371642deaaf64b4477775无许可证275K 个星标收录于 2026年10月9日更新于 2026年10月9日仓库4天前更新

Create reproducible, cross-platform (macOS/Linux) development environments with Flox, a declarative Nix-based environment manager. Use when setting up project toolchains, installing system-level dependencies (compilers, databases, native libs), pinning exact package versions for a team, onboarding developers, running local services (PostgreSQL, Redis, Kafka), or solving 'works on my machine' problems — including agent/vibe-coding setups that need project-scoped tools without sudo. Also use when the user mentions .flox/, manifest.toml, flox activate, or FloxHub.

仅含说明DevOps & Cloud
AI 生成的概览

指导通过 manifest.toml 创建可复现的 Flox 开发环境,涵盖软件包、钩子、服务与共享。

功能
该技能说明如何使用 Flox(基于 Nix 的声明式环境管理器)定义可复现、跨平台的开发环境。内容涵盖清单结构、软件包安装与版本固定、平台专属软件包、冲突解决、各语言配方、钩子与 profile、服务、环境共享以及调试。它产出的是指导说明与清单示例,而非可执行脚本。
适用场景
适用于搭建项目工具链、安装系统级依赖、为团队固定软件包版本、新成员上手、运行本地服务,或解决不同机器上环境不一致的问题。当用户提到 .flox/、manifest.toml、flox activate 或 FloxHub,或智能体需要在无 sudo 权限下使用项目级工具时,也可使用。
运行要求
需先在 macOS、Linux 或 Docker 上安装 Flox;该技能本身不附带脚本,仅提供说明与清单示例。

Flox Environments

Flox creates reproducible development environments defined in a single TOML manifest. Every developer on the team gets identical packages, tools, and configuration — across macOS and Linux — without containers or VMs. Built on Nix with access to over 150,000 packages.

When to Activate

Use this skill when the user has an environment management problem — even if they haven't mentioned Flox. Flox is the right tool when:

  • The project needs system-level packages (compilers, databases, CLI tools) alongside language-specific dependencies
  • Reproducibility matters — the setup should work identically on a teammate's machine, in CI, or on a fresh laptop
  • The user needs multiple tools to coexist — e.g., Python 3.11 + PostgreSQL 16 + Redis + Node.js in one environment
  • Cross-platform support is needed (macOS and Linux from the same config)
  • AI agents need to install tools — Flox lets agents add packages to a project-scoped environment without sudo, system pollution, or sandbox restrictions

If the user just needs a single language runtime with no system dependencies, standard tooling (nvm, pyenv, rustup alone) may suffice. If they need full OS-level isolation, containers might be more appropriate. Flox sits in the sweet spot: declarative, reproducible environments without container overhead.

Prerequisite: Flox must be installed first — see flox.dev/docs for macOS, Linux, and Docker.

Core Concepts

Flox environments are defined in .flox/env/manifest.toml and activated with flox activate. The manifest declares packages, environment variables, setup hooks, and shell configuration — everything needed to reproduce the environment anywhere.

Key paths:

  • .flox/env/manifest.toml — Environment definition (commit this)
  • $FLOX_ENV — Runtime path to installed packages (like /usr — contains bin/, lib/, include/)
  • $FLOX_ENV_CACHE — Persistent local storage for caches, venvs, data (survives rebuilds)
  • $FLOX_ENV_PROJECT — Project root directory (where .flox/ lives)

Essential Commands

bash
flox init                       # Create new environmentflox search <package> [--all]   # Search for packagesflox show <package>             # Show available versionsflox install <package>          # Add a packageflox list                       # List installed packagesflox activate                   # Enter environmentflox activate -- <cmd>          # Run a command in the environment without a subshellflox edit                       # Edit manifest interactively

Manifest Structure

toml
# .flox/env/manifest.toml
[install]# Packages to install — the core of the environmentripgrep.pkg-path = "ripgrep"jq.pkg-path = "jq"
[vars]# Static environment variablesDATABASE_URL = "postgres://localhost:5432/myapp"
[hook]# Non-interactive setup scripts (run every activation)on-activate = """  echo "Environment ready""""
[profile]# Shell functions and aliases (available in interactive shell)common = """  alias dev="npm run dev""""
[options]# Supported platformssystems = ["x86_64-linux", "aarch64-linux", "x86_64-darwin", "aarch64-darwin"]

Package Installation Patterns

Basic Installation

toml
[install]nodejs.pkg-path = "nodejs"python.pkg-path = "python311"rustup.pkg-path = "rustup"

Version Pinning

toml
[install]nodejs.pkg-path = "nodejs"nodejs.version = "^20.0"          # Semver range: latest 20.x
postgres.pkg-path = "postgresql"postgres.version = "16.2"         # Exact version

Platform-Specific Packages

toml
[install]# Linux-only toolsvalgrind.pkg-path = "valgrind"valgrind.systems = ["x86_64-linux", "aarch64-linux"]
# macOS frameworksSecurity.pkg-path = "darwin.apple_sdk.frameworks.Security"Security.systems = ["x86_64-darwin", "aarch64-darwin"]
# GNU tools on macOS (where BSD defaults differ)coreutils.pkg-path = "coreutils"coreutils.systems = ["x86_64-darwin", "aarch64-darwin"]

Resolving Package Conflicts

When two packages install the same binary, use priority (lower number wins):

toml
[install]gcc.pkg-path = "gcc12"gcc.priority = 3
clang.pkg-path = "clang_18"clang.priority = 5               # gcc wins file conflicts

Use pkg-group to group packages that should resolve versions together:

toml
[install]python.pkg-path = "python311"python.pkg-group = "python-stack"
pip.pkg-path = "python311Packages.pip"pip.pkg-group = "python-stack"    # Resolves together with python

Language-Specific Recipes

Python with uv

toml
[install]python.pkg-path = "python311"uv.pkg-path = "uv"
[vars]UV_CACHE_DIR = "$FLOX_ENV_CACHE/uv-cache"PIP_CACHE_DIR = "$FLOX_ENV_CACHE/pip-cache"
[hook]on-activate = """  venv="$FLOX_ENV_CACHE/venv"  if [ ! -d "$venv" ]; then    uv venv "$venv" --python python3  fi  if [ -f "$venv/bin/activate" ]; then    source "$venv/bin/activate"  fi
  if [ -f requirements.txt ] && [ ! -f "$FLOX_ENV_CACHE/.deps_installed" ]; then    uv pip install --python "$venv/bin/python" -r requirements.txt --quiet    touch "$FLOX_ENV_CACHE/.deps_installed"  fi"""

Node.js

toml
[install]nodejs.pkg-path = "nodejs"nodejs.version = "^20.0"
[hook]on-activate = """  if [ -f package.json ] && [ ! -d node_modules ]; then    npm install --silent  fi"""

Rust

toml
[install]rustup.pkg-path = "rustup"pkg-config.pkg-path = "pkg-config"openssl.pkg-path = "openssl"
[vars]RUSTUP_HOME = "$FLOX_ENV_CACHE/rustup"CARGO_HOME = "$FLOX_ENV_CACHE/cargo"
[profile]common = """  export PATH="$CARGO_HOME/bin:$PATH""""

Go

toml
[install]go.pkg-path = "go"gopls.pkg-path = "gopls"delve.pkg-path = "delve"
[vars]GOPATH = "$FLOX_ENV_CACHE/go"GOBIN = "$FLOX_ENV_CACHE/go/bin"
[profile]common = """  export PATH="$GOBIN:$PATH""""

C/C++

toml
[install]gcc.pkg-path = "gcc13"gcc.pkg-group = "compilers"
# IMPORTANT: gcc alone doesn't expose libstdc++ headers — you need gcc-unwrappedgcc-unwrapped.pkg-path = "gcc-unwrapped"gcc-unwrapped.pkg-group = "libraries"
cmake.pkg-path = "cmake"cmake.pkg-group = "build"
gnumake.pkg-path = "gnumake"gnumake.pkg-group = "build"
gdb.pkg-path = "gdb"gdb.systems = ["x86_64-linux", "aarch64-linux"]

Hooks and Profile

Hooks — Non-Interactive Setup

Hooks run on every activation. Keep them fast and idempotent. Rule of thumb: if it should happen automatically, put it in [hook]; if the user should be able to type it, put it in [profile].

toml
[hook]on-activate = """  setup_database() {    if [ ! -d "$FLOX_ENV_CACHE/pgdata" ]; then      initdb -D "$FLOX_ENV_CACHE/pgdata" --no-locale --encoding=UTF8    fi  }  setup_database"""

Profile — Interactive Shell Configuration

Profile code is available in the user's shell session.

toml
[profile]common = """  dev() { npm run dev; }  test() { npm run test -- "$@"; }"""

Anti-Patterns

Absolute Paths

toml
# BAD — breaks on other machines[vars]PROJECT_DIR = "/home/alice/projects/myapp"
# GOOD — use Flox environment variables[vars]PROJECT_DIR = "$FLOX_ENV_PROJECT"

Using exit in Hooks

toml
# BAD — kills the shell[hook]on-activate = """  if [ ! -f config.json ]; then    echo "Missing config"    exit 1  fi"""
# GOOD — return from hook, don't exit[hook]on-activate = """  if [ ! -f config.json ]; then    echo "Missing config — run setup first"    return 1  fi"""

Storing Secrets in Manifest

toml
# BAD — manifest is committed to git[vars]API_KEY = "<set-at-runtime>"
# GOOD — reference external config or pass at runtime# Use: API_KEY="<your-api-key>" flox activate[vars]API_KEY = "${API_KEY:-}"

Slow Hooks Without Idempotency Guards

toml
# BAD — reinstalls every activation[hook]on-activate = """  pip install -r requirements.txt"""
# GOOD — skip if already installed[hook]on-activate = """  if [ ! -f "$FLOX_ENV_CACHE/.deps_installed" ]; then    uv pip install -r requirements.txt --quiet    touch "$FLOX_ENV_CACHE/.deps_installed"  fi"""

Putting User Commands in Hooks

toml
# BAD — hook functions aren't available in the interactive shell[hook]on-activate = """  deploy() { kubectl apply -f k8s/; }"""
# GOOD — use [profile] for user-invokable functions[profile]common = """  deploy() { kubectl apply -f k8s/; }"""

Full-Stack Example

A complete environment for a Python API with PostgreSQL:

toml
[install]python.pkg-path = "python311"uv.pkg-path = "uv"postgresql.pkg-path = "postgresql_16"redis.pkg-path = "redis"jq.pkg-path = "jq"curl.pkg-path = "curl"
[vars]UV_CACHE_DIR = "$FLOX_ENV_CACHE/uv-cache"DATABASE_URL = "postgres://localhost:5432/myapp"REDIS_URL = "redis://localhost:6379"
[hook]on-activate = """  if [ ! -d "$FLOX_ENV_CACHE/pgdata" ]; then    initdb -D "$FLOX_ENV_CACHE/pgdata" --no-locale --encoding=UTF8  fi
  venv="$FLOX_ENV_CACHE/venv"  if [ ! -d "$venv" ]; then    uv venv "$venv" --python python3  fi  if [ -f "$venv/bin/activate" ]; then    source "$venv/bin/activate"  fi
  if [ -f requirements.txt ] && [ ! -f "$FLOX_ENV_CACHE/.deps_installed" ]; then    uv pip install --python "$venv/bin/python" -r requirements.txt --quiet    touch "$FLOX_ENV_CACHE/.deps_installed"  fi"""
[profile]common = """  serve() { uvicorn app.main:app --reload --host 0.0.0.0 --port 8000; }  migrate() { alembic upgrade head; }"""
[services]postgres.command = "postgres -D $FLOX_ENV_CACHE/pgdata -k $FLOX_ENV_CACHE"redis.command = "redis-server --port 6379 --daemonize no"
[options]systems = ["x86_64-linux", "aarch64-linux", "x86_64-darwin", "aarch64-darwin"]

Activate with services: flox activate --start-services

Environment Sharing

Flox environments are git-native. Commit the .flox/ directory and every collaborator gets the same environment:

bash
git add .flox/git commit -m "Add Flox environment"# Teammates just run:git clone <repo> && cd <repo> && flox activate

For reusable base environments across projects, push to FloxHub:

bash
flox push                         # Push environment to FloxHubflox activate -r owner/env-name   # Activate remote environment anywhere

Compose environments with [include]:

toml
[include]base.floxhub = "myorg/python-base"
[install]# Project-specific additions on top of basefastapi.pkg-path = "python311Packages.fastapi"

AI-Assisted and Vibe Coding

Flox is ideal for AI-assisted development and vibe coding workflows. When an AI agent needs a tool that isn't available in the current environment — a compiler, a database, a linter, a CLI utility — it can add it to the project's Flox manifest without requiring sudo access, polluting system packages, or hitting sandbox restrictions.

Why this matters for agents:

  • No sudo required — flox install works entirely in user space, so agents can add packages without elevated permissions
  • Project-scoped — packages are installed into the project environment only, not globally, so different projects can have different versions without conflict
  • Sandbox-friendly — agents running in sandboxed or restricted environments can still install the tools they need through Flox
  • Reversible — every change is captured in manifest.toml, so unwanted packages can be removed cleanly with no system residue
  • Reproducible — when an agent sets up an environment, that exact setup is committed to git and works for everyone

Agent workflow pattern:

bash
# Agent discovers it needs a tool (e.g., jq for JSON processing)flox search jq                    # Verify the package existsflox install jq                   # Install into project environment
# Or for more control, edit the manifest directlytmp_manifest="$(mktemp)"flox list -c > "$tmp_manifest"# Add the package to [install] section, then applyflox edit -f "$tmp_manifest"
# Run a command with the tool availableflox activate -- jq '.results[]' data.json

This makes Flox a natural fit for any workflow where Claude Code or other AI agents need to bootstrap project tooling on the fly.

Debugging

bash
flox list -c                      # Show raw manifestflox activate -- which python     # Check which binary resolvesflox activate -- env | grep FLOX  # See Flox environment variablesflox search <package> --all       # Broader package search (case-sensitive)

Common issues:

  • Package not found: Search is case-sensitive — try flox search --all
  • File conflicts between packages: Add priority to the package that should win
  • Hook failures: Use return not exit; guard with ${FLOX_ENV_CACHE:-}
  • Stale dependencies: Delete the $FLOX_ENV_CACHE/.deps_installed flag file

Related Skills

The following skills are available as part of the Flox Claude Code plugin for deeper integration:

  • flox-services — Service management, database setup, background processes
  • flox-builds — Reproducible builds and packaging with Flox
  • flox-containers — Create Docker/OCI containers from Flox environments
  • flox-sharing — Environment composition, remote environments, team patterns
  • flox-cuda — CUDA and GPU development environments

Learn more and install at flox.dev/docs

来源与署名

来源:affaan-m/ECC位于skills/flox-environments提交ef648e0

许可证: 无许可证

内容归原作者所有。SourceWeft 从公开仓库中收录这些内容。

举报或申请下架