StackMap
Subscribe
Explore / loafer
lupppig

loafer

YAML-defined ETL/ELT engine with a CLI and self-hosted control plane: Postgres/MySQL/Mongo/CSV/REST/PDF in, upserts with cursors, validation and quarantine, durable workers — AI transforms optional.

6 1 Python MITupdated 21 days ago
View on GitHubDispute this mapping →
Curator's take

Loafer is an ETL engine first and an 'AI agent' only by its tagline: the AI is an optional transform step, and the example pipelines run with no API key. What it does well is make data movement legible — a pipeline file says source, transform class (row-local vs global pushdown), target, incremental cursor and what happens to bad rows. Use it for durable scheduled loads into Postgres/Mongo from a dev-friendly YAML. NOT for whole-dataset joins/aggregates in Python (it forces those to ELT pushdown by design), and not yet for the dashboard, OCR or crawl workers the README lists as in development. Six stars, v0-era — read PRODUCTION_READINESS.md first.

Mapped by ShipWithAI editors · links verified

Continue your stack

What teams reach for next — and why each earns a place beside loafer. Ranked by curator confidence.

alternativeduckleloafer
pairs wellalternativebuilt withpick a node for the why · open it from the panel
Weekly digest
README.md2 min read

Loafer

Loafer is an open-source ETL/ELT engine for defining data pipelines in YAML and running them from the command line or through a self-hosted control plane.

It exists to make serious data movement understandable: a pipeline says where data comes from, how it changes, where it goes, and what correctness rules apply. The same definition can run locally during development or as a durable job handled by independent workers.

Loafer currently supports:

  • PostgreSQL, MySQL, MongoDB, SQLite, CSV, Excel, REST, and PDF sources
  • PostgreSQL, MongoDB, CSV, and JSON targets
  • SQL, custom Python, multi-step, and optional AI-authored transforms
  • incremental cursors, validation, schema-drift policies, quarantine, and upserts
  • bounded row-local ETL and in-database ELT
  • durable schedules, retries, cancellation, checkpoints, and role-isolated workers
  • a self-hosted API and authentication boundary

The CLI engine and distributed runtime are implemented. The connected operations dashboard, distributed object storage, OCR/web-crawl workers, and native multi-pipeline DAGs are still in development. See Production readiness before choosing a workload or making scale guarantees.

Quick start

Python 3.11 or newer is required.

pip install loafer-etl
loafer --version

To run the included no-API-key example from a clone:

git clone https://github.com/lupppig/loafer.git
cd loafer
uv sync

uv run loafer validate examples/pipelines/04_bypass_ai.yaml
uv run loafer run examples/pipelines/04_bypass_ai.yaml --local --yes

--local is deliberate: local execution must be requested explicitly. Durable jobs are submitted with loafer enqueue and executed by a worker.

A pipeline at a glance

name: daily_orders
mode: etl
chunk_size: 5000

source:
  type: postgres
  url: ${SOURCE_DATABASE_URL}
  query: SELECT * FROM orders

transform:
  type: custom
  path: ./transforms/normalize_order.py

target:
  type: postgres
  url: ${WAREHOUSE_DATABASE_URL}
  table: analytics.orders
  write_mode: upsert
  key: order_id

incremental:
  column: updated_at
  initial: "1970-01-01"

execution:
  transform_class: row_local
  schema_drift: quarantine
  quarantine_path: ./rejected/orders.json

validation:
  required_columns: [order_id, updated_at]
  on_failure: quarantine

The important declaration is transform_class. Use row_local only when each output row depends on data in its current batch. Joins, aggregates, windows, sorts, and whole-dataset deduplication are global work and must use ELT pushdown or the materialized compatibility path.

Architecture

Loafer has one execution engine with two ways into it:

Local development
  CLI ───────────────────────────────────────────────┐
                                                     │
Durable deployment                                  ▼
  Browser → Next.js auth/BFF → loaferd          application service
  CLI/automation ────────────────┘                    │
                                  PostgreSQL          ▼
                              metadata + outbox → relay → NATS JetStream
                                                           │
                                               role-isolated workers
                                                           │
                                      extract → validate → transform → load
                                                           │
                                              sources, targets, artifacts

The metadata database is the authority for run state: PostgreSQL in a distributed deployment and SQLite in the embedded profile. NATS carries small job notifications, not pipeline definitions, credentials, or row data. A worker resolves the immutable pipeline version and its allowed secret references only after claiming a fenced lease.

Architectural decisions

Decision Why it matters
YAML is the pipeline contract Pipelines stay re