{"id":50729242,"url":"https://github.com/ncode/yaml","last_synced_at":"2026-06-10T07:03:07.092Z","repository":{"id":355894513,"uuid":"1227128385","full_name":"ncode/yaml","owner":"ncode","description":"A native Zig library for reading and writing YAML 1.2.2","archived":false,"fork":false,"pushed_at":"2026-05-29T18:10:58.000Z","size":522,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-29T19:09:54.143Z","etag":null,"topics":["yaml","zig","zig-library","zig-package"],"latest_commit_sha":null,"homepage":"","language":"Zig","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ncode.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-05-02T08:42:07.000Z","updated_at":"2026-05-29T18:10:32.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ncode/yaml","commit_stats":null,"previous_names":["ncode/yaml"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/ncode/yaml","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ncode%2Fyaml","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ncode%2Fyaml/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ncode%2Fyaml/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ncode%2Fyaml/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ncode","download_url":"https://codeload.github.com/ncode/yaml/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ncode%2Fyaml/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34140776,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-10T02:00:07.152Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["yaml","zig","zig-library","zig-package"],"created_at":"2026-06-10T07:03:00.147Z","updated_at":"2026-06-10T07:03:07.086Z","avatar_url":"https://github.com/ncode.png","language":"Zig","funding_links":[],"categories":[],"sub_categories":[],"readme":"# yaml\n\n[![CI](https://github.com/ncode/yaml/actions/workflows/ci.yml/badge.svg)](https://github.com/ncode/yaml/actions/workflows/ci.yml)\n[![codecov](https://codecov.io/gh/ncode/yaml/graph/badge.svg?token=97Q2MPTNBJ)](https://codecov.io/gh/ncode/yaml)\n\nNative Zig YAML 1.2.2 library.\n\n## Why This Library\n\n- Pure Zig.\n- Passes the full official [`yaml/yaml-test-suite`](https://github.com/yaml/yaml-test-suite) at the pinned released tag, with **zero skips** (enforced by the build).\n- Caller-allocated and leak-free. Every owning type has a `deinit`; allocation failure is propagated, not hidden.\n- Memory-safe on malformed input: no panics, no `unreachable`, no UB. Limits return `error.Unsupported` with a diagnostic.\n- Structured diagnostics with byte offset and 1-based line/column for parser, loader, emitter, and typed-conversion failures.\n- Configurable schemas (failsafe, JSON, core), duplicate-key handling, unknown-tag handling, and safety limits across the pipeline.\n\n## Status\n\n- Requires **Zig 0.16.0** or newer (enforced at build time).\n- **YAML 1.2.2 compliant.** The library passes every case in the vendored `yaml-test-suite` at the pinned released tag (currently `data-2022-01-17`, see `vendor/yaml-test-suite.PIN`). The skip list in `tests/conformance/skips.zig` is empty, and the build refuses to accept new skips against the pinned suite.\n- Run `zig build conformance-report` for current parser, loader, expected-error, and emitter coverage counts.\n- Pre-1.0: the public API may still change before a tagged release.\n\n## Install\n\nAdd the library as a dependency:\n\n```sh\nzig fetch --save git+https://github.com/ncode/yaml\n```\n\nWire it into your `build.zig`:\n\n```zig\nconst yaml = b.dependency(\"yaml\", .{\n    .target = target,\n    .optimize = optimize,\n});\n\nexe.root_module.addImport(\"yaml\", yaml.module(\"yaml\"));\n```\n\nThen import it from your Zig source:\n\n```zig\nconst yaml = @import(\"yaml\");\n```\n\n## Quick Start\n\n```zig\nconst std = @import(\"std\");\nconst yaml = @import(\"yaml\");\n\npub fn main() !void {\n    var debug_allocator: std.heap.DebugAllocator(.{}) = .init;\n    defer _ = debug_allocator.deinit();\n    const allocator = debug_allocator.allocator();\n\n    var document = try yaml.load(allocator, \"name: yaml\\nactive: true\\n\");\n    defer document.deinit();\n\n    const output = try yaml.dump(allocator, document.root);\n    defer allocator.free(output);\n\n    std.debug.print(\"{s}\", .{output});\n}\n```\n\n## API Tour\n\nThe public surface lives in `src/lib.zig`. Files below it are internal.\n\n### Events\n\nPull-style with `Parser`, or bulk with `parseEvents`:\n\n```zig\nvar parser = try yaml.Parser.init(allocator, input, .{});\ndefer parser.deinit();\n\nwhile (try parser.next()) |event| {\n    _ = event;\n}\n\nvar events = try yaml.parseEvents(allocator, input);\ndefer events.deinit();\n```\n\nEvents carry style, anchor, and tag metadata for stream, document, sequence, mapping, scalar, and alias nodes.\n\n### Documents\n\n```zig\nvar document = try yaml.load(allocator, input);\ndefer document.deinit();\n\nvar stream = try yaml.loadStream(allocator, input);\ndefer stream.deinit();\n```\n\nLoaded documents are arena-owned node graphs. Node variants include null, boolean, integer, float, scalar, sequence, mapping, and alias.\n\n### Typed Loading\n\nLoad directly into Zig structs, slices, enums, scalars, optionals, and supported tagged unions:\n\n```zig\nconst Config = struct {\n    name: []const u8,\n    ports: []const u16,\n    enabled: bool = true,\n};\n\nvar typed = try yaml.loadTyped(Config, allocator, input);\ndefer typed.deinit();\n```\n\nUse `loadTypedWithOptions` to pass parser and conversion options together:\n\n```zig\nvar parse_diagnostic: yaml.Diagnostic = .{};\nvar typed_diagnostic: yaml.TypedDiagnostic = .{};\n\nvar typed = try yaml.loadTypedWithOptions(Config, allocator, input, .{\n    .load = .{\n        .schema = .core,\n        .duplicate_key_behavior = .reject,\n        .diagnostic = \u0026parse_diagnostic,\n    },\n    .conversion = .{\n        .field_name_transform = .snake_to_kebab,\n        .diagnostic = \u0026typed_diagnostic,\n    },\n});\ndefer typed.deinit();\n```\n\n`load` options control schema, duplicate keys, unknown tags, limits, and parser diagnostics. `conversion` options control typed-conversion behavior and diagnostics. `loadStreamTyped` covers multi-document inputs. `convertNode` converts an already-loaded `Node` graph:\n\n```zig\nvar loaded = try yaml.load(allocator, input);\ndefer loaded.deinit();\n\nvar converted = try yaml.convertNode(Config, allocator, loaded.root, .{});\ndefer converted.deinit();\n```\n\nConversion failures return typed errors such as `error.MissingField`, `error.TypeMismatch`, `error.LengthMismatch`, `error.AmbiguousField`, and `error.UnsupportedTargetType`.\n\n### Emission\n\nAllocating and writer-based variants for both events and value graphs:\n\n```zig\nconst dumped = try yaml.dump(allocator, document.root);\ndefer allocator.free(dumped);\n\nvar buffer: [4096]u8 = undefined;\nvar writer: std.Io.Writer = .fixed(\u0026buffer);\ntry yaml.dumpToWriter(allocator, \u0026writer, document.root);\n\nconst emitted = try yaml.emitEvents(allocator, events.events);\ndefer allocator.free(emitted);\n```\n\n`dumpStream` and `dumpStreamToWriter` serialize a `LoadedStream`; `emitValue` and `emitValueToWriter` are lower-level node-graph variants alongside `dump`. Every emit and dump function has a `*WithOptions` form.\n\nEmitter and dumper options control collection style preservation, `%TAG` directive preservation, redundant document-start omission, and output size limits.\n\n### Options And Diagnostics\n\n```zig\nvar diagnostic: yaml.Diagnostic = .{};\nvar document = try yaml.loadWithOptions(allocator, input, .{\n    .schema = .core,\n    .duplicate_key_behavior = .reject,\n    .unknown_tag_behavior = .preserve,\n    .max_input_bytes = 1024 * 1024,\n    .max_nesting_depth = 128,\n    .diagnostic = \u0026diagnostic,\n});\ndefer document.deinit();\n```\n\nSchemas: `.failsafe`, `.json`, `.core`. Limits cover input size, token count, event count, scalar size, nesting depth, alias count, alias expansion, document count, and output size depending on the API layer. Diagnostic messages are library-owned static strings; do not free them.\n\n### Scanner\n\n```zig\nvar tokens = try yaml.scanner.scan(allocator, input);\ndefer tokens.deinit();\n```\n\nThe token stream owns its token array and any decoded or normalized source buffer.\n\n## Build And Test\n\nPrimary commands:\n\n```sh\nzig build\nzig build test\n```\n\nFocused targets:\n\n```sh\nzig build test-unit\nzig build test-conformance\nzig build test-direct-conformance\nzig build test-structure\nzig build test-schema\nzig build test-stress\nzig build test-allocation\nzig build test-leaks\nzig build test-valgrind\nzig build coverage\nzig build docs\n```\n\nTools:\n\n```sh\nzig build bench                # parser/loader micro-benchmarks\nzig build conformance-report   # current yaml-test-suite coverage counts\nzig build libfyaml-compare     # cross-check suite behavior against libfyaml fy-tool\n```\n\n`libfyaml-compare` requires `python3` and an `fy-tool` executable; supply one with `-Dlibfyaml-fy-tool=/path/to/fy-tool` or have `fy-tool` on `PATH`.\n\n## Conformance\n\nThe conformance harness validates behavior against the vendored pinned `yaml/yaml-test-suite` release under `vendor/yaml-test-suite/`. The exact repository, tag, and commit are recorded in `vendor/yaml-test-suite.PIN`.\n\n`zig build conformance-report` is the source of truth for current parser, loader, expected-error, and emitter coverage. The README intentionally does not copy snapshot counts.\n\nTo run conformance against a different generated suite data directory without replacing the vendored pin:\n\n```sh\nzig build test-conformance -Dyaml-test-suite-dir=/path/to/yaml-test-suite-data\n```\n\n## Documentation\n\n- `docs/api.md`: public API examples, options, diagnostics, and ownership details.\n- `docs/architecture.md`: processing pipeline and dependency direction.\n- `docs/memory.md`: allocator, borrowing, cleanup, error, and limit contracts.\n- `AGENTS.md`: contributor-facing project rules, file-size targets, and TDD workflow.\n\nThe package root is `src/lib.zig`; files below it are internal unless re-exported there.\n\n## Scope And Non-Goals\n\n- Native Zig implementation only.\n- Library API only; no command-line YAML tool.\n- Correctness and memory safety take priority over performance shortcuts.\n- YAML 1.2.2 conformance is tracked through the pinned test suite, not README status snapshots.\n\n## License\n\nMIT. See [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fncode%2Fyaml","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fncode%2Fyaml","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fncode%2Fyaml/lists"}