# stephenberry/glaze: a header-only C++ serialization and reflection library

> Glaze reads and writes structs directly from object memory across JSON, BEVE, CBOR, MessagePack, CSV, TOML and YAML. It is fast on the benchmark the project publishes, but it assumes you build with a modern compiler and can live without exceptions or RTTI.

**stephenberry/glaze** — Extremely fast, in memory, serialization, reflection, and RPC library for C++. JSON, BEVE, BSON, CBOR, CSV, JSONB, MessagePack, TOML, YAML, EETF

- Repository: https://github.com/stephenberry/glaze
- Website: https://stephenberry.github.io/glaze/
- Stars: 3,031 · Forks: 273
- Language: C++
- License: MIT
- Published: 2026-09-24 · Updated: 2026-09-24 · Language: en
- Canonical page: https://hysenlabs.com/projects/stephenberry-glaze

## The problem Glaze solves for C++ structs

Most C++ JSON libraries make you choose between two costs. Either you write mapping code by hand, or you accept a runtime representation that copies data into a document tree before you can touch it. Glaze takes a third path: it reflects aggregate structs at compile time and reads or writes them directly from object memory. The README describes this as "Direct to memory serialization/deserialization" and "Pure, compile time reflection for structs". The audience is C++ developers who already have plain structs and want them to cross a wire or a file boundary without a parallel set of DTO classes. The library is header-only, so there is no compiled artifact to link, and the format headers are separate (glaze/json.hpp, glaze/beve.hpp, glaze/cbor.hpp) so that including JSON does not drag in TOML or Erlang term support. That separation matters in large translation units where every extra header is a compile-time tax.

## How reflection and the format headers fit together

The mechanism is compile-time reflection over aggregate-initializable structs. The README states that Glaze can "Read/write aggregate initializable structs without writing any metadata or macros". A glz::meta specialization exists for cases where you need custom names or behaviour, but it is optional. Format support is organized as one header per format, each building on the same reflection core, so the same struct can be written as JSON or MessagePack without a second mapping. The README also lists compile-time maps with constant time lookups and perfect hashing, which is how key lookup avoids a runtime string comparison loop. Two constraints shape the design: the library compiles with -fno-exceptions and -fno-rtti, and it validates UTF-8 as part of RFC 8259 compliance. Under C++26 P2996 reflection the README claims additional reach: non-aggregate types with constructors and inheritance, automatic enum serialization to strings, private member access, and no 128-member cap. Those capabilities are gated on GCC 16+ with -std=c++26 -freflection or Bloomberg clang-p2996, which is a narrow set of compilers. The README also notes that HTTP support is arriving and that the networking API "is likely to be changing and improving", so the stable surface today is serialization, not servers.

## Installing Glaze and writing your first struct

The README points to the documentation site and the docs folder, and the repository root carries CMakeLists.txt, CMakePresets.json and a cmake/ directory, which is the shape of a CMake-based project. It is header-only, so the practical install is either adding the include directory to your build or consuming it through CMake. The README does not spell out a single canonical install command, so check the documentation page for the current one before copying anything.

Once the headers are on your include path, a minimal write looks like this. The struct needs no macros and no registration, because reflection is compile time.

```cpp
#include "glaze/json.hpp"
#include <string>

struct User {
   std::string name;
   int age;
};

User u{"Alice", 30};
auto json = glz::write_json(u).value_or("error");
// {"name":"Alice","age":30}
```

That snippet is adapted from the P2996 example in the README, which uses the same glz::write_json call and the same value_or fallback. The value_or form is the tell that Glaze does not throw by default: read and write return an expected-like result, and you decide what to do with the error. If you prefer exceptions for cleaner call sites, the README points to a separate Glaze Exceptions helper rather than changing the core. For reading, the same struct works in reverse through the JSON header. The exact read function name is not shown in the README excerpt, so confirm it against the JSON documentation page rather than guessing.

## Where Glaze is the wrong choice

The README's own caveat section is the honest part. It notes that simdjson and yyjson lose performance when data is not in the expected sequence or keys are missing, and that the problem grows with file size. That argument cuts both ways: Glaze's advantage is tied to knowing the struct shape at compile time. If your input is genuinely schemaless, if keys arrive in arbitrary order with unknown names, or if you need to inspect a document before deciding what it is, a DOM-style parser is a better fit. Glaze also assumes a modern toolchain. The P2996 features need GCC 16+ or Bloomberg clang-p2996, and the 128-member cap applies to the traditional reflection path. On an older compiler you get less than the README's headline list. The no-exceptions design is a constraint, not a neutral choice: error handling moves into return values everywhere, and code that assumes try/catch around a parse will not compile as written. Finally, the networking side is explicitly in flux. Building a REST service on Glaze today means tracking an API the README says is still changing.

