zig-pkl
Zig 0.17 bindings for Pkl. Evaluate modules into Zig types, generate those types from Pkl schemas, and serve modules and resources from your own code.
zig fetch --save git+https://github.com/guanchzhou/zig-pkl#v0.1.1Read config.pkl into a struct
const std = @import("std");
const zig_pkl = @import("zig_pkl");
const Config = struct {
name: []const u8,
port: u16,
tags: []const []const u8,
};
pub fn main(init: std.process.Init) !void {
const allocator = init.gpa;
const io = init.io;
// One manager owns one `pkl server` process.
const manager = try zig_pkl.Manager.init(allocator, io, &.{ "pkl", "server" }, zig_pkl.Logger.noop);
defer manager.deinit();
// An evaluator holds the settings modules are evaluated with.
var rejected: ?[]u8 = null;
defer if (rejected) |text| allocator.free(text);
const evaluator = try manager.createEvaluator(zig_pkl.Options.preconfigured(), &rejected);
defer evaluator.close();
const module_uri = try zig_pkl.uri.fromFile(allocator, io, "config.pkl");
defer allocator.free(module_uri);
var failure: ?[]u8 = null;
defer if (failure) |text| allocator.free(text);
const config = evaluator.evaluateInto(Config, allocator, .uri(module_uri), null, &failure) catch |err| {
if (failure) |text| std.debug.print("{s}\n", .{text});
return err;
};
defer zig_pkl.convert.freeInto(Config, allocator, config);
std.debug.print("{s} listens on {d}\n", .{ config.name, config.port });
}What the package covers
- Typed and dynamic evaluation
- Decode a module or an expression into Zig structs, unions, enums, slices, and maps, or walk the value tree.
- Code generation
zig-pkl-genwrites Zig types from Pkl modules, including recursive classes and unions of unrelated types.- Readers
- Serve modules and resources from Zig callbacks, or run your program as an external reader that Pkl starts.
- Projects
- Load
PklProjectsettings and dependencies, with the same path rules on every supported Pkl release. - Concurrency
- One server process shared by evaluators on any thread, with per-call timeouts and cancellation.
- Restricted evaluation
- Allow lists for modules and resources, an empty environment by default, and HTTP settings.
Measured against pkl-zig
Same run, same Pkl 0.32.2 executable, Apple M5, median of 31 rounds. Method, Linux results, and raw data.
- 2.75×faster pkl-binary decoding, geometric mean of three cases
- 245×fewer allocations decoding a configuration into a value tree
- 7.76 msto start the server, evaluate, and shut down; pkl-zig 8.41 ms
- 25.5 µsper evaluation on a running evaluator; pkl-zig 31.4 µs
Tested Pkl releases
CI runs the conformance suite, the integration tests, and every example against each of these releases on Linux, and Pkl 0.32.2 on linux-x86_64, linux-aarch64, macos-aarch64, windows-x86_64.
- 0.25.3
- 0.26.3
- 0.27.2
- 0.28.2
- 0.29.1
- 0.30.2
- 0.31.1
- 0.32.2
Some settings need a newer release. See version compatibility, or migrating from pkl-zig.