Skip to content

# 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 (use a custom opts struct for indentation settings)
    struct indent2 : glz::opts {
       uint8_t indentation_width = 2;
    };
    auto error = glz::write<indent2{.prettify = true}>(obj, json);

## Performance Tips

1. Use `std::string` buffers: Glaze is optimized for `std::string` input/output
2. 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