Packages and Distribution
Local projects, exact git dependencies, lockfiles, cache restoration, and bundle validation.
Zynx package distribution is deliberately narrow in 0.0.0-dev. Builds use
local source, exact git dependencies, and lockfiles. There is no central
registry, semver solver, package signing, publishing workflow, mirror
selection, or first-class vendor archive format in the current development
contract.
Included:
- local project packages with
zynx.json - exact git dependencies declared in
zynx.json - optional manifest-pinned git revisions with
rev zynx.lockreuse for deterministic dependency selection- new project scaffolding with
zynx new <name>andzynx init - read-only package validation with
zynx package check - package-cache restoration with
zynx fetch - dependency updates with
zynx updateorzynx update <package> - deterministic module identity and duplicate-module rejection
- static
.zxmbundle metadata validation
Excluded:
- package registries and package indexes
- semver ranges such as
^1.2.0,~1.2, or>=1 - dependency declarations by registry package name alone
- publishing commands
- signed package verification
- mirror selection
- automatic vendor-cache archives
- transitive dependency solving beyond the exact locked package graph
Unsupported dependency keys are rejected. Dependency entries may contain only
git and optional rev.
Create a new project directory:
./zynx new hello
cd hello
./zynx run
Initialize the current directory instead:
./zynx init
./zynx init --name my_project
zynx new <name> creates a directory containing zynx.json and src/main.zx.
zynx init writes those files in the current directory and fails if
zynx.json already exists. --name supplies the package name explicitly; when
it is omitted, the name is derived from the directory and normalized to package
name characters. Dependency-free projects do not get a zynx.lock until one is
needed.
zynx.json describes the local package, build targets, and exact dependencies.
{
"format": "zynx-project",
"version": 1,
"package": {
"name": "app",
"version": "0.1.0"
},
"targets": {
"app": {
"kind": "executable",
"main": "src/main.zx"
}
},
"default_target": "app",
"build": {
"target": "native",
"profile": "debug"
},
"dependencies": {
"util": {
"git": "https://github.com/your-org/zynx-util.git",
"rev": "0123456789abcdef0123456789abcdef01234567"
}
}
}
package.version is metadata only. It does not participate in dependency
selection.
zynx.lock records the exact dependency graph selected for a build:
{
"format": "zynx-lock",
"version": 1,
"packages": {
"util": {
"git": "https://github.com/your-org/zynx-util.git",
"rev": "0123456789abcdef0123456789abcdef01234567",
"path": "git/util/0123456789abcdef0123456789abcdef01234567"
}
}
}
A normal build reuses a matching lockfile entry for the same dependency name
and git URL. If the package cache is missing but the lockfile names a valid git
revision, zynx fetch restores the checkout into the cache.
The default package cache is $ZYNX_HOME/packages, or
~/.local/share/zynx/packages when ZYNX_HOME is not set.
Check package state without modifying zynx.lock or fetching dependencies:
./zynx package check
package check validates zynx.json, reads zynx.lock when present, reports
missing or stale dependency lock entries, and reports invalid existing package
cache checkouts. It does not contact git remotes and does not create or update
the lockfile. A clean project reports package check: ok.
Refresh unlocked git dependencies to their remote HEAD with:
./zynx update
Refresh one dependency with:
./zynx update util
Manifest dependencies with rev are pinned to that exact revision. Changing a
pinned revision is a source edit to zynx.json, followed by a normal build or
fetch.
To reproduce a build, keep these inputs fixed:
- project source
zynx.jsonzynx.lock- package cache entries named by
zynx.lock - active SDK and standard library
- explicit
--module-pathroots, if any
Fully offline reproduction requires the locked package cache and SDK/stdlib inputs to already be present. Zynx does not define an offline vendor archive format or registry mirror.
Imports use dotted module identities. A package module must provide the same identity that the source imports. Duplicate non-standard module identities across explicit module paths or locked dependency packages are rejected instead of being resolved by path order.
A local source file next to the importer may intentionally shadow package
modules. builtin and std.* remain reserved for the active standard library
and SDK.
Static .zxm bundles may be imported only when their embedded metadata matches
the requested module identity, active target, ABI, and supported bundle kind.
Dynamic bundles and runtime loading are not part of normal source. Use ordinary
import plus declared package inputs.