JSON to serde.zig

zigshape writes idiomatic snake_case Zig structs with a pub const serde block that serde.zig reads directly, so camelCase or kebab-case JSON maps without hand-written renames.

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
const serde = @import("serde");

pub const User = struct {
    id: u8,
    name: []const u8,
    email: []const u8,
    roles: []const []const u8,
    profile: Profile,
};

pub const Profile = struct {
    created_at: []const u8,
    active: bool,

    pub const serde = .{
        .rename_all = .camel_case,
    };
};
loading zig fmt 2 structs · 7 fields 18 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

serde.zig options zigshape emits

  • .rename_all = .camel_case (or kebab, Pascal, SCREAMING_SNAKE) when one convention round-trips every key; per-field .rename otherwise.
  • .alias for sibling keys that share a shape and never appear in the same sample.
  • Tagged unions with .tag and .tag_field when objects carry a discriminator, in any of serde.zig's four tagging styles.
  • .deny_unknown_fields, .flatten and .skip from the Options panel or the CLI config, with defaults added for skipped fields.

Questions

How do I parse JSON with the generated serde.zig struct?
var parsed = try serde.json.fromSliceManaged(User, allocator, input); then defer parsed.deinit();. The result owns one arena, so a single deinit frees everything.
Which serde.zig version does the output target?
serde.zig 1.2.3, which supports Zig 0.15.2, 0.16 and 0.17. The More menu copies the zig fetch command for that release.
What happens with fields whose type can't be inferred?
They become ?serde.Value = null. serde.zig reads null into it but doesn't parse arbitrary input into serde.Value, so zigshape warns and suggests setting a concrete type.