Native
JSON::Native
A JSON parser with a native fast path on Raku++, and JSON::Fast everywhere else.
The XS pattern: the distribution ships C source, the build step compiles it
against Raku++'s extension ABI, and the module uses it when it is there. On a
Raku++ without the built extension, from-json still runs native through the
interpreter's own built-in codec. On Rakudo ā or wherever neither is present ā
nothing breaks, it simply calls JSON::Fast. The same program runs on both.
Why it exists
Raku++ interprets an AST rather than JIT-compiling, so a tokenizer written in
Raku costs it roughly an order of magnitude more than it costs Rakudo, and
JSON is exactly that shape of work. The engine fast-paths the JSON::Fast
calls it can cover ā both directions ā so what this module adds is the parse
column below, and a name that says at the point of use that the code leans
on native speed. 278 KB document, measured 2026-08-23:
278 KB document parse serialise
Rakudo JSON::Fast 42 ms 41 ms
Raku++ JSON::Fast (fast path) ~6 ms 6.1 ms
JSON::Native (extension) 5.0 ms 3.5 ms
Synopsis
use JSON::Native;
my $data = from-json('{"a": [1, 2.5, true, null]}');
say $data<a>[1].WHAT; # (Rat) ā Raku numerics, not doubles
say to-json($data, :!pretty);
say json-backend; # 'native', 'engine' or 'JSON::Fast'
Compatibility
from-json returns what JSON::Fast returns, checked value by value: Int for
integer tokens (arbitrary precision), Rat for decimals, Num for exponent forms,
Bool, Any for null, Hash and Array ā or Map and List under :immutable.
to-json is native too as of extension ABI 2, which made a hash walk cost
O(1) per key instead of O(i). Its output is JSON::Fast's, byte for byte ā
that is a contract programs already depend on, so it is checked value by value
rather than merely being valid JSON, down to backspace being written as a
six-character \u escape rather than as \b.
The native serialiser takes one value and an optional :pretty. Anything
else ā :sorted-keys, :spacing, NaN/Inf (whose rendering follows
$*JSON_NAN_INF_SUPPORT), or a value outside the extension ABI's
vocabulary ā falls through to JSON::Fast unchanged. from-json follows
the same rule for adverbs: :immutable is native, anything else
(:allow-jsonc, or whatever JSON::Fast grows next) is delegated, never
refused. Being exactly right or standing aside is the whole bargain; being
approximately right would be worse than being slow.