{"id":13460009,"url":"https://github.com/goccy/go-yaml","last_synced_at":"2025-05-14T11:02:57.635Z","repository":{"id":35434699,"uuid":"213852395","full_name":"goccy/go-yaml","owner":"goccy","description":"YAML support for the Go language","archived":false,"fork":false,"pushed_at":"2025-05-07T07:26:31.000Z","size":1575,"stargazers_count":1551,"open_issues_count":86,"forks_count":172,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-05-07T10:52:36.512Z","etag":null,"topics":["go","golang","golang-library","yaml","yaml-parser"],"latest_commit_sha":null,"homepage":"https://goccy.github.io/go-yaml","language":"Go","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/goccy.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","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},"funding":{"github":["goccy"]}},"created_at":"2019-10-09T07:38:12.000Z","updated_at":"2025-05-07T03:36:03.000Z","dependencies_parsed_at":"2024-01-13T18:11:27.994Z","dependency_job_id":"1638c01d-17bf-45b2-a455-44eca2a12367","html_url":"https://github.com/goccy/go-yaml","commit_stats":{"total_commits":560,"total_committers":60,"mean_commits":9.333333333333334,"dds":"0.29107142857142854","last_synced_commit":"0c41d8e83cdffa1c336825dca302fe204b52ca6b"},"previous_names":[],"tags_count":131,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goccy%2Fgo-yaml","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goccy%2Fgo-yaml/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goccy%2Fgo-yaml/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goccy%2Fgo-yaml/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/goccy","download_url":"https://codeload.github.com/goccy/go-yaml/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254129467,"owners_count":22019628,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["go","golang","golang-library","yaml","yaml-parser"],"created_at":"2024-07-31T10:00:33.850Z","updated_at":"2025-05-14T11:02:57.553Z","avatar_url":"https://github.com/goccy.png","language":"Go","funding_links":["https://github.com/sponsors/goccy"],"categories":["语言资源库","Go","Repositories"],"sub_categories":["go"],"readme":"# YAML support for the Go language\n\n[![PkgGoDev](https://pkg.go.dev/badge/github.com/goccy/go-yaml)](https://pkg.go.dev/github.com/goccy/go-yaml)\n![Go](https://github.com/goccy/go-yaml/workflows/Go/badge.svg)\n[![codecov](https://codecov.io/gh/goccy/go-yaml/branch/master/graph/badge.svg)](https://codecov.io/gh/goccy/go-yaml)\n[![Go Report Card](https://goreportcard.com/badge/github.com/goccy/go-yaml)](https://goreportcard.com/report/github.com/goccy/go-yaml)\n\n\u003cimg width=\"300px\" src=\"https://user-images.githubusercontent.com/209884/67159116-64d94b80-f37b-11e9-9b28-f8379636a43c.png\"\u003e\u003c/img\u003e\n\n## This library has **NO** relation to the go-yaml/yaml library\n\n\u003e [!IMPORTANT]\n\u003e This library is developed from scratch to replace [`go-yaml/yaml`](https://github.com/go-yaml/yaml).\n\u003e If you're looking for a better YAML library, this one should be helpful.\n\n# Why a new library?\n\nAs of this writing, there already exists a de facto standard library for YAML processing for Go: [https://github.com/go-yaml/yaml](https://github.com/go-yaml/yaml). However, we believe that a new YAML library is necessary for the following reasons:\n\n- Not actively maintained\n- `go-yaml/yaml` has ported the libyaml written in C to Go, so the source code is not written in Go style\n- There is a lot of content that cannot be parsed\n- YAML is often used for configuration, and it is common to include validation along with it. However, the errors in `go-yaml/yaml` are not intuitive, and it is difficult to provide meaningful validation errors\n- When creating tools that use YAML, there are cases where reversible transformation of YAML is required. However, to perform reversible transformations of content that includes Comments or Anchors/Aliases, manipulating the AST is the only option\n- Non-intuitive [Marshaler](https://pkg.go.dev/gopkg.in/yaml.v3#Marshaler) / [Unmarshaler](https://pkg.go.dev/gopkg.in/yaml.v3#Unmarshaler)\n\nBy the way, libraries such as [ghodss/yaml](https://github.com/ghodss/yaml) and [sigs.k8s.io/yaml](https://github.com/kubernetes-sigs/yaml) also depend on go-yaml/yaml, so if you are using these libraries, the same issues apply: they cannot parse things that go-yaml/yaml cannot parse, and they inherit many of the problems that go-yaml/yaml has.\n\n# Features\n\n- No dependencies\n- A better parser than `go-yaml/yaml`. \n  - [Support recursive processing](https://github.com/apple/device-management/blob/release/docs/schema.yaml)\n  - Higher coverage in the [YAML Test Suite](https://github.com/yaml/yaml-test-suite?tab=readme-ov-file)\n    - YAML Test Suite consists of 402 cases in total, of which `gopkg.in/yaml.v3` passes `295`. In addition to passing all those test cases, `goccy/go-yaml` successfully passes nearly 60 additional test cases ( 2024/12/15 )\n    - The test code is [here](https://github.com/goccy/go-yaml/blob/master/yaml_test_suite_test.go#L77)\n- Ease and sustainability of maintenance\n  - The main maintainer is [@goccy](https://github.com/goccy), but we are also building a system to develop as a team with trusted developers\n  - Since it is written from scratch, the code is easy to read for Gophers\n- An API structure that allows the use of not only `Encoder`/`Decoder` but also `Tokenizer` and `Parser` functionalities.\n  - [lexer.Tokenize](https://pkg.go.dev/github.com/goccy/go-yaml@v1.15.4/lexer#Tokenize)\n  - [parser.Parse](https://pkg.go.dev/github.com/goccy/go-yaml@v1.15.4/parser#Parse)\n- Filtering, replacing, and merging YAML content using YAML Path\n- Reversible transformation without using the AST for YAML that includes Anchors, Aliases, and Comments\n- Customize the Marshal/Unmarshal behavior for primitive types and third-party library types ([RegisterCustomMarshaler](https://pkg.go.dev/github.com/goccy/go-yaml#RegisterCustomMarshaler), [RegisterCustomUnmarshaler](https://pkg.go.dev/github.com/goccy/go-yaml#RegisterCustomUnmarshaler))\n- Respects `encoding/json` behavior\n  - Accept the `json` tag. Note that not all options from the `json` tag will have significance when parsing YAML documents. If both tags exist, `yaml` tag will take precedence.\n  - [json.Marshaler](https://pkg.go.dev/encoding/json#Marshaler) style [marshaler](https://pkg.go.dev/github.com/goccy/go-yaml#BytesMarshaler)\n  - [json.Unmarshaler](https://pkg.go.dev/encoding/json#Unmarshaler) style [unmarshaler](https://pkg.go.dev/github.com/goccy/go-yaml#BytesUnmarshaler)\n  - Options for using `MarshalJSON` and `UnmarshalJSON` ([UseJSONMarshaler](https://pkg.go.dev/github.com/goccy/go-yaml#UseJSONMarshaler), [UseJSONUnmarshaler](https://pkg.go.dev/github.com/goccy/go-yaml#UseJSONUnmarshaler))\n- Pretty format for error notifications\n- Smart validation processing combined with [go-playground/validator](https://github.com/go-playground/validator)\n  - [example test code is here](https://github.com/goccy/go-yaml/blob/45889c98b0a0967240eb595a1bd6896e2f575106/testdata/validate_test.go#L12)\n- Allow referencing elements declared in another file via anchors\n\n# Users\n\nThe repositories that use goccy/go-yaml are listed here.\n\n- https://github.com/goccy/go-yaml/wiki/Users\n\nThe source data is [here](https://github.com/goccy/go-yaml/network/dependents). \nIt is already being used in many repositories. Now it's your turn 😄\n\n# Playground\n\nThe Playground visualizes how go-yaml processes YAML text. Use it to assist with your debugging or issue reporting.\n\nhttps://goccy.github.io/go-yaml\n\n# Installation\n\n```sh\ngo get github.com/goccy/go-yaml\n```\n\n# Synopsis\n\n## 1. Simple Encode/Decode\n\nHas an interface like `go-yaml/yaml` using `reflect`\n\n```go\nvar v struct {\n\tA int\n\tB string\n}\nv.A = 1\nv.B = \"hello\"\nbytes, err := yaml.Marshal(v)\nif err != nil {\n\t//...\n}\nfmt.Println(string(bytes)) // \"a: 1\\nb: hello\\n\"\n```\n\n```go\n\tyml := `\n%YAML 1.2\n---\na: 1\nb: c\n`\nvar v struct {\n\tA int\n\tB string\n}\nif err := yaml.Unmarshal([]byte(yml), \u0026v); err != nil {\n\t//...\n}\n```\n\nTo control marshal/unmarshal behavior, you can use the `yaml` tag.\n\n```go\n\tyml := `---\nfoo: 1\nbar: c\n`\nvar v struct {\n\tA int    `yaml:\"foo\"`\n\tB string `yaml:\"bar\"`\n}\nif err := yaml.Unmarshal([]byte(yml), \u0026v); err != nil {\n\t//...\n}\n```\n\nFor convenience, we also accept the `json` tag. Note that not all options from\nthe `json` tag will have significance when parsing YAML documents. If both\ntags exist, `yaml` tag will take precedence.\n\n```go\n\tyml := `---\nfoo: 1\nbar: c\n`\nvar v struct {\n\tA int    `json:\"foo\"`\n\tB string `json:\"bar\"`\n}\nif err := yaml.Unmarshal([]byte(yml), \u0026v); err != nil {\n\t//...\n}\n```\n\nFor custom marshal/unmarshaling, implement either `Bytes` or `Interface` variant of marshaler/unmarshaler. The difference is that while `BytesMarshaler`/`BytesUnmarshaler` behaves like [`encoding/json`](https://pkg.go.dev/encoding/json) and `InterfaceMarshaler`/`InterfaceUnmarshaler` behaves like [`gopkg.in/yaml.v2`](https://pkg.go.dev/gopkg.in/yaml.v2).\n\nSemantically both are the same, but they differ in performance. Because indentation matters in YAML, you cannot simply accept a valid YAML fragment from a Marshaler, and expect it to work when it is attached to the parent container's serialized form. Therefore when we receive use the `BytesMarshaler`, which returns `[]byte`, we must decode it once to figure out how to make it work in the given context. If you use the `InterfaceMarshaler`, we can skip the decoding.\n\nIf you are repeatedly marshaling complex objects, the latter is always better\nperformance wise. But if you are, for example, just providing a choice between\na config file format that is read only once, the former is probably easier to\ncode.\n\n## 2. Reference elements declared in another file\n\n`testdata` directory contains `anchor.yml` file:\n\n```shell\n├── testdata\n   └── anchor.yml\n```\n\nAnd `anchor.yml` is defined as follows:\n\n```yaml\na: \u0026a\n  b: 1\n  c: hello\n```\n\nThen, if `yaml.ReferenceDirs(\"testdata\")` option is passed to `yaml.Decoder`, \n `Decoder` tries to find the anchor definition from YAML files the under `testdata` directory.\n \n```go\nbuf := bytes.NewBufferString(\"a: *a\\n\")\ndec := yaml.NewDecoder(buf, yaml.ReferenceDirs(\"testdata\"))\nvar v struct {\n\tA struct {\n\t\tB int\n\t\tC string\n\t}\n}\nif err := dec.Decode(\u0026v); err != nil {\n\t//...\n}\nfmt.Printf(\"%+v\\n\", v) // {A:{B:1 C:hello}}\n```\n\n## 3. Encode with `Anchor` and `Alias`\n\n### 3.1. Explicitly declared `Anchor` name and `Alias` name\n\nIf you want to use `anchor`, you can define it as a struct tag.\nIf the value specified for an anchor is a pointer type and the same address as the pointer is found, the value is automatically set to alias.\nIf an explicit alias name is specified, an error is raised if its value is different from the value specified in the anchor.\n\n```go\ntype T struct {\n  A int\n  B string\n}\nvar v struct {\n  C *T `yaml:\"c,anchor=x\"`\n  D *T `yaml:\"d,alias=x\"`\n}\nv.C = \u0026T{A: 1, B: \"hello\"}\nv.D = v.C\nbytes, err := yaml.Marshal(v)\nif err != nil {\n  panic(err)\n}\nfmt.Println(string(bytes))\n/*\nc: \u0026x\n  a: 1\n  b: hello\nd: *x\n*/\n```\n\n### 3.2. Implicitly declared `Anchor` and `Alias` names\n\nIf you do not explicitly declare the anchor name, the default behavior is to\nuse the equivalent of `strings.ToLower($FieldName)` as the name of the anchor.\nIf the value specified for an anchor is a pointer type and the same address as the pointer is found, the value is automatically set to alias.\n\n```go\ntype T struct {\n\tI int\n\tS string\n}\nvar v struct {\n\tA *T `yaml:\"a,anchor\"`\n\tB *T `yaml:\"b,anchor\"`\n\tC *T `yaml:\"c\"`\n\tD *T `yaml:\"d\"`\n}\nv.A = \u0026T{I: 1, S: \"hello\"}\nv.B = \u0026T{I: 2, S: \"world\"}\nv.C = v.A // C has same pointer address to A\nv.D = v.B // D has same pointer address to B\nbytes, err := yaml.Marshal(v)\nif err != nil {\n\t//...\n}\nfmt.Println(string(bytes)) \n/*\na: \u0026a\n  i: 1\n  s: hello\nb: \u0026b\n  i: 2\n  s: world\nc: *a\nd: *b\n*/\n```\n\n### 3.3 MergeKey and Alias\n\nMerge key and alias ( `\u003c\u003c: *alias` ) can be used by embedding a structure with the `inline,alias` tag.\n\n```go\ntype Person struct {\n\t*Person `yaml:\",omitempty,inline,alias\"` // embed Person type for default value\n\tName    string `yaml:\",omitempty\"`\n\tAge     int    `yaml:\",omitempty\"`\n}\ndefaultPerson := \u0026Person{\n\tName: \"John Smith\",\n\tAge:  20,\n}\npeople := []*Person{\n\t{\n\t\tPerson: defaultPerson, // assign default value\n\t\tName:   \"Ken\",         // override Name property\n\t\tAge:    10,            // override Age property\n\t},\n\t{\n\t\tPerson: defaultPerson, // assign default value only\n\t},\n}\nvar doc struct {\n\tDefault *Person   `yaml:\"default,anchor\"`\n\tPeople  []*Person `yaml:\"people\"`\n}\ndoc.Default = defaultPerson\ndoc.People = people\nbytes, err := yaml.Marshal(doc)\nif err != nil {\n\t//...\n}\nfmt.Println(string(bytes))\n/*\ndefault: \u0026default\n  name: John Smith\n  age: 20\npeople:\n- \u003c\u003c: *default\n  name: Ken\n  age: 10\n- \u003c\u003c: *default\n*/\n```\n\n## 4. Pretty Formatted Errors\n\nError values produced during parsing have two extra features over regular\nerror values.\n\nFirst, by default, they contain extra information on the location of the error\nfrom the source YAML document, to make it easier to find the error location.\n\nSecond, the error messages can optionally be colorized.\n\nIf you would like to control exactly how the output looks like, consider\nusing  `yaml.FormatError`, which accepts two boolean values to\ncontrol turning these features on or off.\n\n\u003cimg src=\"https://user-images.githubusercontent.com/209884/67358124-587f0980-f59a-11e9-96fc-7205aab77695.png\"\u003e\u003c/img\u003e\n\n## 5. Use YAMLPath\n\n```go\nyml := `\nstore:\n  book:\n    - author: john\n      price: 10\n    - author: ken\n      price: 12\n  bicycle:\n    color: red\n    price: 19.95\n`\npath, err := yaml.PathString(\"$.store.book[*].author\")\nif err != nil {\n  //...\n}\nvar authors []string\nif err := path.Read(strings.NewReader(yml), \u0026authors); err != nil {\n  //...\n}\nfmt.Println(authors)\n// [john ken]\n```\n\n### 5.1 Print customized error with YAML source code\n\n```go\npackage main\n\nimport (\n  \"fmt\"\n\n  \"github.com/goccy/go-yaml\"\n)\n\nfunc main() {\n  yml := `\na: 1\nb: \"hello\"\n`\n  var v struct {\n    A int\n    B string\n  }\n  if err := yaml.Unmarshal([]byte(yml), \u0026v); err != nil {\n    panic(err)\n  }\n  if v.A != 2 {\n    // output error with YAML source\n    path, err := yaml.PathString(\"$.a\")\n    if err != nil {\n      panic(err)\n    }\n    source, err := path.AnnotateSource([]byte(yml), true)\n    if err != nil {\n      panic(err)\n    }\n    fmt.Printf(\"a value expected 2 but actual %d:\\n%s\\n\", v.A, string(source))\n  }\n}\n```\n\noutput result is the following:\n\n\u003cimg src=\"https://user-images.githubusercontent.com/209884/84148813-7aca8680-aa9a-11ea-8fc9-37dece2ebdac.png\"\u003e\u003c/img\u003e\n\n\n# Tools\n\n## ycat\n\nprint yaml file with color\n\n\u003cimg width=\"713\" alt=\"ycat\" src=\"https://user-images.githubusercontent.com/209884/66986084-19b00600-f0f9-11e9-9f0e-1f91eb072fe0.png\"\u003e\n\n### Installation\n\n```sh\ngit clone https://github.com/goccy/go-yaml.git\ncd go-yaml/cmd/ycat \u0026\u0026 go install .\n```\n\n\n# For Developers\n\n\u003e [!NOTE]\n\u003e In this project, we manage such test code under the `testdata` directory to avoid adding dependencies  on libraries that are only needed for testing to the top `go.mod` file. Therefore, if you want to add test cases that use 3rd party libraries, please add the test code to the `testdata` directory.\n\n# Looking for Sponsors\n\nI'm looking for sponsors this library. This library is being developed as a personal project in my spare time. If you want a quick response or problem resolution when using this library in your project, please register as a [sponsor](https://github.com/sponsors/goccy). I will cooperate as much as possible. Of course, this library is developed as an MIT license, so you can use it freely for free.\n\n# License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgoccy%2Fgo-yaml","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgoccy%2Fgo-yaml","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgoccy%2Fgo-yaml/lists"}