spade install
The spade install command installs a block collection so its blocks can be used in pipelines. <source> is a registry reference, a git URL, or a local directory path. A registry reference fetches a prebuilt, signed artifact; the other two acquire the source and build it locally using the appropriate language toolchain.
Blocks are unpacked into ~/.spade/blocks/<collection>/<version>/ and registered in the local block index (~/.spade/registry.db).
Usage🔗
# From the cloud registry
spade install gdal@1.0.0
spade install gdal@latest
# From a git URL
spade install https://github.com/spade-dev/gdal-blocks.git
spade install git@github.com:spade-dev/gdal-blocks.git
# From a local path
spade install .
spade install ./my-collection
spade install /home/user/projects/my-collection<source> is interpreted as follows:
| Form | Example |
|---|---|
<collection>@<version> or <collection>@latest — no scheme, no path separator | gdal@1.0.0 |
http://, https://, git://, ssh://, file://, or git@host:path | https://github.com/spade-dev/core-blocks.git |
Local path (., ./sub, or absolute) | . |
A local path does not need to be a git repository — the directory is used as-is.
Registry-fetch mode🔗
For a registry reference the CLI installs exactly what the cloud's workers run, with no build toolchain involved:
- Resolve the version.
latestis the highestavailableversion listed by the registry. - Fetch the artifact tarball and its detached signature for
<collection>/<version>/<platform>/<arch>of the local machine. - Verify the signature against the registry's trusted public keys (cached under
~/.spade/cache/), then the tarball's content hash against the registry's metadata. - Unpack into
~/.spade/blocks/<collection>/<version>/and register each block in the local index.
Fetching gdal@1.0.0 (linux/amd64) from the registry...
Installed gdal@1.0.0 to /home/user/.spade/blocks/gdal/1.0.0The credential is your spade login session; the command asks you to log in if there is none.
Private collections🔗
A private collection (Visibility and sharing) can be installed only by its owner. A user the collection has been shared with can run its blocks in the cloud but cannot take the artifact, and the command says so:
priv is a private collection: only its owner can install it
If it has been shared with you, that covers cloud execution only — run the pipeline with 'spade submit'Asking for priv@latest as a non-owner reports the collection as not found, or private and not yours, for the same reason: the registry lists a private collection's versions only to its owner.
The registry builds artifacts for the worker fleet's platform. On another platform the fetch reports that the artifact is not available for it and points at building from source instead.
Build-from-source mode🔗
For a git URL or a local path, the steps are:
1. Acquire the source🔗
- Git URL: shallow-cloned (
--depth=1) into a temporary directory. - Local path: resolved to an absolute path and used in place. Not required to be a git repository.
Cloning https://github.com/spade-dev/gdal-blocks.git...2. Detect the language🔗
Spade examines the source root for language marker files, checked in this order:
| Marker file | Language |
|---|---|
Cargo.toml | Rust |
go.mod | Go |
pyproject.toml | Python |
package.json | TypeScript |
| (none of the above) | R (default) |
Detected language: rust3. Discover blocks🔗
All blocks/*.yaml files are loaded and parsed as block manifests. If none are found, the install fails.
4. Read collection metadata🔗
The collection name and version are read from the language-specific manifest:
| Language | Name source | Version source |
|---|---|---|
| Rust | Cargo.toml name field | Cargo.toml version field |
| Go | Last path segment of go.mod module | Defaults to 0.1.0 |
| Python | pyproject.toml name field | pyproject.toml version field |
| TypeScript | package.json name field | package.json version field |
| R | Directory name | Defaults to 0.1.0 |
If the manifest can't be read for some reason, the CLI falls back to the source directory's basename for the name and 0.1.0 for the version rather than failing outright.
Multiple versions of the same collection can be installed side by side.
5. Build🔗
A language-specific build command is run against the source:
| Language | Build command | Notes |
|---|---|---|
| Rust | cargo build --release | Produces a single binary with subcommands |
| Go | go build -o <collection> | Produces a single binary with subcommands |
| Python | uv sync | Resolves dependencies into a project-local environment; no separate install step |
| TypeScript | bun install (frozen lockfile, falling back to a normal install) then bun build <entry> --compile --outfile <collection> | Bundles into a single self-contained executable |
| R | Rscript -e <pak install script> if a DESCRIPTION or pkg.lock is present, otherwise Rscript setup.R if present, otherwise no build step | Installs dependencies (and the local spadelib runtime) via pak into the user library the sandbox binds |
Local-path installs build in place, so native toolchains (Cargo, Go, etc.) can reuse their incremental build caches across repeated spade install . runs.
6. Install🔗
The built artifacts and block manifests are copied into ~/.spade/blocks/<collection>/<version>/. For Python collections, the CLI additionally runs a fresh uv sync inside the install directory to create a venv there, since the copied environment can't be reused directly from the original source location.
Detected language: rust
Collection: gdal-blocks v1.2.0
Building...
Installed 6 block(s) to /home/user/.spade/blocks/gdal-blocks/1.2.07. Update the local block index🔗
Each block manifest is registered in ~/.spade/registry.db, along with a content hash computed over the installed directory.
Verifying the installation🔗
After installing, you can verify that blocks are registered by referencing them in a pipeline and running spade check:
spade check my-pipeline.yamlIf the pipeline references a block type that was just installed and spade check reports it as valid, the installation succeeded.
Examples🔗
From a git URL:
spade install https://github.com/spade-dev/gdal-blocks.gitCloning https://github.com/spade-dev/gdal-blocks.git...
Detected language: rust
Collection: gdal-blocks v1.2.0
Building...
Installed 6 block(s) to /home/user/.spade/blocks/gdal-blocks/1.2.0From the current directory (typical during development):
spade install .Installing from local directory: /home/user/projects/my-collection
Detected language: python
Collection: my-collection v0.1.0
Building...
Installed 3 block(s) to /home/user/.spade/blocks/my-collection/0.1.0Locally built versus registry-fetched🔗
Locally built collections are not signed; the local index records them as locally built, distinct from registry-fetched artifacts. Production workers always use registry-fetch. To distribute a collection to another developer, publish it and have them spade install <collection>@<version>, or — for a collection they may only use, not take — share it with them and have them run pipelines with spade submit.
See also🔗
spade publishfor submitting a collection to the cloud registryspade loginfor authenticating to a Spade serverspade setupfor initializing the local environment before installingspade checkfor verifying the installed blocks work in a pipelinespade initfor creating a new collection to develop locally