Skip to main content

Boost.JSON

Boost.JSON is a header-only, RFC 8259 compliant JSON library added in Boost 1.75. It provides a DOM-style value type (object, array, string, number, bool, null), a SAX-style streaming parser, and a serializer — all designed for performance, with a memory_resource interface for custom allocation and no dependency on exceptions for error reporting.

The problem it solves

C++ has no standard JSON library. PropertyTree can read JSON but loses type information (everything becomes a string) and ignores null. Third-party libraries like nlohmann/json are popular but external dependencies. Boost.JSON gives you production-quality JSON with the same trust chain as the rest of Boost.

Parsing JSON

parse.cpp
#include <boost/json.hpp>
#include <iostream>

namespace json = boost::json;

int main() {
auto jv = json::parse(R"({
"name": "Ada",
"age": 36,
"languages": ["C++", "Haskell"]
})");

auto& obj = jv.as_object();
std::cout << obj["name"].as_string() << "\n"; // Ada
std::cout << obj["age"].as_int64() << "\n"; // 36
std::cout << obj["languages"].as_array()[0] << "\n"; // "C++"
}

Building JSON values

build.cpp
#include <boost/json.hpp>
#include <iostream>

namespace json = boost::json;

int main() {
json::object obj;
obj["host"] = "localhost";
obj["port"] = 8080;
obj["features"] = json::array{"auth", "logging"};

std::cout << json::serialize(obj) << "\n";
// {"host":"localhost","port":8080,"features":["auth","logging"]}
}

Value types

JSON typeC++ accessorUnderlying type
objectas_object()json::object (ordered key-value)
arrayas_array()json::array
stringas_string()json::string (SSO-optimised)
number (int)as_int64() / as_uint64()std::int64_t / std::uint64_t
number (float)as_double()double
booleanas_bool()bool
nullis_null()json::value{}
Kind checking

Use jv.kind() or jv.is_object(), jv.is_string(), etc. before calling as_*() — accessing the wrong kind throws std::invalid_argument.

Custom type conversion with value_from / value_to

Map your own types to and from JSON by specialising tag_invoke:

custom_type.cpp
#include <boost/json.hpp>

struct Point {
double x, y;
};

void tag_invoke(json::value_from_tag, json::value& jv, const Point& p) {
jv = {{"x", p.x}, {"y", p.y}};
}

Point tag_invoke(json::value_to_tag<Point>, const json::value& jv) {
auto& obj = jv.as_object();
return {obj.at("x").as_double(), obj.at("y").as_double()};
}

// Usage:
// json::value jv = json::value_from(Point{1.5, 2.5});
// Point p = json::value_to<Point>(jv);

Streaming parser

For large or incrementally arriving JSON, use json::stream_parser instead of loading everything into memory at once:

stream.cpp
#include <boost/json.hpp>

namespace json = boost::json;

json::value parse_chunks(const std::vector<std::string>& chunks) {
json::stream_parser parser;
for (auto& chunk : chunks)
parser.write(chunk);
parser.finish();
return parser.release();
}

Error handling without exceptions

Every parsing function has an overload that takes a boost::system::error_code:

boost::system::error_code ec;
auto jv = json::parse("{invalid", ec);
if (ec) {
std::cerr << "parse error: " << ec.message() << "\n";
}

Memory resources

Boost.JSON uses boost::json::memory_resource (compatible with std::pmr::memory_resource) for all allocations. You can supply a monotonic buffer, a pool, or any custom allocator:

#include <boost/json.hpp>

unsigned char buf[4096];
json::static_resource mr(buf, sizeof(buf));
auto jv = json::parse(R"({"key": "value"})", &mr);
Performance

Boost.JSON is designed for speed. It uses short-string optimisation, avoids unnecessary copies, and allows zero-allocation parsing via memory resources. Benchmarks regularly show it competitive with RapidJSON.

Boost.JSON versus alternatives

FeatureBoost.JSONnlohmann/jsonPropertyTreeRapidJSON
RFC 8259 compliantYesYesNoYes
Type fidelityFullFullStrings onlyFull
Header-onlyYesYesYesYes
Memory resourceYesNoNoYes
Custom type mappingvalue_from / value_toto_json / from_jsonNoNo
Part of BoostYesNoYesNo

See also