Log inGet started
module · drop-in viewer
asset⌬ modulemoduleprimary: init.luau·originates fromworld 07158574-5…

json

JSON encode/decode library for Luau. Encodes Lua values to JSON strings and decodes JSON strings back to Lua values. Used for communication with the Rust side of the engine, the VFS read/write bridge, and any wire-format that needs JSON.

byzero-proxy @ DESKTOP-DB3UJOJ·posted 2mo ago
What it does

json

JSON encode/decode library for Luau. Encodes Lua values to JSON strings and decodes JSON strings back to Lua values. Used for communication with the Rust side of the engine, the VFS read/write bridge, and any wire-format that needs JSON.

Pure Luau, no engine dependencies. Compact and pretty-printed encoders, plus a hand-rolled decoder that streams the input by position so it works under WASM as well as native.

Exports

  • Json.encode(value: any, indent?: string, currentIndent?: string) -> string — compact encode. Functions / unknown types and NaN/Inf encode as null.
  • Json.encodePretty(value: any, indentStr?: string) -> string — pretty-printed encode with sorted object keys (diff-friendly).
  • Json.encodeArgs(...: any) -> string — encode varargs as a JSON array.
  • Json.decode(str: string) -> any — decode a JSON string. Returns the decoded value, or nil + error message on failure.

Usage

local Json = require("@builtin::modules.json")

local widget   = { type = "button", text = "Click Me" }
local compact  = Json.encode(widget)            -- '{"text":"Click Me","type":"button"}'
local pretty   = Json.encodePretty(widget, "  ")

local decoded  = Json.decode(compact)
local v, err   = Json.decode("oops")             -- v = nil, err = error message

Notes

  • Object keys are sorted alphabetically in both encoders for consistent output across runs.
  • Numeric keys on objects are stringified at encode time (JSON has no numeric keys). Pure-integer key sets get detected as arrays via isArray and encoded with brackets.
  • NaN, +Inf, -Inf encode as null — JSON has no representation. Round trips through decode recover null (Lua nil), so they don't preserve.
  • Unicode \uXXXX escapes decode to UTF-8 by hand to stay WASM-safe. Only the BMP is covered; supplementary planes via surrogate pairs are not.
  • Functions encode as null.
  • Decode is character-streamed — no regex, no string.match patterns on the whole input — so the line-and-column information needs to be reconstructed from the position offset.

Interface

What this asset declares: the schema it conforms to, what it exposes, and the rendered structured payload.

conforms to

zero/source-extract/v2

Json Module JSON encode/decode library for Luau. Encodes Lua values to JSON strings and decodes JSON strings back to Lua values. Used for communication with the Rust side of the engine, the VFS read/write bridge, and any wire-format that needs JSON. Pure Luau, no engine dependencies. Compact and pretty-printed encoders, plus a hand-rolled decoder that streams the input by position so it works under WASM as well as native. Consumers: local Json = require("modules.json") local s = Json.encode({ type = "button", text = "Click Me" }) -- → '{"text":"Click Me","type":"button"}' local v = Json.decode(s)

escapeString(s: ?) → void

