Package Manager Implementation Plan
This plan breaks down RFC #218: Package Manager Design into implementation phases for the Run compiler and docs. The package manager uses run.toml, run.lock, semantic version tags, a local module cache, Minimum Version Selection, run install / run i for dependency installation, and run pkg for package maintenance commands.
- Build the compiler-internal foundation first: TOML, semantic versions, checksums,
run.toml, andrun.lock. - Add GitHub tag discovery, archive download, fast manifest fetches, and local cache management behind testable interfaces.
- Implement deterministic dependency resolution with MVS before exposing package manager commands.
- Wire
run install, itsrun ialias, andrun pkginto the CLI after the manifest, lockfile, fetch, cache, and resolver layers are stable. - Integrate external imports into the compiler last: path classification, scope-aware checking, multi-module compilation, cross-package lowering, and C codegen.
- Finish with vendor mode, offline builds, private repository authentication, monorepo sub-modules, docs, and end-to-end tests.
Current Baseline
Section titled “Current Baseline”The compiler already has a single-file pipeline:
Source (.run) -> Lexer -> Parser -> Naming -> Resolve -> TypeCheck -> Lower (IR) -> CodegenC -> zig ccThe package manager work should preserve that pipeline for single-file and stdlib-only projects while adding module-aware behavior around project setup, dependency resolution, and compilation.
Current constraints:
run initalready writes a basicrun.toml, but the CLI does not yet exposerun install,run i, orrun pkg.- Imports parse as
use "path"and currently behave as simple package symbols. - The driver compiles one primary source file and discovers nearby assembly files.
- Lowering and C codegen still assume most cross-package behavior is either local code or known runtime/stdlib builtins.
Phase 1: Foundation
Section titled “Phase 1: Foundation”Related issues: #293, #294, #295, #296, #297, #298
Add the data model and parsing modules used by every later phase.
- Add
src/toml.zigfor the compiler-internal TOML subset required byrun.tomlandrun.lock. - Add
src/semver.zigfor semantic version parsing, comparison, sorting,vtag prefix stripping, and constraint evaluation. - Add
src/checksum.zigfor SHA-256 archive hashing andsha256:<hex>formatting. - Add
src/modfile.zigfor manifest parsing, validation, serialization, dependency sections, and scope tracking. - Add
src/lockfile.zigfor deterministic lockfile parsing and generation. - Update project initialization so
run initandrun pkg initcreate a complete manifest template. - Export the new modules from
src/root.zigsozig build testdiscovers their tests.
Acceptance gates:
- Valid and invalid TOML fixtures are covered by unit tests.
- Semver constraints cover
^,~,=,>=,0.x, pre-release, and build metadata cases. - Manifest and lockfile round trips are deterministic.
- Missing required package fields and malformed dependency entries produce clear diagnostics.
Phase 2: Fetching And Cache
Section titled “Phase 2: Fetching And Cache”Related issues: #299, #300, #301, #302
Add the GitHub and local filesystem layer that resolution depends on.
- Add
src/modfetch.zigfor module path parsing, GitHub URL construction, tag discovery, archive downloads, and rawrun.tomlfetches. - Add
src/modcache.zigfor the default~/.run/modcache andRUNMODCACHEoverride. - Store archives under
cache/<host>/<owner>/<repo>/. - Extract immutable source trees to versioned module directories.
- Cache fetched manifests separately so transitive resolution can avoid downloading full archives just to inspect dependencies.
- Make process execution and HTTP behavior injectable so unit tests do not depend on live GitHub access.
Acceptance gates:
- Tag discovery filters semver tags, strips
v, ignores dereference suffixes, and sorts deterministically. - Cache path construction is tested for regular modules and future sub-module paths.
- Archive checksum computation is recorded for lockfile generation.
- HTTP, Git, auth, missing tag, and missing manifest failures produce actionable errors.
Phase 3: Dependency Resolution
Section titled “Phase 3: Dependency Resolution”Related issues: #303, #304, #305
Add MVS and lockfile generation before adding user-facing commands.
- Add
src/mvs.zigfor requirement graph construction and deterministic Minimum Version Selection. - Resolve production dependencies first.
- Resolve
dev,test, anddebugdependency graphs independently with production dependencies as the floor. - Detect hard major-version conflicts and show which dependency introduced each incompatible requirement.
- Generate
run.lockfrom the resolved graph. - Skip re-resolution when the manifest and lockfile are already consistent.
- Verify previously cached modules before trusting cache hits.
Acceptance gates:
- Unit tests cover simple chains, diamonds, shared transitive dependencies, major conflicts, pre-release versions, and fetch-order independence.
- Scoped dependency tests prove test/debug/dev dependencies do not unexpectedly upgrade production dependencies.
- Generated
run.lockoutput is stable for identical inputs.
Phase 4: CLI Commands
Section titled “Phase 4: CLI Commands”Related issues: #306, #307, #308, #309, #310, #311
Expose the package manager once the core behavior is reliable.
- Add
src/pkg_cmd.zigforinstall,tidy,download,verify,graph, andvendorhandlers. - Wire
run install,run i, andrun pkgsubcommands throughsrc/main.zig. - Support
run install <module>[@version],run i <module>[@version],--test,--debug,--dev,-u <module>, and-u. - Implement atomic updates for
run.tomlandrun.lock. - Implement
run pkg tidyby using the parser and AST import declarations instead of source-text matching. - Implement
run pkg downloadandrun pkg verifyfrom lockfile state. - Implement
run pkg graphwith direct and transitive dependency output, version labels, scopes, and diamond dependencies. - Add user documentation for manifests, locks, scopes, semver syntax, and package manager workflows.
Acceptance gates:
run --helpincludes package manager commands.run installandrun ifail cleanly whenrun.tomlis missing and suggestrun pkg init.run pkg verifyexits non-zero on missing or mismatched cache entries.- CLI tests cover valid usage, invalid arguments, and error messages.
Phase 5: Compiler Integration
Section titled “Phase 5: Compiler Integration”Related issues: #312, #313, #314, #315, #316, #317, #318
Make resolved dependencies usable by the compiler.
- Extend import resolution to classify stdlib, relative, and external import paths.
- Look up external modules in
run.tomlandrun.lock. - Resolve module source from
vendor/or the local cache. - Enforce dependency scopes based on file type and build mode.
- Add parser, AST, resolver, and formatter support for import aliases such as
use mux "github.com/user/router". - Introduce a multi-unit compilation model in the driver: root package plus dependency packages.
- Namespace package-level symbols to avoid collisions.
- Compile dependency
.runfiles in dependency order. - Generalize lowering so external function calls and type references use resolved symbol metadata instead of hardcoded package behavior.
- Extend C codegen for cross-module forward declarations, shared type definitions, duplicate definition avoidance, and stable generated C ordering.
- Add an end-to-end test that creates a local git repository package, runs package-manager commands, builds a dependent project, and executes the result.
Acceptance gates:
- Unknown external modules produce an error that suggests
run install. - Scoped dependencies are rejected outside their allowed contexts.
- External package functions generate correct mangled names.
- Multi-package generated C compiles without duplicate symbols or missing declarations.
- E2E tests do not depend on live GitHub network availability.
Phase 6: Polish
Section titled “Phase 6: Polish”Related issues: #319, #320, #321, #322
Finish production workflows after the core package manager and compiler integration work.
- Implement
run pkg vendorand prefervendor/over the global cache when present. - Add offline build behavior that never performs network requests when all required modules are cached or vendored.
- Add private repository support through
GITHUB_TOKEN, git credential helpers, andRUNPRIVATE. - Add monorepo sub-module support using path-prefixed tags and subdirectory
run.tomlfiles. - Document private repository auth, offline workflows, vendor mode, and monorepo publishing.
Acceptance gates:
- Builds work offline when dependencies are cached or vendored.
- Missing cached modules produce a clear
run pkg downloadsuggestion. - Private repository auth failures explain how to configure credentials.
- Sub-module packages resolve, fetch, cache, and import correctly.
Testing Strategy
Section titled “Testing Strategy”- Keep parser, resolver, and compiler behavior covered by inline Zig
testblocks. - Keep package-manager modules covered by focused unit tests with fixture strings and temporary directories.
- Mock Git and HTTP in unit tests.
- Use local temporary git repositories for E2E package-manager tests.
- Run
zig build testfor compiler unit coverage. - Run
zig build test-e2eafter compiler integration phases. - Run website checks from
website/when documentation or sidebar changes.
PR Sequencing
Section titled “PR Sequencing”Each PR should stay close to one phase or one issue dependency chain.
src/toml.zig,src/semver.zig, andsrc/checksum.zigcan land independently.src/modfile.zigshould wait for TOML and semver.src/lockfile.zigshould wait for TOML and scope types from modfile.- Fetch and cache can proceed after semver and checksum.
- MVS should wait for modfile and semver.
- CLI commands should wait for manifest, lockfile, fetch, cache, and resolution.
- Compiler integration should wait for package-manager core and should be split by import resolution, scope checks, multi-file compilation, lowering, and codegen.
- Vendor/offline/private/monorepo behavior should land after the base external import path works.
Done Criteria
Section titled “Done Criteria”The package manager design is complete when:
- All child issues linked from RFC #218 are implemented or explicitly superseded.
run.tomlandrun.lockare deterministic and documented.run install,run i,run pkg tidy,run pkg download,run pkg verify,run pkg graph, andrun pkg vendorwork from the CLI.- External imports compile through the existing pipeline.
- Scoped dependencies are enforced at compile time.
- Cached, vendored, and offline builds are reproducible.
- Private GitHub repositories and monorepo sub-modules have tested workflows.
zig build test,zig build test-e2e, and relevant website checks pass.