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 Version 1 is strict. Unknown sections and unknown fields are errors, not warnings — a typo fails the build instead of silently changing it. Duplicate keys, wrong value types, missing required fields, and invalid identities are rejected the same way, each with the file, line, and column of the offending token.

[Manifest]

The schema header. Every manifest starts with one.

FieldPresenceContract
VersionRequiredInteger schema version; 1 is the only accepted value
MinRuxOptional locally, required to publishSemantic 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"
FieldPresenceContract
NamespaceOptional locally, required to publishOne identity segment
NameRequiredOne identity segment
VersionRequiredStrict Semantic Version, no leading v
TypeRequiredExactly Executable, SharedLibrary, StaticLibrary, or SourceLibrary
DescriptionOptionalShort summary
AuthorsOptionalArray of strings
KeywordsOptionalArray of identity segments, unique after normalization
LicenseOptionalSPDX expression
LicenseFileOptionalPackage-relative path
RepositoryOptionalAbsolute http/https URL with a host and no credentials
HomepageOptionalAbsolute http/https URL with a host and no credentials
ReadmeFileOptionalPackage-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"] }
FormRequiresNotes
RegistryNamespace, VersionResolved from the registry
PathPathA 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.

A path dependency makes a manifest unpublishable — the directory it names exists only on your machine. See Dependencies for the full requirement syntax.

[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.

ProfileApplies toAccepts
Localbuild, check, run, test, …Package and workspace manifests; Namespace and MinRux optional; path dependencies allowed
Publicationpack, publishPackage 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.

ResourceLimit
Manifest source65,536
Dependencies / workspace packages256 each
Defines per table128
Authors / keywords32 each
Description2,048
Author256
URL or path2,048
SPDX expression / version range512
Semantic version256
Identity segment64