## How Glaze differs from nlohmann/json and simdjson

The comparison table in the README puts Glaze at 1.01 s roundtrip, 1396 MB/s write and 1200 MB/s read, against nlohmann at 15.44 s roundtrip, 86 MB/s write and 81 MB/s read. Those are the project's own numbers from its json_performance repository, not an independent result. The approach difference is the real story. nlohmann/json builds a runtime value tree, so you can pass a json object around, inspect it dynamically, and convert later; that flexibility is what costs it in the table. simdjson is a parse-only, on-demand reader with no writer in the comparison, and the README notes it re-iterates through the document when keys are missing or out of order. Glaze sits closer to simdjson on read speed but keeps a writer and works from typed structs rather than an on-demand cursor. If your program manipulates JSON as data rather than as a serialized form of your own types, nlohmann's model is the one you want. If you only parse and never write, simdjson's on-demand approach avoids materializing anything you do not touch.

## Maintenance, licence and upgrade cost

The repository is not archived, and the last push was on 2026-09-23, with v8.4.0 released on 2026-09-15. That is a fast release cadence: v8.2.0 on 2026-08-27, v8.3.0 on 2026-08-29, v8.4.0 on 2026-09-15. Frequent minor releases are good for fixes and bad for pinning, so expect to read release notes between versions. The licence is MIT, which is permissive and places few conditions on redistribution, but this is not legal advice and you should confirm the terms in the LICENSE file against your own distribution model. Because the library is header-only, an upgrade is a header swap plus a rebuild, which is cheap in build time terms but exposes you to any API change in the headers you include. The README's warning about the networking API is the specific place where an upgrade can break you; the serialization headers are the safer surface.

## Conclusion

Adopt Glaze if you serialize structs in a C++ project and want compile-time reflection without writing metadata, and if your toolchain is a recent GCC, Clang or MSVC. Do not adopt it if you need a stable networking API today, since the README says the HTTP side is still changing, or if you must support an old compiler that lacks the reflection features. Before committing, verify that your compiler version passes the project's own tests, that your JSON input tolerates the strict RFC 8259 path, and that you are comfortable with the MIT licence terms for your distribution model.

## FAQ

### How do I install Glaze in a C++ project?

The README points to the documentation site and the docs folder, and the repository root contains CMakeLists.txt, CMakePresets.json and a cmake directory. Since Glaze is header-only, the practical install is adding its include directory to your build or consuming it through CMake. The README does not give one canonical install command, so check the documentation page for the current steps.

### Can I install Glaze on Windows?

The README lists MSVC among the compilers with C++23 compile time reflection support, and the P2996 path is documented for GCC 16+ and Bloomberg clang-p2996. There is no separate Windows installer, because the library is header-only and is consumed through your build system. The README does not document a Windows-specific setup beyond the compiler support.

### How do I use Glaze to serialize a struct to JSON?

Include glaze/json.hpp and call glz::write_json on an aggregate-initializable struct. The README's example writes a User with a name and age and produces {"name":"Alice","age":30}, with no metadata or macros required. The result is returned through value_or in that example, which reflects the library's no-exceptions design.

### Which serialization formats does Glaze support?

The README lists JSON, BEVE, CBOR, JSONB, BSON, CSV, MessagePack, Stencil/Mustache, TOML 1.1, YAML and EETF, each with its own header such as glaze/json.hpp or glaze/cbor.hpp. The separate format headers keep compilation overhead down when you only need one format.

### Does Glaze require exceptions or RTTI?

No. The README states that Glaze compiles with -fno-exceptions and -fno-rtti, and error handling goes through returned results rather than thrown exceptions. If you want throwing helpers for cleaner syntax, the README points to a separate Glaze Exceptions add-on.

## Sources

- [License: MIT](https://github.com/stephenberry/glaze/blob/main/LICENSE)
- [Project website](https://stephenberry.github.io/glaze/)
- [README](https://github.com/stephenberry/glaze/blob/main/README.md)
- [Releases](https://github.com/stephenberry/glaze/releases)
- [stephenberry/glaze on GitHub](https://github.com/stephenberry/glaze)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/stephenberry-glaze
