pydantic/jiter

Fast iterable JSON parser.

Rust

558

262 commits

updated Sep 26, 2026

See the code

README

jiter

CI Crates.io CodSpeed Badge

Fast iterable JSON parser.

Documentation is available at docs.rs/jiter.

jiter has three interfaces:

  • JsonValue an enum representing JSON data
  • Jiter an iterator over JSON data
  • PythonParse which parses a JSON string into a Python object

JsonValue Example

See the JsonValue docs for more details.

use jiter::JsonValue;

let json_data = r#"
    {
        "name": "John Doe",
        "age": 43,
        "phones": [
            "+44 1234567",
            "+44 2345678"
        ]
    }"#;
let json_value = JsonValue::parse(json_data.as_bytes(), true).unwrap();
println!("{:#?}", json_value);

returns:

Object(
    {
        "name": Str("John Doe"),
        "age": Int(43),
        "phones": Array(
            [
                Str("+44 1234567"),
                Str("+44 2345678"),
            ],
        ),
    },
)

Jiter Example

To use Jiter, you need to know what schema you're expecting:

use jiter::{Jiter, NumberInt, Peek};

let json_data = r#"
    {
        "name": "John Doe",
        "age": 43,
        "phones": [
            "+44 1234567",
            "+44 2345678"
        ]
    }"#;
let mut jiter = Jiter::new(json_data.as_bytes());
assert_eq!(jiter.next_object().unwrap(), Some("name"));
assert_eq!(jiter.next_str().unwrap(), "John Doe");
assert_eq!(jiter.next_key().unwrap(), Some("age"));
assert_eq!(jiter.next_int().unwrap(), NumberInt::Int(43));
assert_eq!(jiter.next_key().unwrap(), Some("phones"));
assert_eq!(jiter.next_array().unwrap(), Some(Peek::String));
// we know the next value is a string as we just asserted so
assert_eq!(jiter.known_str().unwrap(), "+44 1234567");
assert_eq!(jiter.array_step().unwrap(), Some(Peek::String));
// same again
assert_eq!(jiter.known_str().unwrap(), "+44 2345678");
// next we'll get `None` from `array_step` as the array is finished
assert_eq!(jiter.array_step().unwrap(), None);
// and `None` from `next_key` as the object is finished
assert_eq!(jiter.next_key().unwrap(), None);
// and we check there's nothing else in the input
jiter.finish().unwrap();

Benchmarks

There are lies, damned lies and benchmarks.

In particular, serde-json benchmarks use serde_json::Value which is significantly slower than deserializing to a string.

For more details, see the benchmarks.

benchmarkjiter iterjiter valueserde valueserde/jiter
strings
x1008ns9ns40ns4.4x
sentence232ns124ns293ns2.4x
unicode268ns159ns308ns1.9x
unicode_dense152ns152ns177ns1.2x
string_array466ns751ns3.0µs4.0x
pass2304ns785ns576ns0.7x
json_cases_strings-14.92ms58.85ms3.9x
json_cases_escapes-1.62ms2.44ms1.5x
json_cases_non-ascii-715.5µs995.3µs1.4x
numbers
short_numbers-10.9µs37.6µs3.4x
floats_array15.2µs19.2µs117.2µs6.1x
doubles_array13.2µs17.6µs110.9µs6.3x
short_floats9.7µs12.6µs46.6µs3.7x
long_significand_floats12.1µs13.9µs94.7µs6.8x
bigints_array12.2µs12.5µs69.3µs5.6x
massive_ints_array73.2µs77.9µs284.9µs3.7x
big2.93ms3.96ms20.32ms5.1x
json_cases_numbers-7.81ms50.42ms6.5x
json_cases_ints-7.82ms50.27ms6.4x
json_cases_floats-3.04ms17.68ms5.8x
constants
true_array194ns477ns1.1µs2.3x
true_object2.4µs1.4µs6.0µs4.2x
json_cases_constants-25.6µs66.3µs2.6x
documents
pass1-1.8µs5.3µs3.0x
medium_response-2.2µs6.8µs3.1x
json_cases_all-22.15ms90.38ms4.1x
json_cases_arrays-10.78ms45.96ms4.3x
json_cases_objects-12.98ms53.66ms4.1x
json_cases_deep-4.63ms12.83ms2.8x
json_cases_whitespace-6.24ms16.58ms2.7x
json_cases_error-2.38ms11.87ms5.0x

Part of the Pydantic Stack

The Pydantic Stack is everything you need to ship production-grade AI agents:

json
json-parser
pydantic
rust

pydantic/jiter

Fast iterable JSON parser.

Rust

558

262 commits

updated Sep 26, 2026

See the code

README

jiter

CI Crates.io CodSpeed Badge

