conda.toml specification#
This page is the normative reference for the conda.toml workspace
manifest format read by conda-workspaces. It is the human-readable
companion to schema/conda-toml-1.schema.json and the source
material for the future Conda Enhancement Proposal that will
standardise the format across the conda ecosystem.
For tutorials and examples see Configuration and Quickstart; for plugin name aliases see Plugin format names and aliases.
Status#
Field |
Value |
|---|---|
Format name |
|
Schema version |
|
Schema URL |
|
Canonical plugin name |
|
Reference implementation |
|
Standardisation track |
Pre-CEP — see the CEP tracker issue |
Scope#
conda.toml describes a workspace: a project root that may declare
one or more conda environments composed from reusable features, plus
a set of tasks that run inside those environments. It is the
conda-native sibling of pixi.toml; the schema is a constrained
subset of pixi.toml plus one conda-specific extension, with the
explicit goal that the conda-vouched-for subset can also be consumed
by pixi. The reverse direction (pixi.toml → conda.toml) holds only
when the pixi.toml keeps to the fields described here; see Pixi
compatibility ladder below for the precise asymmetry.
Out of scope: package build recipes (use recipe.yaml), package
distribution metadata (pyproject.toml [project]), and lockfile
contents (use the companion conda.lock, see Lockfile relationship
below).
File detection#
A conda-workspaces tool MUST detect a workspace using one of these two forms, in order:
A file named
conda.tomlat the workspace root that contains a top-level[workspace]table.A file named
pyproject.tomlat the workspace root that contains a[tool.conda.workspace]table.
A conda.toml without a [workspace] table is permitted: it is
treated as a tasks-only manifest (see [tasks] below) and does not
constitute a workspace on its own.
For compatibility, conda-workspaces also reads pixi.toml (top-level
[workspace] / [project]) and pyproject.toml
[tool.pixi.workspace]. That compatibility surface is not part of
this specification — it is documented in
Configuration.
Search order#
Tools that search a directory tree for the manifest MUST consult these filenames in this order, returning the first hit:
conda.tomlpixi.tomlpyproject.toml
When more than one form is present in the same directory, conda.toml
wins. When pyproject.toml contains both [tool.conda] and
[tool.pixi] tables, [tool.conda] wins (see
Configuration).
Top-level tables#
All tables are optional unless marked required. Field types follow TOML conventions: string, integer, boolean, array, table, inline-table.
[workspace] (required when used as a workspace manifest)#
Workspace metadata.
Field |
Type |
Required |
Description |
|---|---|---|---|
|
string |
no |
Workspace name. Defaults to the workspace directory name. |
|
string |
no |
Workspace version. |
|
string |
no |
Short prose description. |
|
array of channel |
yes |
Conda channels in priority order. |
|
array of platform |
yes |
Platforms the workspace targets. Used to drive multi-platform solves. |
|
string |
no |
One of |
|
string |
no |
Where per-env prefixes live, relative to the workspace root. Default: |
A channel is either:
a string containing a channel name (
"conda-forge") or URL ("https://my.channel/label/dev"), oran inline table
{ channel = "<name-or-url>" }. Other keys (e.g.priority) are reserved and currently ignored by this version.
A platform is a conda subdir string from the closed enum defined in
the JSON schema under $defs.platform (e.g. linux-64,
osx-arm64, win-64, noarch).
[dependencies]#
Conda packages that belong to the default feature. Keys are package names; values are either a version constraint string or a detailed dependency spec.
[dependencies]
python = ">=3.10"
numpy = ">=1.24,<2"
scipy = "*"
cuda-toolkit = { version = ">=12", build = "*cuda*" }
A detailed conda dependency accepts:
Field |
Type |
Description |
|---|---|---|
|
string |
Version constraint (e.g. |
|
string |
Build-string glob (e.g. |
[pypi-dependencies]#
PyPI packages that belong to the default feature. Keys are package names; values are either a PEP 508 version-constraint string or a detailed PyPI dependency spec:
Field |
Type |
Description |
|---|---|---|
|
string |
PEP 508 constraint. |
|
string |
Local path to the package. |
|
boolean |
Install in editable mode. |
|
string |
Git repository URL. |
|
string |
Branch (with |
|
string |
Tag (with |
|
string |
Revision (with |
[activation]#
Default-feature activation settings.
Field |
Type |
Description |
|---|---|---|
|
array of string |
Shell scripts sourced on environment activation. |
|
table of |
Environment variables set on activation. |
[system-requirements]#
Default-feature system-level constraints (e.g. minimum glibc, macOS
version). All keys are strings; values are stringified version
constraints. Recognised keys mirror conda’s virtual-package names
(__glibc, __osx, __cuda, …).
[target.<platform>]#
Per-platform overrides for the default feature. <platform> MUST be
one of the platform values listed above.
Field |
Type |
Description |
|---|---|---|
|
conda deps |
Platform-specific conda overrides. |
|
PyPI deps |
Platform-specific PyPI overrides. |
[feature.<name>]#
A reusable group of dependencies and settings. <name> is an
arbitrary identifier referenced from [environments].
Field |
Type |
Description |
|---|---|---|
|
conda deps |
Conda dependencies for this feature. |
|
PyPI deps |
PyPI dependencies for this feature. |
|
array of channel |
Additional channels. |
|
array of platform |
Restrict the feature to these platforms. |
|
table |
Per-feature system requirements. |
|
table |
Per-feature activation. |
|
table of |
Per-platform dep overrides for the feature. |
|
table |
Tasks contributed by this feature; merged into the workspace task set. |
[environments]#
A named environment is a composition of one or more features plus
(by default) the default feature defined by the top-level
[dependencies], [pypi-dependencies], [activation] and
[system-requirements] tables.
Two forms are accepted:
[environments]
test = ["test"] # shorthand
docs = { features = ["docs"], no-default-feature = false }
Field |
Type |
Description |
|---|---|---|
|
array of string |
Feature names to include in addition to the default feature. |
|
string |
Solve-group identifier; environments in the same solve-group are version-coordinated. |
|
boolean |
If |
When [environments] is omitted entirely, a single implicit
environment named default is used, composed from the default feature
only.
[tasks]#
Named tasks runnable via conda task run <name>. Each value is
either a command string or a task table.
Field |
Type |
Description |
|---|---|---|
|
string or array of string |
Command to execute. Omit to define an alias whose only purpose is |
|
array of task arg |
Named arguments with optional defaults. |
|
array of task dep |
Tasks to run before this one. |
|
string |
Working directory for the task. |
|
table of |
Environment variables to set. |
|
string |
Human-readable description. |
|
array of string |
Glob patterns for cache inputs. |
|
array of string |
Glob patterns for cache outputs. |
|
boolean |
Run with a minimal environment. |
|
string |
Conda environment to activate by default for this task. |
|
table of |
Per-platform overrides. |
A task arg is an inline table such as
{ arg = "path", default = "tests/" }.
A task dep is one of:
a string naming another task:
"build", oran inline table with extra fields:
{ task = "test", args = ["tests/unit/"], environment = "py311" }.
[target.<platform>.tasks]#
Platform-specific task overrides. Each entry follows the same shape
as a [tasks] entry.
Composition rules#
When a tool resolves an environment named <env>:
Start with the default feature (top-level
[dependencies],[pypi-dependencies],[activation],[system-requirements],[target]) unless the environment setsno-default-feature = true.Merge in each named feature listed in
features, in order. Later features override earlier ones for conflicting keys; lists are concatenated and de-duplicated.Apply
[target.<platform>]overrides for the host’s platform last.
Channel order is preserved. Duplicate dependency names within the same stack (conda or PyPI) are an error and the tool MUST surface them to the user.
Lockfile relationship#
conda workspace lock and conda workspace install produce and
consume conda.lock at the workspace root. The lockfile schema is
rattler-lock v6 (the same schema pixi.lock uses) with
one on-disk difference: conda.lock writes version: 1 instead of
version: 6 so tools can identify the file as conda-workspaces-owned
at a glance. The remainder of the document — environments,
packages, channels, platform package lists — is byte-compatible.
See Plugin format names and aliases for the
canonical and alias strings under which conda.lock is registered.
Lockfile satisfiability check#
conda workspace install and conda workspace info evaluate the
lockfile against the manifest to determine whether a re-solve is
needed. The check is purely structural (no file timestamps) and
runs in this order:
Schema version – the lockfile
versionfield must match the expected version (1).Environments – every environment declared in the manifest must have a corresponding entry in the lockfile.
Channels – the channel list for each environment in the lockfile must match the manifest (order-sensitive, URLs normalized).
Platforms – every platform declared in the manifest must be present in each lockfile environment’s
packagessection.Dependencies – for each dependency in the manifest (on the current platform), a locked package must exist whose version satisfies the manifest’s version spec.
The check returns the first failing condition it finds. The result is one of three states:
Status |
Constant |
Meaning |
|---|---|---|
|
|
All checks pass |
|
|
At least one check fails |
|
|
No |
JSON output fields#
conda workspace info --json includes the following lockfile fields:
Field |
Type |
Description |
|---|---|---|
|
|
One of |
|
|
Human-readable reason (only present when |
Embedded form (pyproject.toml)#
The same tables are accepted under [tool.conda.<name>] inside a
pyproject.toml:
Top-level table |
Embedded equivalent |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
When both conda.toml and pyproject.toml exist in the same
directory, conda.toml wins. When a pyproject.toml contains both
[tool.conda] and [tool.pixi] tables, [tool.conda] wins.
Pixi compatibility ladder#
conda.toml and pixi.toml share a deliberately overlapping table
layout, but they are not byte-for-byte interchangeable. The
relationship is:
Direction |
Holds? |
Why |
|---|---|---|
Every valid |
Yes |
The fields enumerated in this spec are all accepted by pixi. |
Every valid |
No |
Pixi’s |
pixi reads our |
No |
|
conda-workspaces reads |
Yes |
conda-workspaces ships a separate compatibility reader for |
Two intentional differences from pixi.toml:
conda.tomlaccepts only[workspace]; the legacy pixi[project]table is not part of this specification.conda-workspaces resolves dependencies with conda’s solver (libmamba) and installs them as conventional conda prefixes; pixi’s build-process options (e.g.
[package]-style build recipes) are not part of this specification.
If you need pixi-only fields, write a pixi.toml and let
conda-workspaces’ compatibility reader handle it; do not extend
conda.toml with them.
Versioning policy#
The schema is versioned with a single integer (1). A future
backwards-incompatible change to required fields, semantics, or
defaults bumps the version to 2 and gets a sibling schema URL
(https://schemas.conda.org/conda-toml-2.schema.json) and plugin
canonical name (conda-workspaces-v2). Aliases follow the rules in
format-aliases.md.
Backwards-compatible additions (new optional fields, new platforms in the platform enum) do not bump the version. Tools MUST ignore unknown top-level keys and unknown keys inside known tables in the same major version.
Open questions (non-normative)#
These are tracked for the CEP draft and are not part of v1:
Whether
[workspace]should be required to carryversionandname(currently both optional).Whether
solve-groupsemantics need a normative description beyond “version-coordinated”.Whether to standardise an
[envs]shorthand that maps a feature one-to-one to an environment of the same name.Discovery rules for nested workspaces (currently parent-directory search stops at the first match).
Whether
[tool.pixi.*]compatibility belongs in this specification or in a separate “compatibility” CEP.Whether
conda.tomlshould exist as a separate filename at all, or whether the spec should describe a “conda-workspaces dialect ofpixi.toml” — i.e. apixi.tomlplus the singledefault-environmentextension, without a parallel filename or schema URL. Trade-off: governance ownership (conda community vs. Prefix.dev) versus format proliferation. See the CEP tracker for discussion.