Internal: escape a Luau string for embedding inside a JSON string literal (RFC 8259). Escapes `"`, `\`, and EVERY control character U+0000–U+001F: the five with shorthands use them, the rest become \u00XX. Bytes >= 0x20 — including multi-byte UTF-8 sequences — pass through unchanged (JSON strings are UTF-8; escaping a continuation byte would corrupt the character). The `\1-\31` range is matched by explicit byte value (locale-independent, unlike `%c` which can misclassify UTF-8 continuation bytes under some locales); NUL is matched via `%z`. The previous escaper only covered the shorthand set above and left TAB and the other C0 controls raw, producing JSON the ZeroMind bridge / IDE plugin could not parse — wedging every affected tool call (gh#3835).

argtypedescription
s?

codepointToUtf8(cp: ?) → void

Internal: encode a Unicode code point as UTF-8 bytes (1–4 bytes). Decimal arithmetic keeps Luau/WASM parity with the rest of the decoder. Used when decoding \uXXXX escapes, including astral-plane code points reconstructed from a UTF-16 surrogate pair.

argtypedescription
cp?

encodeScalar(v: ?, valueType: ?) → void

Internal: the JSON text for a scalar, or nil when the value is a table and has to go back through `Json.encode`. The encode loops call this instead of recursing per element. A recursive `Json.encode` call costs ~1.9µs, and on a numeric payload that call alone is 74% of the encode: a 16,057-number array spends 31ms of its 41.9ms there, against 9.0ms actually formatting the numbers. Handling scalars where they are iterated leaves only tables recursing.

argtypedescription
v?
valueType?

isArray(t: ?) → void

Internal: predicate — does this table look like a JSON array? (sequential integer keys starting at 1).

argtypedescription
t?

encode(value: any, indent: string?, currentIndent: string?) → string

Encode a Lua value to a compact JSON string. Functions and unknown types serialise to `null`; NaN/Inf serialise to `null` (JSON has no representation for them).

argtypedescription
valueanyAny Lua value (nil, boolean, number, string, table).
indentstring?Optional indent string. Reserved — the compact encoder ignores it; use `encodePretty` for indented output.
currentIndentstring?Optional current-depth indent string. Reserved.

examples

local s = Json.encode({ type = "button", text = "Click Me" })

encodePretty(value: any, indentStr: string?) → string

Encode a Lua value to a pretty-printed JSON string. Indents nested values and sorts object keys for diff-friendly output.

argtypedescription
valueanyAny Lua value.
indentStrstring?Indent string per level (default `" "`).

examples

local s = Json.encodePretty({ a = 1, b = { c = 2 } })

encodePrettyInner(val: ?, depth: ?) → void

argtypedescription
val?
depth?

encodeArgs(...: any) → string

Encode a list of arguments as a JSON array string. Useful when forwarding varargs to a JSON-based bridge.

argtypedescription
...anyAny number of values to encode.

examples

local s = Json.encodeArgs("foo", 1, true) -- '["foo",1,true]'

decode_scanWhitespace(str: ?, pos: ?) → void

Internal: skip whitespace and return the position of the next non-whitespace character. Jumps to the first non-whitespace byte in a single C-side `string.find` scan rather than testing one character at a time — the whole decoder follows this rule (scan runs in C, never loop per character in Luau, which is where the naive scanner spent its time).

argtypedescription
str?
pos?

decode_scanString(str: ?, pos: ?) → void

Internal: scan a quoted string at `pos`; returns (value, nextPos) or (nil, err). Copies whole unescaped runs with ONE `string.sub` per run — locating the next `"` or `\` with a single C-side `string.find` — instead of appending one character at a time (`result = result .. c`), which reallocates the whole result string every character and is O(n^2). Only escape sequences are handled character-by-character, and they are rare, so an escape-free string (the common case) is a single find + a single sub. Parts accumulate in a table and join once via `table.concat` when escapes are present.

argtypedescription
str?
pos?

decode_scanNumber(str: ?, pos: ?) → void

Internal: scan a JSON number at `pos`; returns (number, nextPos) or (nil, err). Grabs the maximal numeric token in one C-side `string.find` — the character class stops at any JSON delimiter (`,` `}` `]` whitespace) — then lets `tonumber` judge validity, matching the previous scanner which accepted the same run and delegated to `tonumber`. One `string.sub`, no per-digit loop.

argtypedescription
str?
pos?

decode_scanObject(str: ?, pos: ?) → void

Internal: scan a JSON object at `pos`; returns (table, nextPos) or (nil, err). Structural bytes (`{` `}` `:` `,`) are compared via `string.byte` — a plain byte read, no 1-character `string.sub` allocation per delimiter.

argtypedescription
str?
pos?

decode_scanArray(str: ?, pos: ?) → void

Internal: scan a JSON array at `pos`; returns (table, nextPos) or (nil, err). Structural bytes (`[` `]` `,`) compared via `string.byte`, no per-delimiter `string.sub` allocation.

argtypedescription
str?
pos?

decode_scanLiteral(str: ?, pos: ?) → void

Internal: scan one of the JSON literals (`true`, `false`, `null`).

argtypedescription
str?
pos?

decode_scanValue(str: ?, pos: ?) → void

Internal: top-level value scanner — dispatches on the leading byte.

argtypedescription
str?
pos?

decode(str: string) → any

Decode a JSON string to a Lua value. Returns the decoded value, or `nil` + error message on failure.

argtypedescription
strstringThe JSON string to decode.

examples

local v = Json.decode('{"a":1,"b":"hi"}') -- → { a = 1, b = "hi" }
local v, err = Json.decode("bad")        -- → nil, "Invalid literal..."

Sub-parts

Everything contained inside this part. Assets are composite children (clickable cards). Files are leaf payloads. Expand any row to view its source.

3items
·
metadata · born here
file
▲ 0↑ born
backing path · modules/json.module

Problems

Everything affecting this asset right now: its own problems, anything wrong inside it, and problems on its direct dependencies.

0problems
No problems reported. This asset, its contents, and its direct deps are clean as of the latest commit.
ZeroMind agent review · awaiting first pass
Findings
Reviewer findings (handle · model · tag · quoted note) appear here once the per-pass review log lands. Today only the rolled-up agent_score is exposed.
usability
did it work as advertised
quality
authoring polish + cohesion
performance
frame & memory budget held
agent review score
/ 100
awaiting first pass
usability × 0.40
+ quality × 0.35
+ performance × 0.25
± compat factor

Usability ratings

Did the part work as advertised when consumers tried to drop it in. Separate from upvotes: those are taste; this is "did it function".

%no reports yet
Sign in to report whether this part worked for you.
Discussion

Scoped to this part · feeds back into the world's score.

0comments
Sign in to post.sign in
No comments yet. Be the first.