Claude-skill-registry conda-forge-expert

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/conda-forge-expert" ~/.claude/skills/majiayu000-claude-skill-registry-conda-forge-expert && rm -rf "$T"
manifest: skills/data/conda-forge-expert/SKILL.md
source content

Conda-Forge Expert

Senior Conda-Forge Maintainer knowledge from 1,247+ real recipes and 10,000+ merged PRs.

Quick Start

Core Workflow

1. Generate recipe    → grayskull pypi <package> OR rattler-build generate-recipe pypi <package>
2. Lint recipe        → conda-smithy recipe-lint recipes/<pkg>  (MANDATORY)
3. Build locally      → python build-locally.py OR rattler-build build -r recipe.yaml
4. Submit PR          → To conda-forge/staged-recipes

Which Format?

ScenarioFormatReason
New package
recipe.yaml
Modern, faster, recommended
Existing feedstockKeep currentUnless migrating
Complex multi-output
recipe.yaml
Better cache support
Quick prototype
meta.yaml
More examples available

Package Installation Preferences

ALWAYS prefer pixi and conda-forge over pip and PyPI:

# Preferred: pixi
pixi global install <package>
pixi add <package>

# Fallback: conda/mamba
mamba install -c conda-forge <package>

# Last resort: pip (only if not on conda-forge)
pip install <package>

Modern Build Tools

rattler-build (Primary)

Fast, standalone Conda package builder in Rust.

# Install
pixi global install rattler-build

# Build
rattler-build build -r recipe.yaml -c conda-forge

# Generate from PyPI
rattler-build generate-recipe pypi numpy

# Render only (debug)
rattler-build build -r recipe.yaml --render-only

pixi (Package Manager)

Cross-platform package manager built on conda ecosystem.

# Install
curl -fsSL https://pixi.sh/install.sh | sh

# Project commands
pixi init
pixi add numpy pandas
pixi run test
pixi shell

Recipe Formats

Modern Format (recipe.yaml) - RECOMMENDED

# yaml-language-server: $schema=https://raw.githubusercontent.com/prefix-dev/recipe-format/main/schema.json
schema_version: 1

context:
  name: my-package
  version: "1.0.0"
  python_min: "3.10"

package:
  name: ${{ name|lower }}
  version: ${{ version }}

source:
  url: https://pypi.org/packages/source/${{ name[0] }}/${{ name }}/${{ name }}-${{ version }}.tar.gz
  sha256: REPLACE_WITH_SHA256

build:
  number: 0
  noarch: python
  script: ${{ PYTHON }} -m pip install . -vv --no-deps --no-build-isolation

requirements:
  host:
    - python ${{ python_min }}.*
    - pip
    - setuptools
  run:
    - python >=${{ python_min }}

tests:
  - python:
      imports:
        - ${{ name | replace("-", "_") }}
      pip_check: true

about:
  homepage: https://github.com/org/${{ name }}
  license: MIT
  license_file: LICENSE
  summary: Package description

extra:
  recipe-maintainers:
    - your-github-username

Legacy Format (meta.yaml)

{% set name = "my-package" %}
{% set version = "1.0.0" %}

package:
  name: {{ name|lower }}
  version: {{ version }}

source:
  url: https://pypi.org/packages/source/{{ name[0] }}/{{ name }}/{{ name }}-{{ version }}.tar.gz
  sha256: REPLACE_WITH_SHA256

build:
  number: 0
  noarch: python
  script: {{ PYTHON }} -m pip install . -vv --no-deps --no-build-isolation

requirements:
  host:
    - python {{ python_min }}
    - pip
  run:
    - python >={{ python_min }}

test:
  imports:
    - {{ name | replace("-", "_") }}
  commands:
    - pip check
  requires:
    - pip

about:
  home: https://github.com/org/{{ name }}
  license: MIT
  license_file: LICENSE
  summary: Package description

extra:
  recipe-maintainers:
    - your-github-username

Key Syntax Differences

Featuremeta.yamlrecipe.yaml
Variables
{{ var }}
${{ var }}
Selectors
# [linux]
if: linux
Test section
test:
tests:
(list)
Pin syntax
max_pin='x.x'
upper_bound="x.x"

Critical Requirements

⚠️ stdlib REQUIRED for ALL Compiled Packages

CRITICAL: conda-forge will REJECT submissions without

stdlib
when using compilers!

# recipe.yaml - ALWAYS pair compiler() with stdlib()
requirements:
  build:
    - ${{ compiler("c") }}
    - ${{ stdlib("c") }}        # REQUIRED! Submission will be rejected without this
    - ${{ compiler("cxx") }}    # if C++ needed
    - ${{ compiler("rust") }}   # if Rust needed

