UnQLite: a C amalgamation with a key/value store and a Jx9 document layer in one file
An Embedded NoSQL, Transactional Database Engine
At a glance
- What is it?
- UnQLite embeds a transactional database in a C or C++ program by compiling two files, and offers raw key/value records or a Jx9 document store on top. It has no server, so everything depends on what the host process does.
- Who is it for?
- UnQLite fits a C or C++ application that wants local, transactional storage in one file and is happy to compile unqlite.c into its own binary. It does not fit anything that needs several processes or machines talking to one database, because the README says plainly that it is not client/server.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 5 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 November 7, 2026, and from our analysis. They are not legal advice.
Star history
- symisc/unqlite2,319 ★ · +2
| Repository | 2026-10-14 | 2026-11-07 |
|---|---|---|
| symisc/unqlite | 2.3k | 2.3k |
2 Stars in the last 24 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
The whole engine arrives as unqlite.c and unqlite.h
The recommended way to embed UnQLite is the amalgamation: two files at the repository root, `unqlite.c` and `unqlite.h`. The README calls this the intended drop-in path for production embedding. There is no library to install and no daemon to start, so integration means adding `unqlite.c` to your build.
The `src/` directory holds the split source tree and internal headers that are used to build and maintain the amalgamation. Treat it as the place to read how the engine is organised, and `unqlite.c` as the file you ship. The repository also carries a `CMakeLists.txt`, a `.gitlab-ci.yml`, a `CHANGELOG.md` for release notes, and an `update-md5.py` script at the top level.
The README describes the engine as self-contained, with no external runtime dependency, which is why the single-file approach works at all.
Compiling your application together with unqlite.c
The Quick Start has no separate build step for the library. You compile your own source and `unqlite.c` in one command. With GCC or Clang the README gives this:
cc -O2 -std=c99 -I. your_app.c unqlite.c -o your_appFor MSVC the equivalent is:
cl /nologo /TC /I. your_app.c unqlite.cThe `-std=c99` flag in the first command tells you the baseline language level the README expects, and `/TC` in the second makes MSVC treat the files as C. Both commands rely on `-I.` or `/I.` so that `#include "unqlite.h"` resolves from the repository root. If your source tree keeps third-party code elsewhere, adjust the include path accordingly.
Two layers: unqlite_kv_* records and a Jx9 document store
UnQLite exposes two layers. The lower one is a raw key/value store for binary-safe records. The upper one is a document store powered by Jx9, an embedded scripting language. The README states that if you only need embedded key/value storage, you can stay entirely within the `unqlite_kv_*` API family and ignore the document-store layer.
The key/value side covers CRUD calls and cursor APIs for linear traversal. The minimal example in the README opens a database with `unqlite_open(&db, ":mem:", UNQLITE_OPEN_CREATE)`, stores a record with `unqlite_kv_store`, and reads it back with `unqlite_kv_fetch_callback`, which hands the value to a callback you write. Passing `:mem:` as the name gives an in-memory database, and the README lists both on-disk and in-memory databases among the features.
The Jx9 side lets you bind foreign functions and constants into scripts, so C code can expose its own helpers to the document layer. A project that begins with plain records can therefore add scripting later without changing which engine stores the data, though the README gives no migration steps between the two layers and says nothing about how the document store lays records out inside the file.
One portable file, ACID semantics, and no network protocol
The README claims ACID semantics for local storage workloads and says a database is typically one file on disk. It adds that the file format is cross-platform, so a file written on one operating system can be opened on another. There is no socket protocol and no service to deploy.
That shape has a direct cost. Because the engine runs in-process, your application owns every failure mode: if the host process dies, the database goes with it, and the README describes no replication or remote access. Section Notes spells out the boundary in one line: UnQLite is not a client/server database.
A team that expects several services to read and write the same data over a network would have to put their own server in front of the file. The README offers no help with that.
Threading is a compile-time choice, not a default
Thread support is optional. The README says to define `UNQLITE_ENABLE_THREADS` when building if your application needs it, and gives both forms:
cc -O2 -std=c99 -DUNQLITE_ENABLE_THREADS -I. your_app.c unqlite.c -o your_appcl /nologo /TC /DUNQLITE_ENABLE_THREADS /I. your_app.c unqlite.cThe consequence is easy to miss. A build without the macro is a build without thread support, so a multithreaded program that forgets the `-D` flag is running a configuration the README does not describe as thread-ready. Decide at the start whether your threads will touch the database, and put the flag in your build system before the first test.
The README does not say how locking behaves under load or how many connections to one file are safe, so those questions go to the architecture page on the official site.
The samples directory is the real tutorial
The `samples/` directory holds small programs for common integration paths. `samples/1.c` is the key/value introduction, and the README gives a command to build it:
cc -O2 -std=c99 -I. samples/1.c unqlite.c -o unqlite_kv_intro`samples/2.c` through `samples/6.c` cover broader API use. `samples/unqlite_huge.c` handles large values, `samples/unqlite_tar.c` is an archive-oriented example, and `samples/unqlite_mp3.c` is metadata-oriented. There is also a `samples/demovfs/` folder and a `samples/CMakeLists.txt`.
The README advises a KV-only evaluation to start with `samples/1.c`. For document-oriented scripting it points next to the Jx9 documentation and samples. Beyond the repository, the official site lists a five-minute introduction, a C/C++ API reference, a cursor reference, an architecture overview and a FAQ, all linked from the README.
A recent release, a conflicting license field, and a short pluggable list
The release list shows `1.2.1`, published on 1 May 2026, with earlier entries for `v1.1.9` (a file handle leak fix, May 2019) and `1.1.9` (May 2018). The last push to the repository was on 23 October 2026, and it is not archived. The README names `1.2.1` as the current public release.
The license needs a second look. GitHub reports it as NOASSERTION, yet the README and the file `LICENSE` say 2-Clause BSD, and the README links an official licensing page at https://unqlite.symisc.net/licensing.html. Read that page and the LICENSE file before you ship the code in a product.
The README also lists a pluggable storage engine model and a virtual file system abstraction for portability, but gives no list of alternative engines. Whether you can swap the storage layer without reading `src/` is not something the README answers.
Editorial conclusion
UnQLite fits a C or C++ application that wants local, transactional storage in one file and is happy to compile unqlite.c into its own binary. It does not fit anything that needs several processes or machines talking to one database, because the README says plainly that it is not client/server. Before adopting it, build samples/1.c with your compiler, then check the licensing page the README links, since GitHub reports the license as NOASSERTION while the README says 2-Clause BSD.
Frequently asked questions
Is UnQLite a client/server database?
No. The README says UnQLite is not a client/server database. It runs in-process, with no separate daemon and no socket protocol.
How do I add UnQLite to a C project?
Compile your application together with unqlite.c, with unqlite.h on the include path. The README calls the amalgamation the recommended and simplest embed path.
What license does UnQLite use?
The README says UnQLite is distributed under the 2-Clause BSD license and links a licensing page. GitHub shows the license field as NOASSERTION.
Does UnQLite support threads?
Thread support is optional and is enabled at compile time by defining UNQLITE_ENABLE_THREADS when building the amalgamation.
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/symisc-unqlite)Star history chart for your README
[](https://hysenlabs.com/projects/symisc-unqlite)Was this useful?