<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/a-new-go-api-for-json-psqxhjoea" -->

---
title: A new Go API for JSON | daily.dev
description: Go 1.27 ships new encoding/json/v2 and encoding/json/jsontext packages as stable APIs. They fix long-standing issues in encoding/json: invalid UTF-8 is now...
canonical: https://daily.dev/posts/a-new-go-api-for-json-psqxhjoea
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: A new Go API for JSON | daily.dev
og:description: Go 1.27 ships new encoding/json/v2 and encoding/json/jsontext packages as stable APIs. They fix long-standing issues in encoding/json: invalid UTF-8 is now...
og:url: https://daily.dev/posts/a-new-go-api-for-json-psqxhjoea
og:image: https://api.daily.dev/og/posts/psQxHJoEa.png
og:image:alt: A new Go API for JSON
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# A new Go API for JSON

**[Go](https://daily.dev/sources/golang)** · 17 min read · 1 upvotes · 0 comments

## Summary

Go 1.27 ships new encoding/json/v2 and encoding/json/jsontext packages as stable APIs. They fix long-standing issues in encoding/json: invalid UTF-8 is now rejected, duplicate JSON object names cause errors, and nil slices or maps marshal as empty arrays or objects instead of null. Struct field matching becomes case-sensitive, and unmarshal performance improves by up to 10x in some benchmarks. The v1 package stays fully supported, and v1 and v2 remain interoperable since v1 is now implemented in terms of v2. The effort took about 6 years to reach this stable release.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://go.dev/blog/jsonv2>

## Questions this post answers

### What changes in Go's new encoding/json/v2 package compared to encoding/json?

Encoding/json/v2, stable in Go 1.27, rejects invalid UTF-8 and duplicate JSON object names by default, marshals nil slices and maps as empty arrays or objects instead of null, and matches struct fields case-sensitively. It also redefines omitempty to cover any field that would encode as an empty JSON value (null, "", [], {}).

_Teams planning a json/v2 migration can track Go's compatibility notes and guides on daily.dev._

### Do I need to migrate my Go code from encoding/json to encoding/json/v2?

No, applications using v1 encoding/json continue to be supported indefinitely and never need to migrate. Go 1.27 implements v1 in terms of v2 internally, so v1 and v2 marshalers and unmarshalers interoperate, letting packages mix versions and migrate gradually rather than all at once.

_Developers weighing a gradual json/v2 adoption can follow related Go release coverage on daily.dev._

### How much faster is JSON unmarshaling in Go 1.27's encoding/json/v2 versus the original encoding/json?

Unmarshal performance in encoding/json/v2 is significantly faster than v1, with benchmarks showing improvements of up to 10x. Marshal performance stays roughly at parity with v1, sometimes slightly faster and sometimes slightly slower, with further optimizations planned for Go 1.28.

_Developers benchmarking JSON performance before upgrading can keep tabs on Go release notes via daily.dev._

## Community take

How the wider developer community reacted, aggregated from 2 discussions and 49 comments across hackernews, lobsters (as of 2026-11-04).

**TL;DR:** Most of the discussion is a long technical debate about Go's error-handling philosophy in Marshal/Unmarshal, alongside genuine appreciation for the new v2 API and curiosity about why it took six years to ship.

**Sentiment:** 35% positive · 45% mixed · 20% skeptical

**The case for**

- Several developers say they like encoding/json/v2 and are glad it finally shipped.
- Some note the missing MarshalIndent can be replicated via jsontext's Indent/WithIndent helpers.
- A few argue Go's slow, careful standard library evolution keeps the ecosystem easier to reason about.

**The pushback**

- Many push back on why Marshal returns an error at all, arguing it should panic or be a compile-time issue instead.
- Commenters point out MarshalIndent was dropped and its replacement is seen as more complicated and non-obvious.
- Some are frustrated that this and other features (like generics) took Go an unusually long time to land.

**By community**

- hackernews (mixed): A lengthy back-and-forth debates whether Marshal's error return makes sense, mixed with praise for the new API, complaints about losing MarshalIndent, and tangents on why it took six years and how Go fits into AI-assisted coding workflows.
- lobsters (positive): Brief, informational comments noting this builds on a year-old experimental API with only minor changes since.

**Hottest debate:** Whether json.Marshal should ever return an error versus panicking or being caught at compile time.

**Open questions**

- Why did this API take roughly six years to stabilize compared to other language ecosystems' JSON libraries?
- Could a schema-aware or staged-parsing approach give JSON the performance of formats like simdjson while retaining type safety?

**Highlights**

> the marshal api has been very annoying. why does marshal return an error? the only reason the marshal can return an error is that the input type is not marshalable. it's certainly a code bug. to me it's like int+str returning an error instead of compiler error
> — [lolpanda on hackernews · 9 comments](https://news.ycombinator.com/item?id=50369779)

> > why does marshal return an error? the only reason the marshal can return an error is that the input type is not marshalable Not necessarily. Among other things, MarshalJSON methods called during marshaling can return an error for whatever reason the developer sees fit - one possibility that comes to mind is that part of the object tree being marshalled is lazily loaded, and failed to do so. And, as others have mentioned, there are types like "any" whose marshalability can't be determined at compile time. Those types aren't necessarily at the top level, either; they could appear anywhere in the object tree.
> — [duskwuff on hackernews](https://news.ycombinator.com/item?id=50370539)

> I generally like `encoding/json/v2` and I'm glad they did it. I wish they'd left `MarshalIndent` in there though. The equivalent code is super complicated and non-obvious, so it's a pain to migrate, and it's a pain when you're banging out some quick code and want to dump some readable JSON. I suppose these days the LLMs can write the complicated version for us, of course.
> — [CamouflagedKiwi on hackernews · 2 comments](https://news.ycombinator.com/item?id=50369853)

> The fact that this took 6 years to land stood out to me. I'm not entirely surprised, and I'm glad the Go team is carefully considering their interfaces before launching. But 6 years seems like a lot of work to land a JSON API.
> — [cbarrick on hackernews · 1 comments](https://news.ycombinator.com/item?id=50370631)

> There aren’t any major changes from the original GOEXPERIMENT.  This post is actually an updated version of last year’s experiment post at https://go.dev/blog/jsonv2-exp. From what’s described there literally the only update I had to make from that post is that the “inline” struct tag was renamed to “embed”. Other minor changes to functionality from the original GOEXPERIMENT: * The “string” tag no longer applies recursively (for consistency with other tags). * The “format” tag is removed (we hope to bring this back with better syntax using something like https://go.dev/issue/74472). * Small adjustments to encoding/json/jsontext helper functions (e.g., jsontext.Token.Int and friends can now return an error). * Probably a few other minor changes I’m forgetting at the moment.
> — [prattmic on lobsters · 1 points](https://lobste.rs/s/gfm0xn/new_go_api_for_json_go_programming#c_m8dfco)

**Source threads**

- [hackernews](https://news.ycombinator.com/item?id=50369106) · 90 points · 47 comments
- [lobsters](https://lobste.rs/s/gfm0xn/new_go_api_for_json_go_programming) · 9 points · 2 comments

## Similar posts on daily.dev

- [Go 1.27 interactive tour](https://daily.dev/posts/go-1-27-interactive-tour-dvxr0krfs) · Lobsters · 11 upvotes · 0 comments

---

Tags: [#performance](https://daily.dev/tags/performance), [#architecture](https://daily.dev/tags/architecture), [#golang](https://daily.dev/tags/golang)

[View this post on daily.dev](https://daily.dev/posts/a-new-go-api-for-json-psqxhjoea)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"A new Go API for JSON","url":"https://daily.dev/posts/a-new-go-api-for-json-psqxhjoea","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/a-new-go-api-for-json-psqxhjoea"},"datePublished":"2026-11-04T17:45:56.659Z","dateModified":"2026-11-04T20:34:35.732Z","description":"Go 1.27 ships new encoding/json/v2 and encoding/json/jsontext packages as stable APIs. They fix long-standing issues in encoding/json: invalid UTF-8 is now...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/39b837b91d435ac673a1daa7b32a05fa?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/39b837b91d435ac673a1daa7b32a05fa?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Go","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Go","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/f416aeab0a1f4b9faa22d93768c97905","url":"https://daily.dev/sources/golang"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/a-new-go-api-for-json-psqxhjoea","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":1},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"performance,architecture,golang","timeRequired":"PT17M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Go","item":"https://daily.dev/sources/golang"},{"@type":"ListItem","position":3,"name":"A new Go API for JSON"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/a-new-go-api-for-json-psqxhjoea#faq","mainEntity":[{"@type":"Question","name":"What changes in Go's new encoding/json/v2 package compared to encoding/json?","acceptedAnswer":{"@type":"Answer","text":"Encoding/json/v2, stable in Go 1.27, rejects invalid UTF-8 and duplicate JSON object names by default, marshals nil slices and maps as empty arrays or objects instead of null, and matches struct fields case-sensitively. It also redefines omitempty to cover any field that would encode as an empty JSON value (null, \"\", [], {}). Teams planning a json/v2 migration can track Go's compatibility notes and guides on daily.dev."}},{"@type":"Question","name":"Do I need to migrate my Go code from encoding/json to encoding/json/v2?","acceptedAnswer":{"@type":"Answer","text":"No, applications using v1 encoding/json continue to be supported indefinitely and never need to migrate. Go 1.27 implements v1 in terms of v2 internally, so v1 and v2 marshalers and unmarshalers interoperate, letting packages mix versions and migrate gradually rather than all at once. Developers weighing a gradual json/v2 adoption can follow related Go release coverage on daily.dev."}},{"@type":"Question","name":"How much faster is JSON unmarshaling in Go 1.27's encoding/json/v2 versus the original encoding/json?","acceptedAnswer":{"@type":"Answer","text":"Unmarshal performance in encoding/json/v2 is significantly faster than v1, with benchmarks showing improvements of up to 10x. Marshal performance stays roughly at parity with v1, sometimes slightly faster and sometimes slightly slower, with further optimizations planned for Go 1.28. Developers benchmarking JSON performance before upgrading can keep tabs on Go release notes via daily.dev."}}]}
```

