Open source · MIT · .NET Standard 2.0
The open-source ETL toolkit for .NET.
EtlKit is a free, MIT-licensed ETL library for .NET. Move data between databases, files and message queues with a few lines of C# — readable, testable, and versioned in git with the rest of your code.
$ dotnet add package EtlKit
var source = new CsvSource<Order>("orders.csv"); var clean = new RowTransformation<Order>(o => { o.Email = o.Email.Trim(); return o; }); var dest = new DbDestination<Order>(sqlConnection, "Orders"); source.LinkTo(clean).LinkTo(dest); await source.ExecuteAsync(); await dest.Completion;
- 6 relational databases — SQL Server, PostgreSQL, MySQL, SQLite, ClickHouse, Access
- 3 streaming sources — Kafka, MongoDB change streams, Postgres table tail
- 4 file formats — CSV, JSON, XML, Excel; from disk or over HTTP
- XML pipelines declared as configuration, loaded at runtime
- MIT all 15 NuGet packages, no paid tier
Code your ETL, not boilerplate.
Every pipeline is three steps: create the components, link them
with
LinkTo(), then execute the source and
wait for the destination. Rows stream through TPL Dataflow
buffers, so only the rows in flight are held in memory.
- DbSource
- CsvSource
- JsonSource
- ExcelSource
- KafkaJsonSource
- MongoChangeStreamSource
- PostgresXminTailSource
- RowTransformation
- LookupTransformation
- Aggregation
- Multicast
- MergeJoin
- RestTransformation
- AIBatchTransformation
- DbDestination
- DbMerge
- CsvDestination
- JsonDestination
- KafkaTransformation
- RabbitMqTransformation
- CheckpointWriter
Build ETL in .NET
Write pipelines in your favourite .NET language, with your IDE, debugger and unit tests. Source, transformation and destination components compose into a flow.
Runs everywhere
Written in .NET Standard 2.0 and tested on Linux, macOS and Windows with current .NET. Embed it in a web app, a worker service or a console job.
Made for big data
Built on Microsoft's TPL Dataflow with per-component buffers and
batched bulk writes —
SqlBulkCopy on SQL Server, binary
COPY
on PostgreSQL.
Manage change
Track ETL logic in git, review it, and run it through your existing CI/CD. Control-flow tasks replace ADO.NET ceremony for DDL and SQL with one line each.
What teams build with it.
EtlKit fits wherever data has to move on a schedule or as it arrives, and the people who own that job already write .NET.
Reporting loads
Nightly or hourly loads from OLTP databases into a reporting store — SQL Server or PostgreSQL into ClickHouse, with lookups and aggregations on the way.
Table synchronisation
Keep a copy of a table in another database in step with its
source:
DbMerge inserts, updates and
deletes only what changed.
Partner file imports
CSV, Excel and JSON files from partners or SFTP drops into your database, with malformed rows captured in an error table for follow-up.
Event ingestion
Kafka topics, MongoDB change streams or new rows in a PostgreSQL table, written to a database as they arrive and resumed from a checkpoint after a restart.
Moving off SSIS
Re-implement SSIS packages as C# that builds, tests and deploys with the rest of your services — and runs on Linux.
Enrichment
Call a REST API per row, or send batches to an OpenAI-compatible model to classify or extract fields, inside the same pipeline.
Connect to what you already use.
Source and destination components for common databases, queues and
file types — and a
CustomSource /
CustomDestination for anything else.
Most live in the core EtlKit package;
the rest are opt-in add-ons.
| Connector | Source | Destination | Streaming | Resumable | Bulk write | Package |
|---|---|---|---|---|---|---|
| SQL Server | ✓ | ✓ | — | — | SqlBulkCopy | EtlKit |
| PostgreSQL | ✓ | ✓ | — | — | Binary COPY | EtlKit |
| PostgreSQL table tail | ✓ | — | ✓ polling | ✓ checkpoint | — | EtlKit.PostgresStreaming |
| MySQL | ✓ | ✓ | — | — | Multi-row INSERT | EtlKit |
| SQLite | ✓ | ✓ | — | — | Batched in a transaction | EtlKit |
| ClickHouse | ✓ | ✓ | — | — | INSERT … FORMAT CSV | EtlKit.ClickHouse |
| MS Access (ODBC) | ✓ | ✓ | — | — | Multi-row INSERT | EtlKit |
| MongoDB change streams | ✓ | — | ✓ | ✓ resume token | — | EtlKit.MongoDB |
| Kafka | ✓ | ✓ producer | ✓ | Consumer group offsets | Batched producer | EtlKit.Kafka |
| RabbitMQ | — | ✓ publish | — | — | — | EtlKit.RabbitMq |
| CSV · JSON · XML | ✓ | ✓ | — | — | Streamed, file or HTTP | EtlKit |
| Excel | ✓ | — | — | — | — | EtlKit |
| REST / HTTP | ✓ | ✓ | — | — | Per-row calls | EtlKit.Rest |
| OpenAI-compatible LLM | Batch transformation: prompt template in, structured rows out | EtlKit.AI | ||||
| .NET collections | ✓ | ✓ | — | — | — | EtlKit |
Resumable sources save their position through
ICheckpointStore
and continue from it after a restart (at-least-once). The PostgreSQL
tail polls by transaction ID: it sees inserts and updates, but not
deletes — it is not logical-replication CDC.
Hand-written code vs EtlKit.
What a typical data task takes when you write it from scratch on ADO.NET and client libraries, and what it takes with EtlKit.
| Task | By hand | With EtlKit |
|---|---|---|
| Bulk load |
SqlBulkCopy with a DataTable on
SQL Server, binary COPY on Postgres, batched
INSERTs elsewhere — one code path per database.
|
DbDestination<T>
picks the fastest write path for the connection and batches
rows for you.
|
| Upsert / sync a table |
A staging table plus
MERGE or ON CONFLICT in each
SQL dialect, and a separate pass for deletions.
|
DbMerge<T> with
[IdColumn] and [CompareColumn]:
full, no-deletions or delta mode, same code on five
databases.
|
| CSV → database | A reader loop, type conversion, batching and try/catch around every bad line. |
CsvSource<T> →
DbDestination<T>; bad rows go to
LinkErrorTo().
|
| Kafka → database | A consumer loop, JSON deserialisation, batching writes and shutdown handling. |
KafkaJsonSource<T> →
DbDestination<T>
with a cancellation token.
|
| Tail a Postgres table | A polling query, a stored cursor, and care not to skip rows from transactions still in flight. |
PostgresXminTailSource<T>
+ CheckpointWriter with a
DbCheckpointStore.
|
| MongoDB changes → SQL |
A Watch() loop and your own storage for resume
tokens.
|
MongoChangeStreamSource<T>
resumes from the token in its checkpoint store.
|
Code, or configuration.
With EtlKit.Serialization
the same components can be declared in XML and loaded at runtime:
element names are class names, child elements are properties.
Change a pipeline without recompiling the host.
<EtlDataFlowStep> <Pipeline> <CsvSource><Uri>orders.csv</Uri></CsvSource> <ExpressionRowFiltration> <FilterExpression>Amount > 0</FilterExpression> </ExpressionRowFiltration> <LinkTo> <DbDestination> <ConnectionManager type="PostgresConnectionManager"> <ConnectionString>Host=db;Database=sales</ConnectionString> </ConnectionManager> <TableName>orders</TableName> </DbDestination> </LinkTo> </Pipeline> </EtlDataFlowStep>
Is EtlKit the right tool?
EtlKit is a library for developers. If that is not what you need, one of these will serve you better.
| If you need | Pick |
|---|---|
| Pipelines written in C#, reviewed and tested like the rest of your code, running inside your own app or job on any OS | EtlKit — MIT, no server to run |
| A visual designer for a SQL Server-centric team, scheduled by SQL Server Agent | SSIS — ships with SQL Server licences, Windows-first |
| A vendor-supported .NET ETL library with commercial support and the newer ETLBox feature set | ETLBox 2.x+ — closed-source, commercial licence. EtlKit continues its open 1.x line |
| Hundreds of ready-made SaaS connectors and a UI for loading data into a warehouse | Airbyte — an ELT platform you deploy and operate |
| A long-running data routing server with a visual flow editor and provenance tracking | Apache NiFi — JVM-based |
| One query, one table, run once | Plain ADO.NET or Dapper — no library needed |
Resources
Everything lives in the open. Browse the guides, read the API reference, or grab a release.
Hand-written guides and tutorials, browsable directly in the repo.
Ask AI ↗Chat with an assistant trained on EtlKit's docs and source, via Context7.
API Reference ↗Generated from XML comments — the full public surface of every component.
Releases ↗Tagged versions and release notes on GitHub.
NuGet packages ↗EtlKit and its connector packages (Kafka, MongoDB, REST, and more).
Changelog ↗What changed between versions, including the 1.x → 2.0 rename mapping.
Source code ↗The full solution on GitHub — issues, pull requests, and tests.
llms.txt ↗A plain-text summary of EtlKit for AI coding assistants.