Skip to content

API Overview ​

Complete API reference for zon.zig — a document-based ZON library.

Document vs Type-Based API

zon.zig provides a document-based (DOM-like) API where you work with a Document object containing a Value tree. This differs from Zig's std.zon which deserializes directly into typed Zig structures.

Use zon.zig when you need to edit, search, or manipulate ZON files dynamically.

Module Functions ​

Top-level functions exposed by the zon module.

Document Creation ​

zig
const zon = @import("zon");

// Create empty document (aliases: init, new)
var doc = zon.create(allocator);

// Open file (aliases: load, fromFile, parseFile)
var doc = try zon.open(allocator, "config.zon");

// Parse string (aliases: fromSource, parseString)
var doc = try zon.parse(allocator, source);

// Load or Create
var doc = try zon.loadOrCreate(allocator, "settings.zon", ".{}");

// From JSON (aliases: parseJson)
var doc = try zon.fromJson(allocator, json_string);

// From struct
var doc = try zon.fromStruct(allocator, my_struct);

File Utilities ​

zig
// Check if file exists (alias: hasFile)
if (zon.fileExists("config.zon")) { ... }

// Read file into allocator-owned buffer (caller frees)
const contents = try zon.readFile(allocator, "config.zon");
allocator.free(contents);

// Copy file (overwrite = true to replace destination)
try zon.copyFile("source.zon", "dest.zon", true);

// Move (rename) file (alias: renameFile, removeFile)
try zon.moveFile("old.zon", "new.zon", true);

// Delete file (alias: removeFile)
try zon.deleteFile("temp.zon");

// Key Operations (alias: movePathInFile, copyPathInFile)
try zon.movePathInFile(allocator, "config.zon", "old.key", "new.key");

// Write atomically (writes to temp and renames)
try zon.writeFileAtomic(allocator, "out.zon", sourceData);

Validation & Encoding ​

zig
// Validate ZON syntax
if (zon.validate(allocator, source)) { ... }
if (zon.validateFile(allocator, "config.zon")) { ... }

// Re-format ZON source
const formatted = try zon.format(allocator, source);
try zon.formatFile(allocator, "config.zon");

// Validate semantic version
if (zon.validateSemVer("1.2.3")) { ... }

// Base64 encode/decode
const enc = try zon.base64Encode(allocator, "hello");
const dec = try zon.base64Decode(allocator, enc);

// Stringify raw Value tree
const output = try zon.stringify(allocator, &value, .{});
const json = try zon.stringifyJson(allocator, &value);

Update Checking ​

zig
// Disable update notifications
zon.disableUpdateCheck();

// Enable update notifications
zon.enableUpdateCheck();

// Check if enabled
if (zon.isUpdateCheckEnabled()) { ... }

// Manual check
zon.checkForUpdates(allocator);

Version ​

zig
// Get version string
std.debug.print("Version: {s}\n", .{zon.version});

Document Methods ​

Getters ​

MethodReturnDescription
getString(path)?[]const u8Get string value
getStr(path)?[]const u8Alias for getString
getIdentifier(path)?[]const u8Get identifier value
getBool(path)?boolGet boolean value
getInt(path)?i64Get integer value
getNum(path)?i64Alias for getInt
getInteger(path)?i64Alias for getInt
getInt128(path)?i128Get full-precision integer
getUint(path)?u64Get unsigned integer (u64)
getFloat(path)?f64Get float value
getDecimal(path)?f64Alias for getFloat
getNumber(path)?f64Alias for getFloat
getValue(path)?*const ValueGet raw Value

Setters ​

MethodDescription
setString(path, value)Set string value
setStr(path, value)Alias for setString
putStr(path, value)Alias for setString
setIdentifier(path, value)Set identifier (.value)
setBool(path, value)Set boolean value
setInt(path, value)Set integer value
putInt(path, value)Alias for setInt
setNum(path, value)Alias for setInt
setFloat(path, value)Set float value
setNumber(path, value)Alias for setFloat
setNull(path)Set to null
putNull(path)Alias for setNull
clearPath(path)Alias for setNull
setObject(path)Create empty object
setArray(path)Create empty array
setValue(path, value)Set raw Value
put(path, value)Alias for setValue
setFromStruct(path, value)Set path from struct
getOrPutString(path, def)Get or put string
getOrPutInt(path, def)Get or put integer
getOrPutBool(path, def)Get or put boolean

Checkers ​

