DEV Community

Cover image for I built a free, local-first ETL tool in Rust — describe the pipeline in English, drop into SQL or Python - Odara
Samuel Ramos
Samuel Ramos

Posted on • Originally published at odara.rs

I built a free, local-first ETL tool in Rust — describe the pipeline in English, drop into SQL or Python - Odara

Every ETL tool I've used forces a trade-off.

The visual ones (Talend, Informatica, NiFi) are approachable but heavy — a JVM, a licensing conversation, and a wall the moment you need logic the UI didn't anticipate. The code-first ones are the opposite: total control, but you're writing boilerplate and wiring connectors before you've moved a single row.

I wanted the middle. Sketch the shape of a pipeline visually, and the instant I need real logic, drop into SQL or Python in the same canvas — no context switch, no export-to-code, no JVM. So I built it.

It's called Odara. It's free, it runs locally on your machine, and the engine is Rust + Apache DataFusion. Here's what it actually does.

Describe the pipeline, get the nodes

The part I use most: type the goal in plain English and let the AI assistant draft an ordered list of typed nodes. It doesn't generate a black box — it proposes real, editable nodes you review before they hit the canvas.

AI Assistant composing a pipeline from a plain-English description

"Read orders from PostgreSQL, keep completed, total revenue by category & month, write to Snowflake"

...becomes a Postgres source → filter → SQL aggregation → Snowflake target. You review it, tweak it, run it. The assistant works with DeepSeek, Anthropic/Claude, Gemini, or any OpenAI-compatible provider — you bring your own key, nothing is hardcoded to one vendor.

The AI is a starting point, not a cage. Which matters, because the next thing you'll want to do is edit.

Visual when you want it, code when you need it

Each node is one small, single-purpose block — a source, a transform, a target. You wire them on a React Flow canvas.

Visual pipeline editor with typed source, transform, and target nodes

The transforms are where the "polyglot" idea pays off:

  • SQL transforms run on DataFusion — Apache Arrow-native, Rust-native, no external database needed to compute a join or an aggregation.
  • Python transforms run in a subprocess with PyArrow for the data hand-off, so you get pandas/numpy/whatever-you-need without the engine leaving Rust.

You can mix both in one pipeline. A SQL block to aggregate, a Python block to hit some library SQL can't express, another SQL block to shape the output. Data moves between them as Arrow RecordBatch the whole way — no CSV round-trips between steps.

The connectors you actually reach for

Sources and targets covered out of the box:

  • Databases: PostgreSQL, MySQL, Oracle, SQL Server, MongoDB, Snowflake, DB2, generic ODBC
  • Files: CSV, Excel, XML, and a "Magic File" node that auto-detects the format
  • Cloud storage: S3, Google Drive, Azure Blob
  • Transfer: FTP / SFTP / FTPS
  • APIs: REST source (GET with pagination, auth, retry) and REST target (POST/PUT/PATCH with batching)
  • Streaming: Kafka, RabbitMQ, NATS, MQTT with window/aggregate/join operators

There's also a Talend-tMap-style Mapper node — N inputs, M outputs, joins, and per-field expressions — for the mapping-heavy work that's painful to express any other way.

Running and watching it

Pipelines execute with live progress over SSE. The monitor shows status, duration, and row counts per run, and it doesn't hide failures — a failed connector or a broken conditional branch shows up red with the actual error.

Execution monitor with live status, durations, and row counts

For anything bigger than a single pipeline, an orchestration layer (Maestro) runs pipelines in parallel, in series, or conditionally. And everything's versioned with Git — pipelines are just definitions, so you branch and diff them like code.

Why Rust

Because the boring answer is the real one: no JVM means no multi-hundred-MB runtime and no GC pauses mid-load. The whole thing is a native binary that starts fast and stays light. Execution supports proper cancellation via CancellationToken, jobs persist in SQLite (WAL mode), and connection credentials are encrypted at rest with AES-GCM.

It's local-first by default — your data and your pipelines stay on your machine. Nothing gets shipped to a cloud you didn't choose.

Where it's at, honestly

If you've ever wanted the approachability of a visual ETL tool without the JVM tax and the licensing dance — or you just want to describe a pipeline in a sentence and get real, editable SQL — I'd genuinely love your feedback.

Try it: https://odara.rs

What's the one ETL pain point you'd want a tool like this to kill first? Drop it in the comments — I'm building against real workflows, not a roadmap in a vacuum.

Top comments (0)