Skip to content
StringToJSON

Go (Golang) — String to JSON

Convert a string to JSON in Go.

json.Unmarshal into a struct or a map, json.Marshal back out. Verify your payload with the free online converter above, then match it to a Go type.

Escaped string

0 B

JSON

0 B

Output appears here.

Ready. Paste something above.

Everything runs locally in your browser — your data never leaves this page. Press⌘/Ctrl +Enter to run.

Unmarshal needs a destination

import "encoding/json"

type User struct {
    ID   int      `json:"id"`
    Name string   `json:"name"`
    Tags []string `json:"tags,omitempty"`
}

var u User
if err := json.Unmarshal([]byte(s), &u); err != nil {
    return fmt.Errorf("parse user: %w", err)
}

b, err := json.Marshal(u)     // back to []byte
out := string(b)

Go has no dynamic JSONObject type, so unlike Python or JavaScript there is no "parse and see what you get". You declare the shape first and the decoder fills it in. That is more typing up front and considerably fewer surprises later.

Struct tags

The backtick tag maps a JSON key to a Go field. Without it, matching falls back to a case-insensitive comparison of the field name — which works for name but not foruser_id. Two modifiers matter: omitempty drops zero values when marshalling, and - excludes a field from JSON entirely, which is how you keep a password hash out of an API response.

When the shape is unknown

var v map[string]interface{}
json.Unmarshal([]byte(s), &v)

name, ok := v["name"].(string)   // assert every access
id := int(v["id"].(float64))     // numbers arrive as float64

// keep a sub-document unparsed until you know its type
type Envelope struct {
    Kind string          `json:"kind"`
    Data json.RawMessage `json:"data"`
}

json.RawMessage is the idiomatic answer to polymorphic payloads: read the discriminator field first, then unmarshal the deferred bytes into the right concrete type. It avoids both the double parse and the type assertions.

Traps worth knowing

  • Unexported fields are invisible. A lowercase field name is skipped in both directions, silently, with no error.
  • float64 for every number. Unmarshalling into interface turns an int64 ID into a float and loses precision past 2^53. Use a typed struct field.
  • omitempty cannot see the difference between zero and absent. Afalse or 0 disappears from the output. Use a pointer field when the distinction matters.
  • Unmarshal ignores unknown keys. That is usually right for API clients; when it is not, use a Decoder with DisallowUnknownFields().
  • Marshal escapes HTML by default, turning < into\u003c. Disable it with Encoder.SetEscapeHTML(false).

Streams beat strings

Unmarshal needs the entire document in memory before it starts. For an HTTP handler that is usually fine, but for a large file or a long-lived response it is wasteful.json.NewDecoder(r).Decode(&v) reads straight from anyio.Reader, and json.NewEncoder(w).Encode(v) writes straight to anio.Writer — no intermediate byte slice, and a lower memory ceiling that does not grow with the payload.

The decoder also handles streams of concatenated documents, which is what makes it the right tool for JSON Lines: call Decode in a loop until it returns io.EOF and each call consumes exactly one value. Do add http.MaxBytesReader around request bodies before decoding, or a client can hand you a payload large enough to exhaust the process.

Custom marshalling

When a type does not map cleanly onto JSON — a time.Duration that should be written as "30s", an enum stored as an int but exposed as a name — implementMarshalJSON and UnmarshalJSON on the type itself. The encoder checks for those interfaces before falling back to reflection, so the conversion lives with the type rather than being repeated at every call site. Define them on a named type rather than a struct field, and keep the two implementations symmetrical: a round trip that does not return the original value is a bug that will surface as data drift long after you wrote it.

Naming, briefly

Golang convert string to JSON and convert string to JSON golang both meanjson.Unmarshal; golang convert JSON to string and convert JSON to string golang both mean json.Marshal followed by a string() conversion. Go has exactly two entry points and no third-party parser is required for either direction.

Frequently asked questions

How to convert a string to JSON in Go?
Convert the string to a byte slice and pass a pointer to your target: json.Unmarshal([]byte(s), &v). Go has no generic "JSON value" type, so you always unmarshal into something — a struct, a map, or interface{}.
Struct or map[string]interface{}?
A struct whenever you know the shape — you get compile-time field names and real types. Use map[string]interface{} only for genuinely dynamic documents, and expect to type-assert every value you read out of it.
Why are my struct fields empty after unmarshalling?
Almost always unexported fields. encoding/json uses reflection and can only see exported names, so a field must start with a capital letter. The second cause is a name mismatch — add a `json:"field_name"` tag.
Why did my numbers become float64?
Unmarshalling into interface{} maps every JSON number to float64, which loses precision on large integers. Use a struct with an int64 field, or call Decoder.UseNumber() to get json.Number and convert deliberately.
How do I convert a struct back to a JSON string?
b, err := json.Marshal(v) then string(b). Use json.MarshalIndent(v, "", " ") when you want it formatted.