Shape Packages
The central registry for Shape packages: a sharded, line-oriented index repository, exactly like Cargo's crates.io-index. Every published version of every package lives in it, immutable, next to the tarballs it describes. The shape toolchain resolves shape add against the index over HTTPS.
The bundled standard library is part of the toolchain and is not a package: HTTP, crypto, JSON and hex serialization, filesystem access, collections, concurrency primitives, and math helpers all ship with std. Use them with import std.
Central registry
The index is served at https://packages.shape-lang.org/index/ from the packages-index antique repository. There is one file per package, sharded cargo-style:
1/<name>/<name> (1 char)
2/<name>/<name> (2 chars)
3/<first>/<name> (3 chars)
<first2>/<next2>/<name> (4+ chars, e.g. /nu/nu/nui)
Each file is newline-delimited JSON, one line per published version:
{"name":"nui","vers":"0.1.0","deps":[],"cksum":"<sha256 of the tarball>","features":{},"links":null,"v":2}
Fields: name, vers, deps (each dependency with name, version_req, features, default_features, optional), cksum (SHA-256 of the tarball), features (feature → enabled dependency names), links (reserved for native-libs owned by the toolchain), v (schema version, currently 2).
Resolution rules, mirrored in the client:
shape add nuireadsindex/3/n/nui, resolveslatest, and writesnui = { from = "…", version = "…" }intopackage.toml.shape add nui@0.1.0selects that exact version; there are no ranges or^/~operators.- Private or unregistered sources never need the index:
shape add nui --from antique://code.input.cx/shape/nuirecords exactly thefromyou gave and skips resolution. shape search nuilists matches from the generated listing atindex/_search.json.SHAPE_INDEXoverrides the index URL — point it at an internal mirror or file:// path for air-gapped networks.
Install a package
shape add nui
shape fetch
shape add records the dependency in package.toml. shape fetch vendors the declared packages and their transitive dependencies into ~/.shape (override with SHAPE_STORE) and writes shape.lock.
import nui
fn main() -> Int effects io:
let page = nui.column([nui.heading("island"), nui.button("Follow", "follow")])
print(nui.render(page))
0
package.toml
A package is described by package.toml, exactly like Cargo.toml: a metadata section and a dependencies section. Top-level scalar metadata belongs in [metadata]; dependencies map package names to version requirements or tables with from and version.
[metadata]
name = "nui"
version = "0.1.0"
description = "Declarative UI trees for Shape."
repository = "https://code.input.cx/shape/nui"
license = "Proprietary"
authors = ["Input"]
[dependencies]
http = "0.1.0"
store = { from = "antique://code.input.cx/shape/store", version = "0.2.0" }
[dev-dependencies]
shape = "*"
Local modules and the standard library resolve without declarations. A package's own dependencies in package.toml are vendored from the same store roots as everything else — transitively resolved. shape init scaffolds a new package for you.
shape.lock
shape fetch and shape update generate shape.lock next to your package.toml, recording the exact resolved packages (direct and transitive) and a content hash of every file in each package:
# generated by shape fetch; records the exact resolved packages and their hashes
[[package]]
name = "nui"
version = "0.1.0"
sha256 = "fc951fbb4a77b5446debca22b66b62acdc6c5ee644728a82c15a535085694050"
Publish a package
Any Shape source tree is publishable. Layout convention: name.shape (the package's entry module), optional extra modules, a package.toml, tests runnable with shape test.
shape publish --to antique://code.input.cx/shape/mypackage --message "initial release"
Then add (or append to) the package's file in packages-index — one line per version with the tarball cksum — review and land it with antique review and antique land. The site redeploys the index automatically on landing.
- Packages are immutable once published;
shape.lockpins exact content, and a merged index line cannot be edited. - Dependencies must resolve from the index to be merged; private dependencies link via
--fromand need no entry. - Depending on unmerged packages from a merge-candidate version of the index is fine —
SHAPE_INDEXcan point at a checkout of the index overfile://.
Private packages
There is no god-mode in the index; privacy is a property of the source you name, not a flag on the server.
- Private dependency, public consumer: host the package in a private antique repo. The consumer declares it with
shape add foo --from antique://code.input.cx/you/foo— the index never sees it; only you and your CI need the repo's ACL grant. - Private index for an org: mirror this repository's layout internally, serve it over HTTPS, and point every developer's
SHAPE_INDEXat it. Your toolchain resolves against the mirror; the public index is never contacted. - Antique ACL-scoped packages:
antique acl --prefix foo --private --read teammates --write youscopes exactly which antique users can read and write a package. Shape records the same source URL inpackage.toml; access stays enforced by antique at fetch time. - Vendoring for air gaps:
shape fetch --store ./vendorproduces a directory you can carry offline;SHAPE_STORE=./vendor shape buildresolves entirely against it.
Browse packages
Filter:
- nui
0.1.0— declarative UI trees for Shape: views as plain, typed data with an HTML renderer. Source. - state — smart-contract support on State (state/contract, state/assets, state/sns, state/social, state/dsn, state/dcn, state/smp). In development; State VM enforces permissions. Not yet published.
The standard library ships with the toolchain and is not a package: std provides HTTP client, crypto (sha256, hmac), JSON/hex/bytes serialization, filesystem (std.file_read, std.file_write), collections (std.collections), concurrency (std.spawn, std.wait, std.cancel, std.sleep, std.parallel), and math (std.min, std.max, std.parse_int, bit operations). Nothing extra to install beyond import std. The http package is a thin veneer over host HTTP for projects that want a typed client without pulling std networking into their binary.
FAQ
What is in the standard library vs a package?
Anything every application wants with zero dependencies is in std and ships with the toolchain. Reusable libraries, versioned and community-maintained — like nui — are packages, discovered like any crates.io-style package via the index.
Do I have to use the central registry?
No. shape add name --from <source> records exactly that source and never reads the index. Use it for private, experimental, or air-gapped dependencies. The index is the default because it gives exact, hash-verified, reproducible resolution by default.
How are versions chosen?
Exactly the version in package.toml. shape add nui picks latest from the index at add time; the lockfile records what it picked, with hashes.
Is there a lockfile?
Yes, always: shape.lock records direct and transitive versions plus a content hash per package, generated on every shape fetch / shape update. Commit it.
Shape · Playground · Source