Open-source project
apache/hamilton avatar
apache/hamilton

Apache Hamilton: Dataflow DAGs Built From Plain Python Functions

Apache Hamilton helps data scientists and engineers define testable, modular, self-documenting dataflows, that encode lineage/tracing and metadata. Runs and scales everywhere python does.

2,591 stars213 forksJupyter NotebookApache-2.0

At a glance

What is it?
Apache Hamilton (incubating) turns ordinary Python functions into a directed acyclic graph of data transformations, then executes that graph wherever Python runs. The idea is sound and the Apache licence is permissive, but the project is still in the incubator and the README carries a disclaimer saying the ASF has not fully endorsed it.
Who is it for?
Adopt Apache Hamilton if your team already writes pandas or Python transformation code and wants the dependency graph to be explicit, testable, and portable across a script, a notebook, and an orchestrator without a rewrite. Do not adopt it if you need loops or conditional control flow inside the graph, or if you require a project that has graduated from the Apache Incubator; the README states plainly that incubation means the ASF has not fully endorsed it.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly Jupyter Notebook, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The problem Hamilton addresses is dependency drift in Python data code

Most Python data work starts as a sequence of statements. You read a frame, clean it, join it, aggregate it, and write it out. The order lives in the file, not in the code. When someone reorders two lines or extracts a helper, nothing tells them they broke a downstream assumption until the pipeline runs. Hamilton's answer is to make the dependency order explicit by deriving it from function parameters. A function named B that takes A as an argument is, by construction, downstream of A. The README shows exactly this with functions B() and C() referring to function A via their parameters. The audience is data scientists and engineers who already write Python and want the structure of their transformation code to be inspectable rather than implied. It is a library, not a platform, and that distinction matters for who benefits most.

How the DAG is derived from function signatures

Hamilton loads a module of Python functions and builds a graph where each function is a node and each parameter name is an edge to the node that produces it. The README describes this as loading the definition and automatically building the DAG, and notes that the graph is built from a single line of code whether it has 10 or 1000 nodes. The same page states that Hamilton separates the DAG definition from its execution. That separation is the architectural claim: the module of functions describes what should be computed, and a driver decides when and how to compute it. The README also says Hamilton can assemble multiple Python modules into a pipeline, which is how larger projects avoid one enormous file. Lineage and metadata are described as encoded by the dataflow itself, and the Apache Hamilton UI is offered as a way to visualize, catalog, and monitor execution. The primary language listed for the repository is Jupyter Notebook, which reflects how the project documents and demonstrates itself rather than what it is: a Python library.

Installing Hamilton and the extras that matter

The base install is pip install apache-hamilton. Visualization is an optional extra, and the README is explicit that Graphviz must be installed on the system separately for it to work: pip install "apache-hamilton[visualization]". The UI and SDK are a second set of extras: pip install "apache-hamilton[ui,sdk]". There is a browser sandbox at tryhamilton.dev if you want to look before installing anything. The README claims Python 3.8+ support while the badge in the same file lists 3.10 through 3.14. Those two statements do not agree, and anyone pinning an interpreter version should treat the badge as the more current signal and verify against the package metadata before relying on 3.8 or 3.9. The README also points to @config.when() as the mechanism for changing a DAG between execution environments, positioned as a replacement for if/else feature flags. That decorator is the concrete config surface named in the material; the broader function modifiers documentation is linked but not reproduced, so the exact set of modifiers available is something you have to read at hamilton.apache.org/concepts/function-modifiers rather than infer from the README.

Where Hamilton is the wrong tool: loops, agents, and branching control flow

A DAG has no cycles, and Hamilton builds its graph from function signatures, so any logic that requires iteration or conditional control flow inside the graph does not fit the model. The README says this directly rather than hiding it: Hamilton is great for DAGs, but if you need loops or conditional logic to create an LLM agent or a simulation, it points to a sister library, Burr. That is an unusually honest boundary and it should be read as a real constraint, not a footnote. If your pipeline is fundamentally a state machine, a retry loop, or an agent that decides its own next step, Hamilton is the wrong layer. The second limitation is governance. The README carries an incubation disclaimer stating that Apache Hamilton is undergoing incubation at the ASF, sponsored by the Apache Incubator PMC, and that incubation indicates the project has yet to be fully endorsed by the ASF. The disclaimer also notes that incubation status is not necessarily a reflection of the completeness or stability of the code. Both halves of that sentence matter: it is not a stability warning, and it is not a guarantee either. Teams with procurement rules about incubating projects should treat this as a gating question, not a detail.

Hamilton versus Airflow: transformation library against scheduler

The comparison the README invites is with orchestration. Hamilton's claim is that your DAG is independent of infrastructure or orchestration, and that you can develop locally and reuse the code across contexts including Airflow and FastAPI. Airflow is a scheduler: it owns when tasks run, handles retries and backfills, and its DAGs are defined at the task level. Hamilton owns something different. It defines the transformation graph inside a process, from function signatures, and leaves scheduling to whatever is already running your code. In practice these compose rather than compete. You can define the transformation DAG in Hamilton and have Airflow call into it. The difference in approach shows up in granularity: an Airflow task might be one Python callable that internally runs a Hamilton driver, while the Hamilton graph holds the hundred intermediate nodes that the task does not see. That is the trade. You get fine-grained lineage and unit-testable nodes, and you take on a second concept to learn alongside your orchestrator. If your pipeline is five steps and unlikely to grow, the orchestrator alone is probably enough.

Maintenance cost and the Apache-2.0 licence

The licence is Apache-2.0, which permits commercial use, modification, and redistribution, and includes an explicit patent grant. It also requires that you preserve the licence and NOTICE files and state significant changes. That is the standard Apache arrangement and it is about as permissive as a corporate legal review is likely to want. This is not legal advice; check with your own counsel before shipping. On maintenance, the material shows a release cadence that is active but not rapid: v1.89.0-incubating in October 2025, followed by apache-hamilton-v1.90.0-incubating-RC0 in April 2026. The version string itself carries the incubating suffix, which means upgrade paths and release names will change if and when the project graduates. The dependency footprint is small by design, and the extras are opt-in, so the visualisation and UI packages are only a cost if you install them. The larger ongoing cost is conceptual: your team has to internalise that functions are nodes and parameters are edges, and that the driver, not the module, decides execution. That cost is paid once and then amortised across every pipeline that uses the same pattern.

Editorial conclusion

Adopt Apache Hamilton if your team already writes pandas or Python transformation code and wants the dependency graph to be explicit, testable, and portable across a script, a notebook, and an orchestrator without a rewrite. Do not adopt it if you need loops or conditional control flow inside the graph, or if you require a project that has graduated from the Apache Incubator; the README states plainly that incubation means the ASF has not fully endorsed it. Before committing, read the driver documentation at hamilton.apache.org/concepts/driver and the function modifiers page, and confirm that the modifiers you depend on behave the way your pipeline needs, because that is where the library's expressive surface lives.

Official sources

  1. apache/hamilton on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Community notes

Community notes