CGraph: A Dependency-Free C++ and Python DAG Framework
【A common used C++ & Python DAG framework】 一个通用的、无三方依赖的、跨平台的、收录于awesome-cpp的、基于流图的并行计算框架。欢迎star & fork & 交流
At a glance
- What is it?
- CGraph is a cross-platform directed acyclic graph execution framework written in pure C++11 with no third-party dependencies, with a Python binding called pycgraph. It suits engineers who need to describe parallel task schedules in code, and it is a poor fit for anyone wanting a managed workflow service.
- Who is it for?
- Adopt CGraph if your pipeline is a fixed dependency graph of C++ tasks and you want to avoid pulling in a scheduler dependency; the README's own demo shows node A fanning out to B and C and joining at D. Do not adopt it if you need a hosted workflow service, dynamic graph mutation at runtime, or a language other than C++ and Python.
- Can I use it commercially?
- Yes. MIT 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 1 day ago.
- What is it written in?
- Mainly C++, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The scheduling problem CGraph is built around
Most build and data pipelines start as a shell script and end as a mess of manual thread management. CGraph targets that middle ground: a fixed set of tasks whose dependencies you know at compile time, where some tasks can run in parallel and others must wait. The README describes it as a cross-platform directed acyclic graph framework based on pure C++ without any third-party dependencies, and the pitch is that you build your own operators and describe running schedules such as dependence, parallelling and aggregation yourself.
The intended user is a C++ engineer who wants graph-shaped execution without adopting a build system, a message broker or a runtime. The README states the project is written against the C++11 standard library and supports MacOS, Linux, Windows and Android, with local compilation and secondary development. A Python binding, pycgraph, is published separately so the same scheduling model is available without writing C++.
How GPipeline, GNode and GGroup fit together
The core abstraction is GPipeline, which the README calls the pipeline responsible for underlying scheduling. You register nodes into it and declare edges by passing the upstream nodes as a set. Each node is a subclass of GNode whose run() method you override; the framework calls run() when the node's dependencies have completed. GGroup is the second abstraction, holding multiple nodes so you can express conditional branches, loops and concurrency control at the group level rather than per node.
The README's demo graph makes the data flow concrete: node a runs first, then b and c run in parallel because both depend only on a, and d runs after both b and c finish. That fan-out and join is the whole execution model, and the README states the framework also supports pause, resume and timeout settings on top of it. The repository ships a tutorial/ directory and an example/ directory with eight numbered examples covering an autopilot mock, a mock GUI, a MapReduce flow, an HTTP server and a parallel sort, which is where the real usage patterns live rather than in the README.
Installing CGraph and running a first graph
The README does not put build steps inline; it points at COMPILE.md in the repository root for compilation and installation instructions. The top-level layout includes CMakeLists.txt, xmake.lua, MODULE.bazel and WORKSPACE, so CMake, xmake and Bazel are all represented as build entry points, along with helper scripts such as CGraph-build.sh and CGraph-ninja-build.sh. Check COMPILE.md for the platform-specific procedure before choosing one.
The Python route is shorter. The README's Python example begins with a pip install comment, and the package name on PyPI is pycgraph:
pip install pycgraphAfter installing, the README's Python demo constructs a GPipeline, creates four node instances, registers them with dependency sets, and calls process(). The registration call takes the node, the set of upstream nodes, and a name string:
from pycgraph import GNode, GPipeline, CStatus
pipeline = GPipeline()
a, b, c, d = MyNode1(), MyNode2(), MyNode1(), MyNode2()
pipeline.registerGElement(a, set(), "nodeA")
pipeline.registerGElement(b, {a}, "nodeB")
pipeline.registerGElement(c, {a}, "nodeC")
pipeline.registerGElement(d, {b, c}, "nodeD")
pipeline.process()Each node subclass overrides run() and returns a CStatus. In the README's example the nodes sleep for one or two seconds and print their names, so running it should show nodeA first, then nodeB and nodeC interleaved, then nodeD. The C++ version follows the same shape but registers nodes through a template parameter on the pipeline:
pipeline->registerGElement<MyNode1>(&a, {}, "nodeA");
pipeline->registerGElement<MyNode2>(&b, {a}, "nodeB");
pipeline->registerGElement<MyNode1>(&c, {a}, "nodeC");
pipeline->registerGElement<MyNode2>(&d, {b, c}, "nodeD");
pipeline->process();In C++ the pipeline comes from GPipelineFactory::create() and is released with GPipelineFactory::remove(pipeline), as the README demo shows. Skipping the remove call is the kind of resource leak the example is there to warn you about.
Where CGraph stops being the right tool
CGraph assumes a graph you can describe in source code. The README's own framing is that you set dependencies when registering elements, which means the topology is a compile-time or startup-time decision. If your workflow needs to add nodes in response to runtime events, or if the graph itself is data that changes per request, this model fights you. There is no mention in the README of serializing a graph to disk, loading one from a config file, or mutating the graph while process() is running.
The second boundary is language. The README lists C++ and Python bindings and points to separate sibling repositories for C#, Java and Go, described as API-liked DAG projects rather than bindings of this codebase. If your team is not writing C++ or Python, you are looking at a reimplementation, not this framework.
A third point worth weighing: the README states the project has no third-party dependencies, which is the selling point, but it also means the framework brings its own thread pool and scheduling logic rather than delegating to an established executor. The README's recommended-reading list has five separate articles on thread pool optimization, which tells you the author treats that layer as an ongoing area of work rather than a settled one. That is a fair reason to check the release notes before pinning a version.
CGraph compared with a general-purpose task graph library
The closest comparison in the C++ world is a header-only task graph library where you express work as futures and continuations. The difference is in what the graph knows about itself. In a futures-based model the graph is implicit in the composition of the futures, and the library has no object representing the whole schedule. CGraph inverts that: GPipeline is an explicit object you register into, and GGroup lets you attach conditional, loop and concurrency semantics to a named subset of nodes. That makes the graph inspectable and lets you pause, resume or time out the whole run, which the README lists as supported behavior.
The trade-off is boilerplate. A futures chain of three steps is three lines; the equivalent CGraph code is three subclasses, a pipeline creation, three registration calls, a process call and a removal call. The README's own demo needs two node classes and roughly twenty lines to express a four-node diamond. If your graph is small and static, that overhead is not buying you much. If your graph has groups with loop and condition semantics, the explicit structure is the point.
A Python comparison is instructive too. pycgraph exposes the same GPipeline and GNode names, so a Python developer gets the C++ scheduling model rather than a Pythonic replacement for it. That is deliberate, and it means the Python API reads like a binding, not like a native library.
Licence, releases and what upgrades cost
CGraph is MIT licensed, which places few restrictions on commercial use and modification; the LICENSE file is at the repository root. MIT does not require you to publish your changes, but it does require the copyright notice and permission notice to travel with copies or substantial portions of the software. That is a description of the licence text, not legal advice, and if you are redistributing a modified CGraph inside a product, the exact wording is worth reading yourself.
The release cadence visible in the repository is roughly every two to three months: v3.2.3 in March 2026, v3.2.4 in May 2026, and v3.2.5 in August 2026. The last push to the default branch was on 2026-09-07, and the repository is not archived. Patch-level versioning suggests the maintainer is not promising API stability across minor versions, so pinning a tag rather than tracking main is the safer default. The repository includes functional test and performance test scripts at the root, which gives you a way to validate an upgrade locally before adopting it.
Editorial conclusion
Adopt CGraph if your pipeline is a fixed dependency graph of C++ tasks and you want to avoid pulling in a scheduler dependency; the README's own demo shows node A fanning out to B and C and joining at D. Do not adopt it if you need a hosted workflow service, dynamic graph mutation at runtime, or a language other than C++ and Python. Before committing, read COMPILE.md for the platform you target, confirm the Python binding version on PyPI matches your interpreter, and check the release notes for v3.2.5 to see what changed since the version you plan to pin.
Frequently asked questions
What is CGraph?
CGraph is a cross-platform directed acyclic graph framework written in pure C++11 with no third-party dependencies, according to the README. It schedules tasks by letting you register nodes into a GPipeline and declare dependencies between them, and a Python binding called pycgraph exposes the same model.
What is the simplest definition of a graph?
The README does not define a graph in the general mathematical sense. CGraph's README describes its own subject as a directed acyclic graph framework, where nodes are tasks and edges are the dependencies that determine execution order.
What is a graph example?
The README's C++ demo is a concrete example: four nodes named a, b, c and d, where a runs first, b and c run in parallel after a, and d runs once both b and c have finished. The Python example in the README builds the same graph with pycgraph.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/chunelfeng-cgraph)