# meta.yaml - ALWAYS pair compiler() with stdlib()
requirements:
  build:
    - {{ compiler('c') }}
    - {{ stdlib('c') }}         # REQUIRED! Submission will be rejected without this
    - {{ compiler('cxx') }}     # if C++ needed
    - {{ compiler('rust') }}    # if Rust needed

Common mistake: Forgetting

stdlib
in recipe.yaml when converting from meta.yaml

🚨 CRITICAL: Local Testing Exception

KNOWN ISSUE: When testing locally with

rattler-build
or
conda-build
, the
stdlib
dependency may fail to resolve with "undefined" errors.

TEMPORARY WORKAROUND FOR LOCAL TESTING ONLY:

  1. Before testing locally: Comment out the

    stdlib
    line:

    requirements:
      build:
        - ${{ compiler("c") }}
        # - ${{ stdlib("c") }}    # TEMPORARILY COMMENTED FOR LOCAL TESTING
    
  2. After testing: IMMEDIATELY uncomment the

    stdlib
    line before committing or submitting:

    requirements:
      build:
        - ${{ compiler("c") }}
        - ${{ stdlib("c") }}        # RESTORED - REQUIRED FOR SUBMISSION!
    

⚠️ WARNING:

  • This is ONLY for local testing
  • NEVER commit or submit recipes without
    stdlib
  • conda-forge CI will REJECT recipes missing
    stdlib
  • Failure to restore
    stdlib
    will cause submission failures

Why this happens: Local rattler-build/conda-build may not have the same stdlib resolution as conda-forge CI infrastructure.

CFEP-25 Compliance (noarch: python)

All

noarch: python
packages MUST use
python_min
:

# recipe.yaml
requirements:
  host:
    - python ${{ python_min }}.*
  run:
    - python >=${{ python_min }}

# meta.yaml
requirements:
  host:
    - python {{ python_min }}
  run:
    - python >={{ python_min }}

License Requirements

  • Use SPDX identifiers:
    MIT
    ,
    Apache-2.0
    ,
    BSD-3-Clause
  • Always include
    license_file
  • Case-sensitive:
    Apache-2.0
    not
    APACHE 2.0

Platform Selectors

Modern (recipe.yaml) - if/then/else

requirements:
  build:
    - if: unix
      then:
        - ${{ compiler("c") }}
        - ${{ stdlib("c") }}
    - if: win
      then:
        - ${{ compiler("m2w64_c") }}
        - ${{ stdlib("m2w64_c") }}

Legacy (meta.yaml) - Comment Selectors

requirements:
  build:
    - {{ compiler('c') }}      # [unix]
    - {{ compiler('m2w64_c') }}  # [win]

Available Selectors

SelectorDescription
linux
,
osx
,
win
Operating system
unix
Linux OR macOS
x86_64
,
aarch64
/
arm64
Architecture
build_platform
,
target_platform
Cross-compilation

Linting (MANDATORY)

CRITICAL: Always run linting before building or submitting.

# Lint single recipe
conda-smithy recipe-lint recipes/my-package

