File::Raw · File::Raw::JSON 0.08

File::Raw::JSON

JSON and JSON Lines, read and written through File::Raw.

A file to a Perl structure in one call, and back: the json plugin for one document, jsonl for JSON Lines streamed a record at a time. The parser is yyjson, vendored, behind File::Raw's one read.

Registers jsonjsonl

use File::Raw ();
use File::Raw::JSON;

my $config = File::Raw::slurp('config.json', plugin => 'json');

File::Raw::spew('config.out.json', $config,
    plugin => 'json', pretty => 1, sort_keys => 1);

# JSON Lines, one record at a time: memory stays flat.
File::Raw::each_line('events.jsonl', sub {
    my $event = $_[0];
    print "$event->{type}\n";
}, plugin => 'jsonl');

What you get

  • Two plugins

    json is one value per file. jsonl is JSON Lines, NDJSON or concatenated values: a list on slurp, one record at a time on each_line.

  • JSON Lines as files really are

    Records are found by balancing braces, not by splitting on newlines: a pretty-printed record spanning lines, two records on one line, and braces inside strings all parse.

  • A direct codec

    file_json_decode and file_json_encode for bytes already in memory, with mode => 'lines' for JSONL.

  • Key order kept, when asked

    ordered => 1 decodes into hashes that keep their key order, and the encoder writes them back in that order, so a file round-trips byte for byte. relaxed => 1 accepts comments and trailing commas.

  • Pretty, sorted, or neither

    pretty and sort_keys on the way out, for files people read and diffs people review.

In use

use File::Raw::JSON qw(file_json_decode file_json_encode);

# Bytes already in memory, no file involved.
my $value = file_json_decode('{"name":"lnation","tags":["perl","xs"]}');
my $bytes = file_json_encode($value, sort_keys => 1);

my $rows  = file_json_decode(qq({"n":1}\n{"n":2}\n), mode => 'lines');
print scalar(@$rows), " rows\n";

The numbers

Against the fastest alternative that was installed, and shown whichever way it went.

  • 1.0x decode a 0.8 MB document, against JSON::XS File::Raw::JSON 0.08 at 315/s, JSON::XS 4.04 at 300/s
  • 0.8x encode a 0.8 MB document, keys sorted, against JSON::XS File::Raw::JSON 0.08 at 333/s, JSON::XS 4.04 at 417/s

Measured on Apple M5, darwin with perl 5.42.0, 2026-10-19: each entry timed for 3 CPU seconds by the Benchmark module, 3 times, the median kept, after checking that both sides produced the same result. Every number.

For C

frj_abi.h is a table of the codec for other XS modules: resolve it once at BOOT through File::Raw::JSON::_abi_ptr, then decode and encode with no Perl call in between. The reference has a Hyperman handler decoding a request body with it.

The header in the reference

Works with

Chains from its documentation: the plugins run left to right on a read, right to left on a write.

Get it

cpanm File::Raw::JSON

The reference

Every File::Raw dist