spade install
The spade install command installs a block collection so its blocks can be used in pipelines. <source> is either a git URL or a local directory path; in both cases Spade acquires the source and builds 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 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 |
|---|---|
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.
What it does🔗
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.0Planned: registry-fetch mode🔗
There is currently no way to install a prebuilt, signed artifact from a cloud registry by reference (e.g. a hypothetical spade install gdal@1.0.0). spade install's source-classification logic (isLocalSource in cli/cmd/install.go) only distinguishes a git URL from a local directory path — there is no version-pinned registry syntax, no signature verification, and no content-hash verification step today. Every install is a local build from source.
A registry-fetch mode — resolving a <collection>@<version> reference, downloading a signed artifact, and verifying its signature and content hash before unpacking — is a planned direction, not current behavior. Until it ships, distributing a collection means sharing the git repository (or its tarball) directly; see spade upload for the current (partial) state of packaging a collection for eventual cloud distribution.
See also🔗
spade uploadfor packaging a collection ahead of future cloud distributionspade 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