MethodReturnDescription
exists(path)boolCheck if path exists
has(path)boolAlias for exists
contains(path)boolAlias for exists
isValue(path)boolAlias for exists
isKey(path)boolAlias for exists
isNull(path)boolCheck if value is null
isString(path)boolCheck if value is a string
isBool(path)boolCheck if value is a boolean
isInt(path)boolCheck if value is an integer
isFloat(path)boolCheck if value is a float
isNumber(path)boolCheck if value is int or float
isObject(path)boolCheck if value is an object
isArray(path)boolCheck if value is an array
isIdentifier(path)boolCheck if value is identifier
isUpperCase(path)boolCheck if string is all uppercase
isLowerCase(path)boolCheck if string is all lowercase
isEmpty()boolCheck if document empty
getType(path)?[]const u8Get base type name
getTypeName(path)?[]const u8Get precise type name
isNan(path)boolCheck if value is NaN
isInf(path)boolCheck if value is Inf
toBool(path)boolCoerce value to boolean
toInt(path, T)TCoerce to integer type T
toUint(path, T)TCoerce to unsigned type T
toFloat(path, T)TCoerce to float type T
toString(path, T)!TConvert to Zig struct

Case Utilities ​

MethodReturnDescription
toUpper(path)!voidConvert string to uppercase in-place
toLower(path)!voidConvert string to lowercase in-place
isUpperCase(path)boolCheck if string is all uppercase
isLowerCase(path)boolCheck if string is all lowercase

Modification ​

MethodReturnDescription
delete(path)boolDelete key
remove(path)boolAlias for delete
rename(old, new)!boolRename key/path
move(old, new)!boolAlias for rename
copy(src, dst)!boolDuplicate path
clear()voidClear all data
count()usizeNumber of root keys
size()usizeAlias for count
len()usizeAlias for count
keys()![][]const u8Get all root keys
reload()!voidReload from disk
hasChangedOnDisk()boolCheck if file modified
deleteFileOnDisk()!voidDelete associated file
renameFileOnDisk(new)!voidRename associated file

Array Operations ​

MethodReturnDescription
arrayLen(path)?usizeGet array length
getArrayElement(path, index)?*const ValueGet element
getArrayString(path, index)?[]const u8Get string element
getArrayInt(path, index)?i64Get integer element
getArrayBool(path, index)?boolGet boolean element
appendToArray(path, string)!voidAppend string
appendIntToArray(path, int)!voidAppend integer
appendFloatToArray(path, float)!voidAppend float
appendBoolToArray(path, bool)!voidAppend boolean
insertStringIntoArray(path, idx, val)!voidInsert string at index
insertIntIntoArray(path, idx, val)!voidInsert integer at index
removeFromArray(path, index)boolRemove item at index
popFromArray(path)?ValuePop last element
shiftArray(path)?ValueRemove first element
unshiftArray(path, val)!voidInsert at start
indexOf(path, value)?usizeFind string index
countAt(path)usizeCount items at path
sortArray(path)!voidSort array ascending
reverseArray(path)!voidReverse array in-place
truncate(path, new_len)!voidTruncate to new length
dropFirst(path, n)!voidRemove first n elements
dropLast(path, n)!voidRemove last n elements
compact(path)!voidRemove null values
unique(path)!voidRemove duplicates
first(path)?*const ValueGet first element
last(path)?*const ValueGet last element
every(path, predicate)boolCheck all match predicate
some(path, predicate)boolCheck any matches predicate

Find & Replace ​

MethodReturnDescription
findString(needle)![][]const u8Find paths containing value
findExact(needle)![][]const u8Find paths with exact value
findWhere(predicate)![][]const u8Find paths matching predicate
find(key)?*ValueRecursive key search
findAll(key)![][]const u8Deep key search (paths)
replaceAll(find, replace)!usizeReplace all occurrences
replaceFirst(find, replace)!boolReplace first occurrence
replaceLast(find, replace)!boolReplace last occurrence

Merge & Clone ​

MethodReturnDescription
merge(other)!voidShallow merge document
mergeRecursive(other)!voidRecursive (deep) merge
clone()!DocumentCreate deep copy
eql(other)boolDeep equality check
diff(other)![][]const u8Get differing keys
flatten()!DocumentConvert to flat key-value map

Output ​

MethodReturnDescription
toString()![]u84-space indent
toCompactString()![]u8No indentation
toPrettyString(indent)![]u8Custom indentation
toJsonString()![]u8Serialize to JSON
save()!voidSave to original path
saveAs(path)!voidSave to new path
saveAsAtomic(path)!voidAtomically write to file
saveWithBackup(ext)!voidSave with backup of previous file
saveIfChanged()!boolSave only if contents differ

Traversal & Transformation ​

MethodReturnDescription
paths()![][]const u8Recursively list all paths in the document
walk(context, visitor)voidDepth-first traversal of all values
mapValues(context, mapper)!voidTransform all values recursively
forEach(context, callback)voidIterate over all values with a callback
pick(paths)!DocumentNew document with only specified paths
omit(paths)!DocumentNew document excluding specified paths
filter(alloc, ctx, pred)!DocumentNew document with matching paths
sortKeys()voidRecursively sort all object keys ascending
sortKeysDesc()voidRecursively sort all object keys descending