Fast iterable JSON parser.

Documentation is available at docs.rs/jiter.

jiter has three interfaces:

  • JsonValue an enum representing JSON data
  • Jiter an iterator over JSON data
  • PythonParse which parses a JSON string into a Python object

JsonValue Example

See the JsonValue docs for more details.

use jiter::JsonValue;

let json_data = r#"
    {
        "name": "John Doe",
        "age": 43,
        "phones": [
            "+44 1234567",
            "+44 2345678"
        ]
    }"#;
let json_value = JsonValue::parse(json_data.as_bytes(), true).unwrap();
println!("{:#?}", json_value);

returns:

Object(
    {
        "name": Str("John Doe"),
        "age": Int(43),
        "phones": Array(
            [
                Str("+44 1234567"),
                Str("+44 2345678"),
            ],
        ),
    },
)

Jiter Example

To use Jiter, you need to know what schema you're expecting:

use jiter::{Jiter, NumberInt, Peek};

let json_data = r#"
    {
        "name": "John Doe",
        "age": 43,
        "phones": [
            "+44 1234567",
            "+44 2345678"
        ]
    }"#;
let mut jiter = Jiter::new(json_data.as_bytes());
assert_eq!(jiter.next_object().unwrap(), Some("name"));
assert_eq!(jiter.next_str().unwrap(), "John Doe");
assert_eq!(jiter.next_key().unwrap(), Some("age"));
assert_eq!(jiter.next_int().unwrap(), NumberInt::Int(43));
assert_eq!(jiter.next_key().unwrap(), Some("phones"));
assert_eq!(jiter.next_array().unwrap(), Some(Peek::String));
// we know the next value is a string as we just asserted so
assert_eq!(jiter.known_str().unwrap(), "+44 1234567");
assert_eq!(jiter.array_step().unwrap(), Some(Peek::String));
// same again
assert_eq!(jiter.known_str().unwrap(), "+44 2345678");
// next we'll get `None` from `array_step` as the array is finished
assert_eq!(jiter.array_step().unwrap(), None);
// and `None` from `next_key` as the object is finished
assert_eq!(jiter.next_key().unwrap(), None);
// and we check there's nothing else in the input
jiter.finish().unwrap();

Benchmarks

There are lies, damned lies and benchmarks.

In particular, serde-json benchmarks use serde_json::Value which is significantly slower than deserializing to a string.

For more details, see the benchmarks.

benchmarkjiter iterjiter valueserde valueserde/jiter
strings
x1008ns9ns40ns4.4x
sentence232ns124ns293ns2.4x
unicode268ns159ns308ns1.9x
unicode_dense152ns152ns177ns1.2x
string_array466ns751ns3.0µs4.0x
pass2304ns785ns576ns0.7x
json_cases_strings-14.92ms58.85ms3.9x
json_cases_escapes-1.62ms2.44ms1.5x
json_cases_non-ascii-715.5µs995.3µs1.4x
numbers
short_numbers-10.9µs37.6µs3.4x
floats_array15.2µs19.2µs117.2µs6.1x
doubles_array13.2µs17.6µs110.9µs6.3x
short_floats9.7µs12.6µs46.6µs3.7x
long_significand_floats12.1µs13.9µs94.7µs6.8x
bigints_array12.2µs12.5µs69.3µs5.6x
massive_ints_array73.2µs77.9µs284.9µs3.7x
big2.93ms3.96ms20.32ms5.1x
json_cases_numbers-7.81ms50.42ms6.5x
json_cases_ints-7.82ms50.27ms6.4x
json_cases_floats-3.04ms17.68ms5.8x
constants
true_array194ns477ns1.1µs2.3x
true_object2.4µs1.4µs6.0µs4.2x
json_cases_constants-25.6µs66.3µs2.6x
documents
pass1-1.8µs5.3µs3.0x
medium_response-2.2µs6.8µs3.1x
json_cases_all-22.15ms90.38ms4.1x
json_cases_arrays-10.78ms45.96ms4.3x
json_cases_objects-12.98ms53.66ms4.1x
json_cases_deep-4.63ms12.83ms2.8x
json_cases_whitespace-6.24ms16.58ms2.7x
json_cases_error-2.38ms11.87ms5.0x

Part of the Pydantic Stack

The Pydantic Stack is everything you need to ship production-grade AI agents:

json
json-parser
pydantic
rust

Project health

PyPI

Latest release

0.17.0 · Sep 12, 2026

Releases this year

7

Significant stargazers

Jan-Erik Rediger

1,034 followers · starred Jul 2024

Lukas Geiger

304 followers · starred Dec 2024

XAMPPRocky

801 followers · starred Sep 2024

Emma Smith

476 followers · starred Apr 2026