# json

> Parse, query, edit, merge, and pretty-print JSON, plus streaming parse of arrays and NDJSON.

# json

The `json` module parses JSON into navigable values, queries and edits JSON strings by key, merges and reshapes objects and arrays, pretty-prints or minifies, and streams large arrays or NDJSON one value at a time. Import it with `import json`.

## Parsing and serialization

| Function | Signature | Description |
| --- | --- | --- |
| `valid` | `json.valid(s: string) → bool` | Whether `s` is valid JSON |
| `parse` | `json.parse(s: string) → any` | Parse into a navigable object/array/scalar tree |
| `stringify` | `json.stringify(v: any, indent?: string) → string` | Serialize a value; pass an indent for pretty output. Keys are sorted |
| `pretty` | `json.pretty(s: string) → string` | Re-indent existing JSON text with 2 spaces |
| `minify` | `json.minify(s: string) → string` | Strip whitespace from JSON text |

## Querying

These operate on a JSON string and read top-level keys.

| Function | Signature | Description |
| --- | --- | --- |
| `get` | `json.get(j: string, key: string) → string` | Value at `key` as a string; empty if missing/null |
| `getInt` | `json.getInt(j: string, key: string) → int` | Value at `key` as int; 0 if missing/non-numeric |
| `getBool` | `json.getBool(j: string, key: string) → bool` | Value at `key` as bool; false if missing |
| `has` | `json.has(j: string, key: string) → bool` | Whether `key` exists |
| `keys` | `json.keys(obj: any) → string[]` | Sorted field names of a parsed object or JSON string |
| `length` | `json.length(j: string) → int` | Object key count or array length |
| `arrayGet` | `json.arrayGet(j: string, idx: int) → string` | Element at `idx` of a JSON array |

## Editing

These return a new JSON string with the change applied.

| Function | Signature | Description |
| --- | --- | --- |
| `setString` | `json.setString(j: string, key: string, val: string) → string` | Set `key` to a string value |
| `setInt` | `json.setInt(j: string, key: string, val: int) → string` | Set `key` to an int value |
| `setBool` | `json.setBool(j: string, key: string, val: bool) → string` | Set `key` to a bool value |
| `delete` | `json.delete(j: string, key: string) → string` | Remove `key` |
| `merge` | `json.merge(j1: string, j2: string) → string` | Merge two objects; `j2` keys overwrite `j1` |
| `fromArray` | `json.fromArray(arr: string[]) → string` | Convert an array into a JSON array string |

## json.stream

Streams a JSON source one top-level value at a time, calling `fn(value)` for each. Handles both a JSON array (each element delivered separately) and concatenated values or NDJSON. The callback may return `false` to stop early. Returns the count of values delivered.

| Function | Signature | Description |
| --- | --- | --- |
| `parseString` | `json.stream.parseString(s: string, fn) → int` | Stream values from a JSON string |
| `parseFile` | `json.stream.parseFile(path: string, fn) → int` | Stream values from a JSON file |

## Example

```goost
import json

let doc = json.parse("{\"name\": \"alice\", \"age\": 30}")
print(doc.name)                         // alice

let updated = json.setInt("{\"age\": 30}", "age", 31)
print(updated)

json.stream.parseString("[1, 2, 3]", fn(v) {
    print(v)
    return true
})
```