Package Manifest
Every Rux package is described by a Rux.toml file at its root. It carries the package's identity,
metadata, build settings, and dependencies, and it is required for anything that takes part in the build
system or a workspace.
[Manifest]
Version = 1
MinRux = "0.4.0"
[Package]
Namespace = "Acme"
Name = "Widget"
Version = "1.2.3"
Type = "SourceLibrary"
Description = "A widget for every occasion"
Authors = ["Your Name <[email protected]>"]
License = "MIT"
[Dependencies]
Io = { Namespace = "Rux", Version = "^1.0.0" }
The file is UTF-8 and uses a deliberately small subset of TOML: basic quoted strings, integers, booleans, arrays of quoted strings, the dependency inline table, comments, and the tables documented on this page. Section names, field names, and enum values are PascalCase, and parsing is case-sensitive.
[Manifest]
The schema header. Every manifest starts with one.
| Field | Presence | Contract |
|---|---|---|
Version | Required | Integer schema version; 1 is the only accepted value |
MinRux | Optional locally, required to publish | Semantic version, at least 0.4.0 |
MinRux is the oldest compiler release that can build the package. A compiler older than the declared
minimum refuses to build it. Leaving it out keeps rux new and rux init free of a field only
publication needs.
[Manifest].Version is the schema version of the file. [Package].Version is your package's own
release number. They are unrelated.[Package]
Identity and metadata.
[Package]
Namespace = "Acme"
Name = "Widget"
Version = "1.2.3"
Type = "SharedLibrary"
Description = "A widget for every occasion"
Authors = ["Your Name <[email protected]>"]
Keywords = ["Widget", "Ui"]
License = "MIT"
LicenseFile = "LICENSE.md"
Repository = "https://github.com/acme/widget"
Homepage = "https://acme.dev"
ReadmeFile = "README.md"
| Field | Presence | Contract |
|---|---|---|
Namespace | Optional locally, required to publish | One identity segment |
Name | Required | One identity segment |
Version | Required | Strict Semantic Version, no leading v |
Type | Required | Exactly Executable, SharedLibrary, StaticLibrary, or SourceLibrary |
Description | Optional | Short summary |
Authors | Optional | Array of strings |
Keywords | Optional | Array of identity segments, unique after normalization |
License | Optional | SPDX expression |
LicenseFile | Optional | Package-relative path |
Repository | Optional | Absolute http/https URL with a host and no credentials |
Homepage | Optional | Absolute http/https URL with a host and no credentials |
ReadmeFile | Optional | Package-relative path |
Type decides what the package produces and which commands accept it. Authors
must be an array — the older scalar spelling is invalid.
The two licence fields are independent, and setting both is the norm. License is what machines read —
it is the field a dependency-tree licence audit and the registry's filters work from. LicenseFile is
what people read: it points at the licence text shipped inside the package, so it carries the copyright
holder and year that an SPDX identifier cannot express, it is covered by the release checksum, and it
stays readable offline. The conventional target is the LICENSE.md in the standard
package layout. A licence with no SPDX identifier uses SPDX's own LicenseRef-
form alongside the file:
[Package]
License = "LicenseRef-Acme-Commercial"
LicenseFile = "LICENSE.md"
[Dependencies]
Each key is the name you import the dependency under; each value is an inline table.
[Dependencies]
Io = { Namespace = "Rux", Version = "^1.0.0" }
Json = { Namespace = "Acme", Package = "FastJson", Version = ">=2.0.0, <3.0.0", TargetOS = ["Linux", "MacOS"] }
Util = { Path = "../Util", TargetOS = ["Windows"] }
| Form | Requires | Notes |
|---|---|---|
| Registry | Namespace, Version | Resolved from the registry |
| Path | Path | A local directory; cannot carry Namespace/Version |
Either form may set Package when the dependency's own name differs from the import name; it defaults
to the import name. Two dependencies cannot produce the same import name after normalization.
Either form may also set a non-empty, duplicate-free TargetOS allow-list. The dependency applies only
when the selected target operating system appears in the list. Omitting TargetOS makes it
unconditional. Values are case-sensitive and exactly Windows, Linux, MacOS, FreeBSD, OpenBSD,
NetBSD, DragonFlyBSD, or Illumos.
[Build]
Optional build settings.
[Build]
Output = "Dist"
[Build.Defines]
Channel = "Nightly"
CheckedArithmetic = true
Retries = 3
Output is a package-relative path and defaults to Bin. [Build.Defines] is an optional table of
string, boolean, and integer values exposed to
compile-time configuration through #config, and overridable per build with
--define NAME[=VALUE].
Workspaces
A workspace manifest groups member packages instead of describing one:
[Manifest]
Version = 1
[Workspace]
Packages = [
"Packages/Math",
"Packages/Memory",
]
Packages is a non-empty, duplicate-free array of explicit relative paths — no globs, no parent
traversal. [Workspace] and [Package] are mutually exclusive; a manifest has exactly one of them. A
workspace declares no dependencies or build settings and cannot be published.
Paths
Manifest paths are UTF-8, relative, and /-separated. Backslashes, absolute roots, empty components,
and . components are invalid. A field whose name ends in File names a path inside the package —
it must exist in the published archive, and like workspace paths it rejects ... Dependency and output
paths may begin with .. components, but parent traversal cannot follow a normal component.
Validation profiles
The rules applied depend on the operation, not on anything stored in the file.
| Profile | Applies to | Accepts |
|---|---|---|
| Local | build, check, run, test, … | Package and workspace manifests; Namespace and MinRux optional; path dependencies allowed |
| Publication | pack, publish | Package manifests only; Namespace and MinRux required; path dependencies rejected |
Both rux pack and rux publish apply the publication profile before doing any other work, so a
manifest that cannot be published is reported locally rather than by the registry.
Canonical form
rux fmt --manifest-only, rux add, rux remove, rux new, and rux init all write the same order:
[Manifest], then [Package] or [Workspace], then [Dependencies], [Build], and [Build.Defines].
Only recognized fields are written. Metadata arrays and TargetOS values keep their order; dependency
and define keys use a stable deterministic order. In a dependency inline table, TargetOS follows
Version or Path. Changing a dependency with rux add preserves its existing target condition.
Limits
All limits count UTF-8 bytes.
| Resource | Limit |
|---|---|
| Manifest source | 65,536 |
| Dependencies / workspace packages | 256 each |
| Defines per table | 128 |
| Authors / keywords | 32 each |
| Description | 2,048 |
| Author | 256 |
| URL or path | 2,048 |
| SPDX expression / version range | 512 |
| Semantic version | 256 |
| Identity segment | 64 |