Packages for Shape
Shape's package manager is built into the shape toolchain. It installs packages from source repositories (antique or git) into a shared store, and resolves the exact versions you declare in dependencies.toml. There is no central registry: publish a package anywhere that speaks git or antique, and depend on it with one line.
Install a package
shape add http
shape fetch
shape add records the dependency in dependencies.toml. shape fetch vendors the declared packages, their transitive dependencies, and writes shape.lock. Then import it in source, with no version in sight:
import http
func main() -> Int effects io, network:
let response = std.http_get("https://example.com/")
print(response.status)
dependencies.toml
dependencies.toml is the only place that declares external package dependencies. It is the authoritative source for versions, and the compiler refuses an unversioned or undeclared package. Local modules and the standard library resolve without a manifest.
http = "1.0.0"
ui = { from = "git+https://code.input.cx/shape/ui.git", version = "1.0.0" }
state = { from = "antique://code.input.cx/shape/state.git", version = "0.9.0" }
Keys are package names. Values are either a version string, or a table with version and an optional from source. shape init creates an empty dependencies.toml in the current directory.
Commands:
shape add <name>,shape add <name>@<version>,shape add <name> --from <source>shape remove <name>shape fetch— vendor declared and transitive dependencies, writeshape.lockshape update— re-vendor everything and rewriteshape.lockshape list— list what is installed in the store
shape.lock
shape fetch and shape update generate shape.lock next to your dependencies.toml. It records the exact resolved packages (direct and transitive) and a content hash of every file in each package, so the same manifest resolves to the same bits on every machine.
# generated by shape fetch; records the exact resolved packages and their hashes
[[package]]
name = "http"
version = "1.0.0"
sha256 = "a3f8…"
Publish a package
Any Shape source tree can be published as a package. Packages are ordinary repositories; version directories are not part of the source layout.
shape publish --to antique://code.input.cx/shape/mypackage --message "initial commit"
shape publish --to git+https://code.input.cx/shape/mypackage --message "initial commit"
Consumers then write a top-level entry in dependencies.toml:
mypackage = "1.0.0"
# or pin a different source repository:
mypackage = { from = "git+https://code.input.cx/shape/mypackage.git", version = "1.0.0" }
Notes:
- Packages are immutable once published: every resolved version in
shape.lockis pinned to a content hash. - A package may declare its own dependencies in its own
dependencies.toml;shape fetchresolves those transitively from repositories you can read. - Tooling resolves against the public store (
~/.shape) shared by all projects on the machine. Private packages work the same with private repositories.
Browse packages
Filter the list:
- std — bundled standard library (http, bytes, hex, json, crypto, gpu, tasks). Declared, not installed: ships with the toolchain.
- ui — native Shape UI views, state and actions; rendering backends for desktop, State Pages and State Explorers. In development.
- http — HTTP client and server. In development.
- crypto — hashes, MACs, AEAD, signing. In development.
- serialization — canonical JSON, binary formats, schema-checked codecs. In development.
- collections — maps, sets, arrays, order statistics; used by std but also usable standalone. In development.
- concurrency — structured concurrency, channels, select. In development.
- fs — filesystem access with explicit capabilities. In development.
- graphics — 2D canvas and GPU compute interop. In development.
- math — numeric types, checked conversions, fixed-width lanes. In development.
- state/* — smart-contract support for State (state/contract, state/assets, state/sns, state/social, state/dsn, state/dcn, state/smp). In development; State VM enforces permissions.
The list above is the intended set of official packages. Publishing for each package follows the availability of its source repository; nothing is installable that has not been published yet. Watch code.input.cx/shape for availability.
FAQ
Why no central registry?
Registry infrastructure is a single point of failure and a single point of control. Shape resolves packages directly from repositories, with content hashes in shape.lock. Anyone can mirror any repository; resolution is reproducible either way.
What about global caches?
The shared store lives at ~/.shape (override with SHAPE_STORE). SHAPE_PATH extends module search roots for advanced setups.
How are versions chosen?
Exactly the version in dependencies.toml. There are no ranges, no dist-tags, and no implicit "latest". If you want a different version, change the manifest and run shape fetch.
Shape · Playground · Source