JSON to Zig struct

Paste one JSON document or several samples of the same payload. zigshape writes Zig structs that std.json.parseFromSlice reads without changes, and explains every type it picked.

Target

API responseSmallest int widths from observed range; auto enum suggestion; missing/null become optional.

{
  "id": 42,
  "name": "Alice",
  "email": "alice@example.com",
  "roles": ["admin", "user"],
  "profile": { "createdAt": "2026-01-01T10:00:00Z", "active": true }
}
JSON 7 lines 165 B Drop files here to add samples
User.zig
pub const User = struct {
    id: u8,
    name: []const u8,
    email: []const u8,
    roles: []const []const u8,
    profile: Profile,
};

pub const Profile = struct {
    createdAt: []const u8,
    active: bool,
};
loading zig fmt 2 structs · 7 fields 12 lines

Diagnostics

2 warnings

Field decisions

Why each field got its type. Click a row to see it in the input; edit to override.

struct User $ 5 fields
struct Profile $.profile 2 fields

What zigshape decides for std.json

  • Field names stay exactly as the JSON keys (@"first-name" where needed), because std.json matches names literally and has no rename.
  • A key missing or null in any sample becomes ?T = null.
  • Integers get the smallest width that fits every observed value; the Strict preset switches to u64.
  • Objects with dynamic keys become std.json.ArrayHashMap(V), the map type std.json can parse.
  • Fields with no usable signal fall back to std.json.Value, with a warning that says why.

Questions

How do I parse JSON into the generated struct?
Call std.json.parseFromSlice(User, allocator, input, .{}) and deinit() the result. The More menu copies a ready parseUser helper and a test that parses your sample.
Why are the field names camelCase instead of snake_case?
std.json maps JSON keys to field names one to one, so renaming a field breaks parsing. Switch the target to serde.zig to get snake_case fields with rename_all.
Can I generate one struct from several JSON responses?
Yes. Add every response as a sample. Keys that are missing from some samples become optional, and the field table shows how often each key appeared.
Does my JSON leave the browser?
No. Parsing, inference and zig fmt all run locally; share links keep the data in the URL hash, which browsers never send to a server.