Glaze Quick Start Guide¶
Glaze is one of the fastest JSON libraries in the world, featuring compile-time reflection that lets you serialize C++ structs without writing any metadata or macros.
Basic Reflection¶
Simple Struct Serialization¶
#include "glaze/glaze.hpp"
struct Person {
int age = 25;
std::string name = "John";
double height = 5.9;
};
int main() {
Person person{30, "Alice", 5.7};
// Write to JSON
std::string json = glz::write_json(person).value_or("error");
// Result: {"age":30,"name":"Alice","height":5.7}
// Read from JSON
std::string input = R"({"age":25,"name":"Bob","height":6.1})";
Person new_person{};
auto error = glz::read_json(new_person, input);
if (!error) {
std::string error_msg = glz::format_error(error, input);
std::cout << error_msg << std::endl;
}
else {
// Success! new_person is now populated
std::cout << new_person.name << " is " << new_person.age << " years old\n";
}
return 0;
}
Alternative Expected Handling¶
// Using std::expected return values
auto result = glz::read_json<Person>(input);
if (result) {
Person person = result.value();
// Use person...
} else {
// Handle error
std::string error_msg = glz::format_error(result, input);
std::cout << error_msg << std::endl;
}
Custom Field Names¶
Use glz::meta
to customize JSON field names:
struct Product {
int id;
std::string name;
double price;
};
template <>
struct glz::meta<Product> {
using T = Product;
static constexpr auto value = glz::object(
"product_id", &T::id,
"product_name", &T::name,
"unit_price", &T::price
);
};
// JSON will use: {"product_id":123,"product_name":"Widget","unit_price":9.99}
Containers and Standard Types¶
Glaze automatically handles standard containers:
struct Data {
std::vector<int> numbers = {1, 2, 3};
std::map<std::string, std::string> config = {{"key", "value"}};
std::array<double, 3> coordinates = {1.0, 2.0, 3.0};
std::optional<std::string> description; // null if empty (output skipped by default)
};
// JSON: {"numbers":[1,2,3],"config":{"key":"value"},"coordinates":[1,2,3]}
Enums as Strings¶
enum class Status { Active, Inactive, Pending };
template <>
struct glz::meta<Status> {
using enum Status;
static constexpr auto value = glz::enumerate(Active, Inactive, Pending);
};
struct Task {
std::string name;
Status status = Status::Pending;
};
// JSON: {"name":"My Task","status":"Pending"}
File I/O¶
Person person{25, "Charlie", 5.8};
// Write to file
auto write_error = glz::write_file_json(person, "./person.json", std::string{});
// Read from file
Person loaded_person{};
auto read_error = glz::read_file_json(loaded_person, "./person.json", std::string{});
Pretty Printing¶
Person person{25, "Diana", 5.6};
// Write prettified JSON
std::string pretty_json;
auto error = glz::write<glz::opts{.prettify = true}>(person, pretty_json);
// Or prettify existing JSON
std::string minified = R"({"age":25,"name":"Diana","height":5.6})";
std::string beautiful = glz::prettify_json(minified);
Optional Fields and Null Handling¶
struct User {
std::string username;
std::optional<std::string> email; // Can be null
std::unique_ptr<std::string> bio; // Can be null
};
User user{"alice", std::nullopt, nullptr};
// With skip_null_members (default: true)
// JSON: {"username":"alice"}
// With skip_null_members = false
std::string json;
glz::write<glz::opts{.skip_null_members = false}>(user, json);
// JSON: {"username":"alice","email":null,"bio":null}
Variants¶
struct Circle { double radius; };
struct Rectangle { double width, height; };
using Shape = std::variant<Circle, Rectangle>;
struct Drawing {
std::string name;
Shape shape;
};
// Glaze automatically handles variants based on which fields are present
Error Handling with Details¶
std::string invalid_json = R"({"name": "test", "age": "not_a_number"})";
Person person{};
auto error = glz::read_json(person, invalid_json);
if (error) {
std::string detailed_error = glz::format_error(error, invalid_json);
std::cout << detailed_error << std::endl;
// Shows exactly where the error occurred with context
}
Common Options¶
// Read with comments support (JSONC)
auto error = glz::read<glz::opts{.comments = true}>(obj, json_with_comments);
// Allow unknown keys (don't error on extra fields)
auto error = glz::read<glz::opts{.error_on_unknown_keys = false}>(obj, json);
// Require all keys to be present
auto error = glz::read<glz::opts{.error_on_missing_keys = true}>(obj, json);
// Write with custom indentation
auto error = glz::write<glz::opts{.prettify = true, .indentation_width = 2}>(obj, json);
Performance Tips¶
- Use
std::string
buffers: Glaze is optimized forstd::string
input/output - Reuse buffers: Clear and reuse
std::string
buffers instead of creating new ones
Next Steps¶
- Explore advanced features like JSON pointers, JMESPath queries, and binary formats
- Check out wrappers for fine-grained control
- Learn about custom serialization for complex types