Claude-skill-registry flox-publish
Use for publishing user packages to flox for use in Flox environments. Use for package distribution and sharing of builds defined in a flox environment.
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/flox-publish" ~/.claude/skills/majiayu000-claude-skill-registry-flox-publish && rm -rf "$T"
skills/data/flox-publish/SKILL.mdFlox Package Publishing Guide
Core Commands
flox publish # Publish all packages flox publish my_package # Publish single package flox publish -o myorg package # Publish to organization flox publish -o myuser package # Publish to personal namespace flox auth login # Authenticate before publishing
Publishing Workflow: Development to Runtime
Publishing packages enables a clear separation between development and runtime/consumption:
The Complete Workflow
Phase 1: Development Environment
# .flox/env/manifest.toml (in git with source code) [install] gcc.pkg-path = "gcc13" make.pkg-path = "make" python.pkg-path = "python311Full" [build.myapp] command = ''' python setup.py build mkdir -p $out/bin cp build/myapp $out/bin/ ''' version = "1.0.0"
Developers work in this environment, commit
.flox/ to git alongside source code.
Phase 2: Build and Publish
# Build the package flox build myapp # Publish to catalog flox publish -o myorg myapp
The published package contains BINARIES/ARTIFACTS (what's in
$out/), NOT source code.
Phase 3: Runtime Environment
# Separate environment (can be pushed to FloxHub) [install] myapp.pkg-path = "myorg/myapp" # The published package
Consumers create runtime environments and install the published package. No build tools needed, no source code exposed.
Key insight: You don't install the published package back into the development environment - that would be circular. Published packages are installed into OTHER environments (different projects, production, etc.).
Publishing to Flox Catalog
Prerequisites
Before publishing:
- Package defined in
section or[build].flox/pkgs/ - Environment in Git repo with configured remote
- Clean working tree (no uncommitted changes)
- Current commit pushed to remote
- All build files tracked by Git
- At least one package installed in
[install]
Authentication
Run authentication before first publish:
flox auth login
Publishing Commands
# Publish single package flox publish my_package # Publish all packages flox publish # Publish to organization flox publish -o myorg my_package # Publish to personal namespace (for testing) flox publish -o mypersonalhandle my_package
Catalog Types
Personal catalogs: Only visible to you (good for testing)
- Published to your personal namespace
- Example: User "alice" publishes "hello" → available as
alice/hello - Useful for testing before publishing to organization
Organization catalogs: Shared with team members (paid feature)
- Published to organization namespace
- Example: Org "acme" publishes "tool" → available as
acme/tool - All organization members can install
Build Validation
Flox clones your repo to a temp location and performs a clean build to ensure reproducibility. Only packages that build successfully in this clean environment can be published.
This validation ensures:
- All dependencies are declared
- Build is reproducible
- No reliance on local machine state
- Git repository is clean and up-to-date
After Publishing
- Package available in
,flox search
,flox showflox install - Metadata sent to Flox servers
- Package binaries uploaded to Catalog Store
- Install with:
flox install <catalog>/<package>
Users can then:
# Search for your package flox search my_package # See package details flox show myorg/my_package # Install the package flox install myorg/my_package
What Gets Published
Published packages contain:
- Binaries and compiled artifacts (everything in
)$out/ - Runtime dependencies specified in
runtime-packages - Package metadata (version, description)
Published packages do NOT contain:
- Source code (unless explicitly copied to
)$out/ - Build tools or build-time dependencies
- Development environment configuration
- The
directory itself.flox/
This separation allows you to share built artifacts without exposing source code.
Real-world Publishing Workflows
Application Development Workflow
Developer workflow:
-
Create development environment with build tools:
mkdir myapp && cd myapp flox init flox install gcc make python311Full -
Add source code and build definition to
:.flox/env/manifest.toml[build.myapp] command = '''make && cp myapp $out/bin/''' version = "1.0.0" -
Commit to git (environment definition + source code):
git add .flox/ src/ git commit -m "Add development environment and source" git push origin main -
Build and publish package (binaries/artifacts):
flox build myapp flox publish -o myorg myapp
Other developers:
- Clone repo:
git clone <repo> && cd myapp && flox activate - Get the same development environment with build tools
Consumers:
- Create new runtime environment:
flox init && flox install myorg/myapp - OR install into existing environment:
flox install myorg/myapp - Get the BUILT package (binaries), not source code
- Can push runtime environment to FloxHub without exposing source
Fork-based Development Pattern
- Fork upstream repo (e.g.,
fromuser/project
)upstream/project - Add
to fork with build definitions.flox/ - Commit and push:
git push origin main - Publish package:
flox publish -o username package-name - Others can install:
flox install username/package-name
Versioning Strategies
Semantic Versioning
[build.mytool] version = "1.2.3" # Major.Minor.Patch description = "My awesome tool"
Git-based Versioning
[build.mytool] version.command = "git describe --tags" description = "My awesome tool"
File-based Versioning
[build.mytool] version.file = "VERSION.txt" description = "My awesome tool"
Dynamic Versioning from Source
[build.rustapp] version.command = "cargo metadata --no-deps --format-version 1 | jq -r '.packages[0].version'"
Publishing Multiple Variants
You can publish multiple variants of the same project:
[build.myapp] command = ''' cargo build --release mkdir -p $out/bin cp target/release/myapp $out/bin/ ''' version = "1.0.0" description = "Production build" sandbox = "pure" [build.myapp-debug] command = ''' cargo build mkdir -p $out/bin cp target/debug/myapp $out/bin/myapp-debug ''' version = "1.0.0" description = "Debug build with symbols" sandbox = "off"
Both can be published and users can choose which to install.
Testing Before Publishing
Local Testing
- Build the package:
flox build myapp
- Test the built artifact:
./result-myapp/bin/myapp --version
- Install locally to test:
flox install ./result-myapp
Personal Catalog Testing
Publish to your personal namespace first:
flox publish -o myusername myapp
Then test installation:
flox install myusername/myapp
Once validated, republish to organization:
flox publish -o myorg myapp
Common Gotchas
Branch names
Many repos use
master not main - check with git branch
Auth required
Run
flox auth login before first publish
Clean git state
Commit and push ALL changes before
flox publish:
git status # Check for uncommitted changes git add .flox/ git commit -m "Add flox build configuration" git push origin master
runtime-packages
List only what package needs at runtime, not build deps:
[install] gcc.pkg-path = "gcc" make.pkg-path = "make" [build.myapp] command = '''make && cp myapp $out/bin/''' runtime-packages = [] # No runtime deps needed
Git-tracked files only
All files referenced in build must be tracked:
git add .flox/pkgs/* git add src/ git commit -m "Add build files"
Publishing Nix Expression Builds
For Nix expression builds in
.flox/pkgs/:
- Create the Nix expression:
mkdir -p .flox/pkgs cat > .flox/pkgs/hello.nix << 'EOF' { hello }: hello.overrideAttrs (oldAttrs: { patches = (oldAttrs.patches or []) ++ [ ./my.patch ]; }) EOF
- Track with Git:
git add .flox/pkgs/* git commit -m "Add hello package" git push
- Publish:
flox publish hello
Publishing Configuration and Assets
You can publish non-code artifacts:
Configuration templates
[build.nginx-config] command = ''' mkdir -p $out/etc cp nginx.conf $out/etc/ cp -r conf.d $out/etc/ ''' version = "1.0.0" description = "Organization Nginx configuration"
Protocol buffers
[build.api-proto] command = ''' mkdir -p $out/share/proto cp proto/**/*.proto $out/share/proto/ ''' version = "2.1.0" description = "API protocol definitions"
Teams install and reference via
$FLOX_ENV/etc/ or $FLOX_ENV/share/.
Continuous Integration Publishing
GitHub Actions Example
name: Publish to Flox on: push: tags: - 'v*' jobs: publish: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Install Flox run: | curl -fsSL https://downloads.flox.dev/by-env/stable/install | bash - name: Authenticate env: FLOX_AUTH_TOKEN: ${{ secrets.FLOX_AUTH_TOKEN }} run: flox auth login --token "$FLOX_AUTH_TOKEN" - name: Publish package run: flox publish -o myorg mypackage
GitLab CI Example
publish: stage: deploy only: - tags script: - curl -fsSL https://downloads.flox.dev/by-env/stable/install | bash - flox auth login --token "$FLOX_AUTH_TOKEN" - flox publish -o myorg mypackage
Package Metadata Best Practices
Good Descriptions
[build.cli] description = "High-performance log shipper with filtering" # Good: specific, descriptive # Avoid: # description = "My tool" # Too vague # description = "CLI" # Not descriptive enough
Proper Versioning
- Use semantic versioning: MAJOR.MINOR.PATCH
- Increment MAJOR for breaking changes
- Increment MINOR for new features
- Increment PATCH for bug fixes
Runtime Dependencies
Only include what's actually needed at runtime:
[install] # Build-time only gcc.pkg-path = "gcc" make.pkg-path = "make" # Runtime dependency libssl.pkg-path = "openssl" [build.myapp] runtime-packages = ["libssl"] # Only runtime deps
Related Skills
- flox-builds - Building packages before publishing, dual-environment workflow
- flox-environments - Setting up development and runtime environments
- flox-sharing - Sharing environment definitions (via git or FloxHub) vs publishing packages (binaries/artifacts)