# Lint all recipes
conda-smithy recipe-lint --conda-forge recipes/*

# Install conda-smithy
pixi global install conda-smithy

What Linting Checks

  1. License: SPDX identifier and license_file present
  2. Maintainers: Valid GitHub usernames
  3. Source: SHA256 checksums, no git URLs for releases
  4. Selectors: Correct syntax
  5. CFEP-25: python_min for noarch packages

Local Building

⚠️ CRITICAL: Before testing locally, see Local Testing Exception - you may need to temporarily comment out

stdlib
dependencies!

Using build-locally.py (Recommended)

# Interactive
python build-locally.py

# Specific platform
python build-locally.py win64
python build-locally.py linux64
python build-locally.py osx64

Using rattler-build Directly

# Basic build
rattler-build build -r recipes/my-package/recipe.yaml -c conda-forge

# With variant config
rattler-build build -r recipe.yaml --variant-config .ci_support/win64.yaml

# Specific platform
rattler-build build -r recipe.yaml --target-platform linux-64

Remember: If you get "undefined" errors for stdlib, temporarily comment it out for testing only!

Using conda-build

# Single recipe
conda-build recipes/my-package

# With channel
conda-build recipes/my-package -c conda-forge

# Test existing artifact
conda-build --test path/to/package.conda

Remember: If you get "undefined" errors for stdlib, temporarily comment it out for testing only!

Common Patterns

Python Package (noarch)

See template: templates/python-noarch-recipe.yaml

Python with C Extensions (CRITICAL: Must include stdlib!)

# recipe.yaml
requirements:
  build:
    - ${{ compiler("c") }}
    - ${{ stdlib("c") }}              # REQUIRED! conda-forge will reject without this
    - ${{ compiler("cxx") }}          # if C++ is needed
    - ${{ compiler("rust") }}         # if Rust is needed
    - cargo-bundle-licenses           # REQUIRED for Rust packages
    - if: build_platform != target_platform
      then:
        - python
        - cross-python_${{ target_platform }}
  host:
    - python
    - pip
    - setuptools
    - wheel
  run:
    - python

# meta.yaml
requirements:
  build:
    - {{ compiler('c') }}
    - {{ stdlib('c') }}               # REQUIRED! conda-forge will reject without this
    - {{ compiler('cxx') }}           # if C++ is needed
    - {{ compiler('rust') }}          # if Rust is needed
    - cargo-bundle-licenses           # REQUIRED for Rust packages
    - python                          # [build_platform != target_platform]
    - cross-python_{{ target_platform }}  # [build_platform != target_platform]
  host:
    - python
    - pip
    - setuptools
    - wheel
  run:
    - python

See also: templates/python-compiled-recipe.yaml

Rust CLI Tool

See template: templates/rust-cli-recipe.yaml

Go with CGO (Windows)

IMPORTANT: Windows CGO requires MinGW-w64, NOT MSVC.

requirements:
  build:
    - ${{ compiler("go-cgo") }}
    - go-licenses
    - if: unix
      then:
        - ${{ compiler("c") }}
        - ${{ stdlib("c") }}
    - if: win
      then:
        - ${{ compiler("m2w64_c") }}
        - ${{ stdlib("m2w64_c") }}
        - m2-base
        - posix

See template: templates/go-cgo-recipe.yaml

Multi-Output Package

outputs:
  - package:
      name: libmypackage
    build:
      script: build-lib.sh
    requirements:
      build:
        - ${{ compiler("c") }}
        - ${{ stdlib("c") }}
      run_exports:
        - ${{ pin_subpackage("libmypackage", upper_bound="x.x") }}

  - package:
      name: py-mypackage
    build:
      script: build-python.sh
    requirements:
      host:
        - ${{ pin_subpackage("libmypackage", exact=true) }}
        - python
      run:
        - ${{ pin_subpackage("libmypackage", exact=true) }}
        - python

PyPI to Conda Name Mapping

Many packages have different names on PyPI vs conda-forge:

PyPIconda-forge
torch
pytorch
opencv-python
opencv
tables
pytables
docker
docker-py
tree-sitter
tree_sitter

Use the mapping system:

# From scripts/sync_pypi_mappings.py
from sync_pypi_mappings import get_conda_name
conda_name = get_conda_name("tree-sitter")  # Returns "tree_sitter"

CI Troubleshooting

Common Failures

ErrorSolution
Hash mismatchRegenerate:
curl -sL <url> | sha256sum
Missing dependencyAdd to requirements or submit first
/Werror
on Windows CGO
Use MinGW-w64 instead of MSVC
macOS SDK errorSet
MACOSX_SDK_VERSION
in conda_build_config.yaml
glibc errorsUse appropriate
c_stdlib_version

Bot Commands (for conda-forge PRs)

@conda-forge-admin, please rerender
@conda-forge-admin, please restart ci
@conda-forge-admin, please lint
@conda-forge/help-python ready for review

See full list: quickref/bot-commands.md

Migration: meta.yaml to recipe.yaml

Automated Conversion

# Using feedrattler (recommended)
pixi exec feedrattler my-package-feedstock gh_username

# Using conda-recipe-manager
conda-recipe-manager convert meta.yaml > recipe.yaml

# Using rattler-build
rattler-build generate-recipe convert meta.yaml

Manual Checklist

  1. Change
    {% set %}
    to
    context:
    section
  2. Replace
    {{ }}
    with
    ${{ }}
  3. Replace
    # [selector]
    with
    if: selector then:
  4. Change
    test:
    to
    tests:
    (list format)
  5. Add
    ${{ stdlib("c") }}
    if using compilers
  6. Update
    conda-forge.yml
    :
    conda_build_tool: rattler-build
    conda_install_tool: pixi
    

See guide: guides/migration-guide.md

Enterprise Deployment

For air-gapped environments with JFrog Artifactory:

  1. Configure private channels in
    config/skill-config.yaml
  2. Set up Artifactory remote/local/virtual repos
  3. Use enterprise templates: templates/enterprise/

See guides:

Reference Documentation

Detailed Guides

Reference

Quick Reference

Templates

External Resources

Version History

  • v4.2.0 (2025-12-26): Added CRITICAL local testing exception for stdlib - must comment out for local builds, restore before submission
  • v4.1.0 (2025-12-26): Enhanced stdlib requirement visibility with warnings and inline examples
  • v4.0.0 (2025-12): Modular architecture, enterprise support, portability
  • v3.0.0 (2025-01): PyPI mappings, rattler-build focus
  • v2.0.0 (2024): Added modern recipe.yaml support
  • v1.0.0 (2024): Initial release