Open-source project
LadybugDB/ladybug avatar
LadybugDB/ladybug

Ladybug: an embedded graph database that arrives under three names at once

LadybugDB a graph database

1,766 stars146 forksC++MIT

At a glance

What is it?
The project formerly published as Kuzu keeps its engine, its packages and its query language through a rename, so half the ecosystem still calls it lbug.
Who is it for?
Ladybug is an embedded analytical graph database in the same family as DuckDB and SQLite, where the library links into your process and there is no server to operate. What distinguishes it is the query engine work: a vectorized and factorized processor, columnar CSR join indices, and what the project claims are fast join algorithms.
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 22 days 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 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

An embedded engine, with the feature list to match

The README describes Ladybug as an embedded graph database built for query speed and scalability, optimized for complex analytical workloads on very large databases. That is a specific claim and worth parsing, because embedded and very large are usually opposites in the database world.

The reconciliation is that embedded here means no separate process. The engine links into your application, as SQLite does, so there is no daemon, no connection pool to configure and no separate deployment unit. What it inherits from the server world is the storage engine design: a flexible property graph data model with Cypher as the query language, columnar disk-based storage, and serializable ACID transactions.

The rest of the feature list is where the analytical framing shows. There is native full text search and vector index, adjacency list and join indices in columnar sparse row format, a vectorized and factorized query processor, multi-core query parallelism, and what the README calls novel and very fast join algorithms. Those five items together are the argument for the design: you are paying for a storage layout and an execution strategy that are not the ones SQLite uses.

One more item stands out from the rest: Wasm bindings for fast, secure execution in the browser. That is a different deployment target from the other eleven features, and it tells you the project is aiming at client-side graph workloads, not only server-side analytics.

The rename from Kuzu, and what it did not rename

One line in the README does most of the explaining: the database was formerly known as Kuzu, with a link to the old repository. This is a rebrand of an existing, mature project rather than a new database, and the traces of the old name are everywhere in the current one.

Look at the install table and the two naming schemes appear side by side. The Python package is `ladybug`. The Node package is `@ladybugdb/core`. The Rust crate is `lbug`. The Go package is `github.com/LadybugDB/go-ladybug`. The Java artifact sits on Maven Central under `com.ladybugdb/lbug`. In other words, three of the bindings still use the abbreviation from the previous name, and only the Python one uses the full word. If you are copying an install command from an older tutorial or an older LLM answer, the `lbug` names are not wrong, they are just older.

The same split appears in the social links. The Discord invite and the contact address use the new domain, ladybugdb.com, while the Twitter handle is `@lbugdb`.

The versioning did not restart either. Current tags are in the v0.20.x range, which is a continuation of the old numbering rather than a fresh 1.0. Given that the project has 1,766 stars and 146 forks, treating v0.20 as an early-stage release would be a mistake; the pre-1.0 numbering reflects a project's conservatism about promising stability, not its age.

Six languages, one install table

The README's installation section is a table rather than a paragraph, and that choice makes it easy to miss how many official bindings exist. Python, NodeJS, Rust, Go, Swift, Java, C/C++ and a CLI are all listed.

bash
pip install ladybug
npm install @ladybugdb/core
cargo add lbug
go get github.com/LadybugDB/go-ladybug

The first three are one-liners. Swift and Java are not, because both point at separate repositories or a Maven coordinate rather than a registry you can name in one line, and C/C++ and the CLI point at precompiled binaries on the releases page rather than a package manager.

That pattern is informative. The bindings where the engine is small enough to package cleanly get a package manager entry, and the bindings where it is not get a repository or a download. Swift's separate repository and Java's Maven artifact are the two cases worth knowing about if you are not writing in Python, Rust or Node.

The README itself is candid that it is not the manual. Getting Started, the installation page and the developer guide are all on docs.ladybugdb.com, and the build-from-source instructions point there rather than repeating themselves. For a project with a compiled C++ core, that is the normal arrangement, and it means the documentation site rather than the repository is where evaluation decisions get settled.

Extensions, and the case for staying inside one process

The `Makefile` is more informative about scope than any prose in the repository, because it declares the extension list as a single variable at the top:

make
EXTENSION_LIST ?= adbc;httpfs;duckdb;json;postgres;pg_client;sqlite;fts;delta;iceberg;azure;unity_catalog;ducklake;vector;neo4j;algo;llm;gql

Read that as a capability list. You can federate out over HTTP with `httpfs`, talk to Postgres two ways, read local and remote SQLite, get full text search, reach Delta Lake and Iceberg tables, connect to Azure object storage, Unity Catalog and DuckLake, use vector search, traverse into Neo4j, and there are algo, llm and gql extensions at the end. The ADBC entry means it can also be consumed as a Python database through the Arrow database connectivity standard.

This is the part of the design that most deserves attention. In a server architecture, a query touching Delta, Iceberg, Postgres and Neo4j would mean four network hops and four failure domains. Here it is one process and one transaction boundary. That is the payoff of embedding the engine, and it is a real one for analytical workloads where federated joins are the actual bottleneck.

The rest of the `Makefile` shows the engineering investment. It declares a large set of explicit targets for every binding, including `javatest`, `nodejstest`, `pytest`, `wasmtest`, `rusttest`, `benchmark` and `example`, with configurable job counts and a separate end-to-end extension test pass. It also sets `PGEMBED_PYTHON ?= 3.12`, which tells you the embedded Python runtime version, and builds with `.ONESHELL:` and `-ec` shell flags so any failing step in a chained command stops the target.

