A
A

Data processing at scale. Built for geospatial.

Build powerful data pipelines with reusable blocks in any language.

What is Spade?

Spade is a data processing system designed for massive data with first-class geospatial support. It lets you build complex workflows by connecting reusable, isolated computational blocks.

Processing steps are independent blocks that execute in isolation — each one a sandboxed subprocess with typed inputs and outputs. Write them in Python, R, Go, Rust, or TypeScript.

Define your workflows as declarative YAML pipelines. The scheduler resolves dependencies and executes blocks in parallel, handling caching, map/reduce operations, and fault recovery automatically.

Data
Pipeline
Blocks
Results

Deal Yourself a Winning Hand

Everything you need to build, run, and scale data processing pipelines.

Multi-Language Blocks

Write blocks in Python, R, Go, Rust, or TypeScript. Spade handles the rest.

Declarative Pipelines

Define workflows as YAML. The scheduler resolves dependencies and parallelizes execution.

Geospatial First

Native support for raster, vector, and tabular geospatial data through GDAL integration.

Map/Reduce at Scale

Fan out across collections and reduce results back together, automatically.

Secure by Default

Each block runs in an isolated sandbox with restricted filesystem and network access.

CLI + Web UI

Develop locally with the CLI. Deploy and collaborate through the web interface.

How It Works

1

Define

Write your processing block as a simple function with typed inputs and outputs.

def handler(src: RasterFile)
    -> RasterFile:
  result = process(src)
  return RasterFile(result)
2

Compose

Chain blocks into a pipeline using YAML or the visual flowchart editor.

blocks:
  - name: reproject
    inputs: [source]
  - name: analyze
    inputs: [reproject]
3

Execute

The scheduler handles dependencies, parallelism, caching, and sandboxed execution.

$ spade run pipeline.yaml
✓ reproject (2.1s)
✓ analyze (4.3s)
Pipeline complete!

Simple by Design

Type-safe inputs and outputs. Automatic parameter loading. Zero boilerplate.

from spade import run, RasterFile

def handler(source: RasterFile) -> RasterFile:
    # Your processing logic here
    return RasterFile(path=result)

if __name__ == "__main__":
    run(handler)
library(spade)

handler <- function(source) {
  # Your processing logic here
  RasterFile(path = result)
}

run(handler)
import { run, RasterFile } from "spade";

function handler(source: RasterFile): RasterFile {
  // Your processing logic here
  return new RasterFile(resultPath);
}

run(handler);
package main

import "github.com/spade-dev/spade-go"

func handler(source spade.RasterFile) spade.RasterFile {
    // Your processing logic here
    return spade.NewRasterFile(resultPath)
}

func main() {
    spade.Run(handler)
}
use spade::{run, RasterFile};

fn handler(source: RasterFile) -> RasterFile {
    // Your processing logic here
    RasterFile::new(result_path)
}

fn main() {
    run(handler);
}

Built for Real-World Data

Remote Sensing

Processing satellite imagery at scale, including reprojection, tiling, and analysis across massive raster datasets.

Learn More →

Geospatial ETL

Extracting, transforming, and loading spatial datasets across formats and coordinate systems at any scale.

Learn More →

Scientific Pipelines

Reproducible research workflows combining data from multiple providers and processing steps.

Learn More →

Ready to Play?

Get started in minutes with the Spade CLI.

$ spade init python
$ spade add my-block
$ spade run pipeline.yaml