Integrity & Size ​

MethodReturnDescription
hash()u64Stable 64-bit content hash
checksum(algo, &out)voidGenerate crypto digest
byteSize()!usizeSize in bytes when formatted
compactSize()!usizeSize in bytes when compact

Object & Array Access ​

MethodReturnDescription
getObject(path)?*Value.ObjectGet mutable object
getArray(path)?*Value.ArrayGet mutable array

Cleanup ​

zig
doc.deinit(); // Always call when done
doc.close();  // Alias for deinit

Value Types ​

Value Union ​

zig
pub const Value = union(enum) {
    null_val,
    bool_val: bool,
    number: Number,
    string: []const u8,
    identifier: []const u8,
    object: Object,
    array: Array,
};

Value Methods — Type Checking ​

MethodReturnDescription
isNull()boolCheck if null
isString()boolCheck if string
isBool()boolCheck if boolean
isInt()boolCheck if integer
isFloat()boolCheck if float
isNumber()boolCheck if int or float
isObject()boolCheck if object
isArray()boolCheck if array
isIdentifier()boolCheck if identifier
isNan()boolCheck if NaN
isPositiveInf()boolCheck if positive infinity
isNegativeInf()boolCheck if negative infinity
isSpecialFloat()boolCheck if NaN or Infinity
typeName()[]const u8Get precise type name
toBool()boolCoerce value to boolean
hash()u64Stable content hash
checksum(A, &out)voidCrypto checksum
eql(Value)boolDeep equality check

Value Methods — Type Conversion ​

MethodReturnDescription
asString()?[]const u8Get as string (works for identifiers)
asIdentifier()?[]const u8Get as identifier only
asBool()?boolGet as boolean
asInt()?i64Get as i64 (null if overflow)
asInt128()?i128Get as i128 (all ZON integers)
asUint()?u64Get as u64 (useful for fingerprints)
asFloat()?f64Get as float (converts int to float)
asObject()?*ObjectGet as object
asArray()?*ArrayGet as array
to(alloc, T)!TConvert to Zig type
from(alloc, v)!ValueCreate Value from Zig
clone(allocator)!ValueDeep copy
toDebugString(alloc)![]u8Get debug representation
deinit(allocator)voidFree memory

Error Types ​

ParseError ​

zig
pub const ParseError = error{
    UnexpectedToken,
    InvalidNumber,
    InvalidString,
    UnterminatedString,
    OutOfMemory,
};

Type Name Strings ​

The getType() method returns these strings:

ValueType String
null"null"
true/false"bool"
Integer"int"
Float"float"
"string""string"
.identifier"identifier"
.{ ... } object"object"
.{ ... } array"array"

Quick Reference ​

zig
const std = @import("std");
const zon = @import("zon");

pub fn main() !void {
    var gpa = std.heap.DebugAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    zon.disableUpdateCheck();

    // Create
    var doc = zon.create(allocator);
    defer doc.deinit();

    // Set various types
    try doc.setIdentifier("name", "myapp");
    try doc.setString("version", "1.0.0");
    try doc.setInt("port", 8080);
    try doc.setBool("debug", true);
    try doc.setFloat("rate", 0.05);
    try doc.setNull("password");

    // Nested paths
    try doc.setString("db.host", "localhost");
    try doc.setInt("db.port", 5432);

    // Arrays
    try doc.setArray("paths");
    try doc.appendToArray("paths", "src");
    try doc.appendToArray("paths", "lib");

    // Get
    const name = doc.getIdentifier("name").?;
    const port = doc.getInt("port").?;
    const len = doc.arrayLen("paths").?;

    // Type-check nested values
    if (doc.isString("db.host") and doc.isInt("db.port")) {
        std.debug.print("Database configured\n", .{});
    }

    // Validate and check nested identifiers
    if (doc.isIdentifier("name")) {
        std.debug.print("Package: .{s}\n", .{doc.getIdentifier("name").?});
    }

    // Case utilities
    try doc.toUpper("version"); // "1.0.0" -> "1.0.0" (no-op)
    if (doc.isLowerCase("name")) {
        try doc.toUpper("name"); // "myapp" -> "MYAPP"
    }

    // Modify
    _ = doc.delete("debug");

    // Clone
    var backup = try doc.clone();
    defer backup.deinit();

    // Validate semver and encode
    if (zon.validateSemVer("1.2.3")) {
        const enc = try zon.base64Encode(allocator, "hello");
        defer allocator.free(enc);
    }

    // Output
    const output = try doc.toString();
    defer allocator.free(output);

    // Save
    try doc.saveAs("config.zon");
}

Released under the MIT License.