Recent releases, and what the bug list reveals

The three most recent tags are close together and fix real defects, which is a healthy sign for a storage engine.

v0.20.4, on 2026-09-10, carries only a changelog link. v0.20.3, on 2026-09-08, fixes `canRead` so it accepts storage version 46. That one is worth pausing on: a storage version number appearing in a bug fix means the on-disk format is versioned and gated, and a reader that refused a newly written file would have been a serious data-access problem. The fix suggests someone hit exactly that.

v0.20.2, on 2026-09-02, is the substantive one. Its entries include a fix for re-executed parameterized queries returning stale rows on the cached-plan fast path, a fix for a bad downcast of ArrowResultCollector in the plan mapper that had been skipping arrow and CSR tests, an extension submodule update to fix tests, and a fix to the Iceberg extension's REST catalog file binder. The stale rows on re-execution is a correctness bug in prepared statement handling, and the fact that it surfaced on a fast path suggests the slow path was doing an extra step that the fast path skipped.

Read together, these tell you the query engine and the storage format are both still moving, which is consistent with a pre-1.0 embedded database. The Arrow work also confirms the columnar and vectorized story is real rather than aspirational, since a bad downcast in the Arrow result collector is exactly the kind of bug you get when you are pushing results into Arrow-compatible structures for downstream analytics.

What the repository tree says about the engineering

The root of the repository is a C++ project with a build system chosen for lint coverage and tool configuration rather than for minimum ceremony. Alongside the expected `CMakeLists.txt`, `Makefile` and `LICENSE`, there is `.clang-format`, `.clang-format-ignore`, `.clang-tidy` and `.clang-tidy-analyzer`, plus `.lcovrc` for coverage output and `.gitmodules` for vendored dependencies.

The directories describe the shape of the work. `src/` is the engine, `tools/` is the command line tooling, `extension/` is where the extension list from the Makefile actually lives, `benchmark/` is a first-class directory rather than a script, `test/` is the C++ test suite, and `examples/` and `docs/` sit alongside. There is a `dataset/` directory, which is worth noting because it suggests test data is committed rather than downloaded, and a `third_party/` directory for vendored code.

Two root files say something the README does not. `partition-routing-hook.md` describes a feature the feature list never mentions, which suggests partitioning-aware query routing exists or is planned. And `AGENTS.md` sits next to `CONTRIBUTING.md`, so parts of this codebase are worked on with coding agents, which tells you something about how the remaining work gets done.

The `security/` directory and `SECURITY.md` are also present. For an embedded database that processes untrusted files, that combination is a reasonable baseline, though the README does not make any security claims, so there is nothing further to assess from the project's own description.

Editorial conclusion

Ladybug is an embedded analytical graph database in the same family as DuckDB and SQLite, where the library links into your process and there is no server to operate. What distinguishes it is the query engine work: a vectorized and factorized processor, columnar CSR join indices, and what the project claims are fast join algorithms. What the rename leaves unsettled is naming. The project is Ladybug, the artifacts are still `lbug`, the npm package is `@ladybugdb/core`, and the historical name Kuzu is one search away at all times. If you are evaluating it, install `ladybug` from pip or `lbug` from Cargo, write your first query against the Getting Started page, and check the extension list in the Makefile before assuming you will need to federate out to another engine, because Delta, Iceberg, Postgres, Neo4j and plain SQLite are all reachable from inside a single Ladybug process.

Frequently asked questions

Is Ladybug the same project as Kuzu?

Yes, it is a rename rather than a fork. The README states the database was formerly known as Kuzu and links to the old repository. Version numbering continued across the change, so v0.20.x tags are a continuation of the old series. Install names for Rust, Go and Java still use the abbreviation, which is why `cargo add lbug` and `pip install ladybug` refer to the same engine.

What is Ladybug used for compared with a graph database server?

The difference is process ownership rather than data model. Ladybug links into your application the way SQLite does, so there is no daemon to deploy. It is aimed at analytical graph workloads, with columnar disk-based storage, CSR join indices, multi-core parallelism and serializable ACID transactions. Neo4j remains reachable as an extension, so the two can coexist in one query rather than being mutually exclusive choices.

Does Ladybug need a server?

No. It is described as an embedded, serverless integration into applications, and the C/C++ and CLI distribution is a precompiled binary you link or run locally. There is a WebAssembly build for browser execution, which is the one deployment shape that could not be described that way.

Can Ladybug query data outside its own storage?

Yes, and that is a substantial part of the design. The Makefile's extension list includes httpfs for remote files, Postgres, SQLite, Delta, Iceberg, Azure, Unity Catalog, DuckLake, Neo4j, full text search and vector search. Because the engine is embedded, a query spanning several of those stays in one process and one transaction boundary instead of crossing multiple network hops.

What query language does Ladybug use?

Cypher, over a flexible property graph data model. Cypher is listed both as the query language and as a repository topic. The README does not describe which dialect features are supported, so if you are porting a Cypher query from another engine you would want to check the docs site rather than assume full compatibility.

Official sources

  1. LadybugDB/ladybug on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/ladybugdb-ladybug.svg)](https://hysenlabs.com/projects/ladybugdb-ladybug)