V3 packages (beta)#
Beta — not for production use
V3 is an opt-in preview of the next conda repodata revision and is
still under active development. The on-disk repodata format, the
index.json layout, recipe fields (build.flags, requirements.extras,
…) and the MatchSpec bracket syntax described on this page can and
will change in backwards-incompatible ways before V3 is finalized.
Concretely, this means:
- Packages built with today's
--v3may stop being parseable by a future rattler-build / rattler / pixi without a rebuild. - The
repodata_revision: 3shape is not stable; the field name, value, and surrounding schema may all change. - Recipes using V3-only features may need edits when the syntax stabilizes.
Do not publish V3 packages to channels that other users or CI systems depend on. Use V3 only for experimentation, prototyping, and feedback — and expect to rebuild from source when the format stabilizes. Track the discussion in the relevant CEPs and the rattler-build issue tracker before depending on it.
V3 is a new revision of the conda repodata format. It extends the existing
package record with two new fields and adds a richer MatchSpec bracket
syntax that lets you express conditional, optional and variant-tagged
dependencies. Rattler-Build can produce V3 packages and parse V3 recipes,
but only when the feature is explicitly enabled.
Opting in#
V3 is gated behind a single flag. There are two ways to turn it on:
-
Pass
--v3on the command line: -
Or use the equivalent option from the Python bindings / library API (
CommonData::new(..., v3: true, ...),RenderConfig::new().with_v3(true),ParseConfig { v3: true }).
When the flag is off (the default), Rattler-Build behaves exactly like before:
- Recipes that use V3-only fields (
build.flags,requirements.extras) fail to evaluate with an error pointing at--v3. MatchSpecstrings that use V3-only bracket keys (flags=[…],extras=[…],when="…") fail to parse with the same error.- Built packages get the legacy
index.jsonshape — there is norepodata_revisionfield and noflagsarray.
When the flag is on:
- The new recipe fields are accepted and round-tripped through Stage 0/Stage 1 evaluation.
- V3
MatchSpecsyntax is parsed everywhere a dependency string is allowed (requirements.{build,host,run,run_constraints,extras},run_exports). - Built packages are tagged with
repodata_revision: 3inindex.jsonand carry their declared variant flags in a top-levelflagsarray. Optional dependency groups are written into theextra_dependsmapping.
What V3 adds#
build.flags — package variant flags#
Flags are short lowercase tags that describe a variant of a package — the
canonical examples are cuda, blas:openblas, mpi:mpich. They are stored
on the package record and can be matched by downstream specs (see below).
A flag must match ^[a-z0-9_]+(:[a-z0-9_]+)?$ — i.e. lowercase ASCII,
digits and underscores, optionally with a single :-separated suffix.
Flags are conditional and templated like other recipe lists, so this is
valid:
Flags that depend on a Jinja variable participate in variant hashing, so each flag combination produces its own build hash.
requirements.extras — optional dependency groups#
extras is a mapping from a group name to a list of dependencies. The group
is not installed by default — consumers opt in via the extras=[…]
MatchSpec bracket key. This mirrors the "optional dependencies" idea from
pyproject.toml.
requirements:
run:
- python >=3.10
extras:
plot:
- matplotlib >=3.8
full:
- matplotlib >=3.8
- pandas >=2
A consumer that wants the plot group writes:
In the built package, optional groups land in
index.json::extra_depends.
Richer MatchSpec syntax#
V3 extends the bracket form of MatchSpec with three new keys. They can be
combined with the existing keys (version=…, build=…, channel=…, …).
flags=[…] — match by variant flag#
Selects builds whose flags array contains the listed entries. A *
suffix is a glob over the second segment.
requirements:
run:
- pytorch[flags=[cuda]]
- numpy[flags=[blas:*]] # any BLAS flavour
- mamba[flags=[cuda, blas:openblas]]
when="…" — conditional dependencies#
A spec with when="…" is only included when the embedded predicate is
satisfied by the rest of the resolved environment. This replaces the old
; if syntax (which is now deprecated).
requirements:
run:
- python
- scipy[when="python >=3.10"]
- numpy >=2.0[when="python >=3.10 and __linux"]
The predicate is itself a small spec language and supports and, or,
not, parentheses, virtual packages (__linux, __glibc, …) and nested
MatchSpecs.
extras=[…] — pull in optional groups#
Already shown above — uses the group names declared by the producing
package's requirements.extras.
What ends up in index.json#
A V3 build writes (in addition to the existing fields):
{
"repodata_revision": 3,
"flags": ["cuda", "blas:openblas"],
"extra_depends": {
"plot": ["matplotlib >=3.8"]
}
}
flags and extra_depends are omitted when empty. The repodata_revision
field is the signal that downstream tools should use the V3 parser; it is
only written when the build was run with --v3.
Compatibility notes#
- V3 packages are still valid
.condaarchives — they only differ in metadata. Older clients that ignore unknown fields will still install the base package, but will silently miss conditional dependencies, flag-based selection and optional groups. - Consuming a V3 package correctly requires a resolver that understands
V3 (recent
rattler/pixi/condaversions). Check your toolchain before publishing. - Mixing V3 syntax in a recipe without passing
--v3is always an error — it never silently downgrades.