Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ziglang/zig/llms.txt

Use this file to discover all available pages before exploring further.

Overview

The std.json module provides comprehensive JSON parsing and serialization capabilities conforming to RFC 8259. It offers both low-level token-based APIs and high-level functions for parsing JSON into Zig types.

High-Level API

parseFromSlice

pub fn parseFromSlice(
    comptime T: type, 
    allocator: Allocator, 
    source: []const u8, 
    options: ParseOptions
) !Parsed(T)
Parses a JSON document from a string slice into a Zig value.
T
type
The Zig type to parse into.
allocator
Allocator
Allocator for dynamic memory (strings, arrays, etc.).
source
[]const u8
JSON string to parse.
options
ParseOptions
Parsing configuration options.
return
Parsed(T)
A structure containing the parsed value and arena allocator. Call .deinit() to free.
Example:
const std = @import("std");

const User = struct {
    name: []const u8,
    age: u32,
    active: bool = true,
};

var parsed = try std.json.parseFromSlice(
    User,
    allocator,
    \"{\"name\": \"Alice\", \"age\": 30}",
    .{}
);
defer parsed.deinit();

// Access the parsed value
const user = parsed.value;
std.debug.print("Name: {s}, Age: {}\n", .{user.name, user.age});

parseFromSliceLeaky

pub fn parseFromSliceLeaky(
    comptime T: type,
    allocator: Allocator,
    source: []const u8,
    options: ParseOptions
) !T
Parses JSON without managing cleanup. Caller must free all allocations manually.

stringify

pub fn stringify(
    value: anytype,
    options: StringifyOptions,
    writer: *std.Io.Writer
) !void
Serializes a Zig value as JSON. Example:
const User = struct { name: []const u8, age: u32 };
const user = User{ .name = "Bob", .age = 25 };

var list = std.ArrayList(u8).init(allocator);
defer list.deinit();

var writer = std.Io.Writer.Allocating.init(allocator);
defer writer.deinit();

try std.json.stringify(user, .{}, &writer.writer);
const json_string = writer.written();
// json_string is "{\"name\":\"Bob\",\"age\":25}"

Dynamic JSON Values

Value

pub const Value = union(enum) {
    null,
    bool: bool,
    integer: i64,
    float: f64,
    number_string: []const u8,
    string: []const u8,
    array: Array,
    object: ObjectMap,
};
Represents a dynamically-typed JSON value for runtime inspection. Example:
var parsed = try std.json.parseFromSlice(
    std.json.Value,
    allocator,
    \"{\"key\": [1, 2, 3], \"nested\": {\"flag\": true}}",
    .{}
);
defer parsed.deinit();

const obj = parsed.value.object;
const array = obj.get("key").?.array;
const first = array.items[0].integer; // 1

const nested = obj.get("nested").?.object;
const flag = nested.get("flag").?.bool; // true

ObjectMap

pub const ObjectMap = std.StringArrayHashMapUnmanaged(Value);
A map type for JSON objects, preserving insertion order.

Array

pub const Array = std.ArrayListUnmanaged(Value);
A dynamic array for JSON arrays.

Low-Level Scanner API

Scanner

pub const Scanner = struct {
    pub fn initCompleteInput(allocator: Allocator, source: []const u8) Scanner;
    pub fn next(self: *Scanner) !Token;
    pub fn deinit(self: *Scanner) void;
};
Low-level token scanner for streaming JSON parsing. Example:
var scanner = std.json.Scanner.initCompleteInput(
    allocator,
    \"{\"foo\": 123}\n"
);
defer scanner.deinit();

const tok1 = try scanner.next(); // .object_begin
const tok2 = try scanner.next(); // .string with value "foo"
const tok3 = try scanner.next(); // .number with value "123"
const tok4 = try scanner.next(); // .object_end
const tok5 = try scanner.next(); // .end_of_document

Token

pub const Token = union(enum) {
    object_begin,
    object_end,
    array_begin,
    array_end,
    string: []const u8,
    number: []const u8,
    true,
    false,
    null,
    end_of_document,
};
Represents a single JSON token.

Stringify API

Stringify

pub const Stringify = struct {
    writer: *std.Io.Writer,
    options: Options,
    
    pub const Options = struct {
        whitespace: Whitespace = .minified,
        
        pub const Whitespace = union(enum) {
            minified,
            indent_1,
            indent_2,
            indent_3,
            indent_4,
            indent_tab,
        };
    };
};
Low-level JSON writer for manual control. Methods:
pub fn beginObject(self: *Stringify) !void;
pub fn endObject(self: *Stringify) !void;
pub fn beginArray(self: *Stringify) !void;
pub fn endArray(self: *Stringify) !void;
pub fn objectField(self: *Stringify, name: []const u8) !void;
pub fn write(self: *Stringify, value: anytype) !void;
Example:
var out = std.Io.Writer.Allocating.init(allocator);
defer out.deinit();

var writer = std.json.Stringify{
    .writer = &out.writer,
    .options = .{ .whitespace = .indent_2 },
};

try writer.beginObject();
try writer.objectField("name");
try writer.write("Alice");
try writer.objectField("items");
try writer.beginArray();
try writer.write(1);
try writer.write(2);
try writer.endArray();
try writer.endObject();

const json = out.written();
// {
//   "name": "Alice",
//   "items": [
//     1,
//     2
//   ]
// }

Parse Options

ParseOptions

pub const ParseOptions = struct {
    allocate: AllocWhen = .alloc_always,
    duplicate_field_behavior: DuplicateFieldBehavior = .use_first,
    ignore_unknown_fields: bool = false,
    max_value_len: ?usize = default_max_value_len,
    
    pub const AllocWhen = enum {
        alloc_always,
        alloc_if_needed,
    };
    
    pub const DuplicateFieldBehavior = enum {
        use_first,
        @"error",
        use_last,
    };
};
allocate
AllocWhen
Controls when to allocate for strings. .alloc_always copies all strings; .alloc_if_needed may reference source.
duplicate_field_behavior
DuplicateFieldBehavior
How to handle duplicate object keys.
ignore_unknown_fields
bool
If true, ignore JSON fields that don’t match struct fields.
max_value_len
?usize
Maximum length for string/number tokens.

Validation

validate

pub fn validate(source: []const u8) !void
Validates that a string contains well-formed JSON. Example:
try std.json.validate("{\"valid\": true}");
// Returns successfully

std.json.validate("{invalid}") catch |err| {
    // err is std.json.Error.SyntaxError
};

Formatting Helper

fmt

pub fn fmt(value: anytype, options: Stringify.Options) Formatter(@TypeOf(value))
Returns a formatter that serializes a value using std.fmt integration. Example:
const value = .{ .x = 10, .y = 20 };
std.debug.print("JSON: {f}\n", .{std.json.fmt(value, .{})});
// Prints: JSON: {"x":10,"y":20}

Error Types

Error

pub const Error = error{
    UnexpectedEndOfInput,
    InvalidNumber,
    InvalidEscape,
    InvalidUnicodeEscape,
    InvalidTopLevel,
    SyntaxError,
    BufferUnderrun,
};

ParseError

pub const ParseError = error{
    UnexpectedToken,
    InvalidNumber,
    Overflow,
    InvalidEnumTag,
    DuplicateField,
    UnknownField,
    MissingField,
    LengthMismatch,
} || Error;

Build docs developers (and LLMs) love