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:

FormExample
http://, https://, git://, ssh://, file://, or git@host:pathhttps://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 fileLanguage
Cargo.tomlRust
go.modGo
pyproject.tomlPython
package.jsonTypeScript
(none of the above)R (default)
Detected language: rust

3. 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:

LanguageName sourceVersion source
RustCargo.toml name fieldCargo.toml version field
GoLast path segment of go.mod moduleDefaults to 0.1.0
Pythonpyproject.toml name fieldpyproject.toml version field
TypeScriptpackage.json name fieldpackage.json version field
RDirectory nameDefaults 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:

LanguageBuild commandNotes
Rustcargo build --releaseProduces a single binary with subcommands
Gogo build -o <collection>Produces a single binary with subcommands
Pythonuv syncResolves dependencies into a project-local environment; no separate install step
TypeScriptbun install (frozen lockfile, falling back to a normal install) then bun build <entry> --compile --outfile <collection>Bundles into a single self-contained executable
RRscript -e <pak install script> if a DESCRIPTION or pkg.lock is present, otherwise Rscript setup.R if present, otherwise no build stepInstalls 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.0

7. 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.yaml

If 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.git
Cloning 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.0

From 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.0

Planned: 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 upload for packaging a collection ahead of future cloud distribution
  • spade login for authenticating to a Spade server
  • spade setup for initializing the local environment before installing
  • spade check for verifying the installed blocks work in a pipeline
  • spade init for creating a new collection to develop locally