HermannSamimi/jtoken: json token minimizer. Contribute to HermannSamimi/jtoken development by creating an account on GitHu

github.com · 2026-09-29 · by Long Nguyen ·github
json token minimizer. Contribute to HermannSamimi/jtoken development by creating an account on GitHub.

HermannSamimi/jtoken

json token minimizer. Contribute to HermannSamimi/jtoken development by creating an account on GitHub.

1 stars · 0 forks

README

jtoken

Compress JSON for LLM prompts — same data, fewer tokens. Author: Hermann Samimi PyPI · Repository · Issues jtoken strips JSON syntactic noise, collapses repeated booleans and nulls into summary lines, flattens nested dicts with dot notation, and supports normalization for Elasticsearch hits and MongoDB JSON. The package ships as a stdlib-first library with an optional tiktoken extra and a jtoken CLI. Table of contents

Installation Quick start What the format looks like Normalization and denormalization CLI Token savings API reference Development Contributing Security License

Installation TipInstall jtoken[tiktoken] when you want OpenAI-compatible token counts from the real tokenizer. The core package uses only the standard library and falls back to an estimate when tiktoken is not installed.

Core pip install jtoken No extra runtime dependencies. With tokenizer-accurate counting pip install "jtoken[tiktoken]" Use the tiktoken extra when you want OpenAI-compatible token counts instead of the built-in estimate backend. Quick start import jtoken

data = { "user": "alice", "age": 30, "premium": True, "verified": True, "is_remote": False, "trial": False, "score": 9.5, "referral": None, "last_login": None, }

text = jtoken.encode(data) original = jtoken.decode(text) assert original == data dumps / loads are json-style aliases for encode / decode. What the format looks like JSON {"name": "Alice", "age": 30, "active": true, "verified": false, "ref": null} jtoken name: Alice age: 30 trues: active falses: verified nulls: ref

Nested dicts flatten with dot notation. Booleans and nulls at any depth collapse into the same summary lines. Decode reconstructs the original nested structure. Normalization and denormalization NoteDecoding back to Mongo shell, Extended JSON, or an Elasticsearch hit envelope is only lossless when you keep the normalization context from encode (NormalizationContext, or --context-out on the CLI) and pass it into decode (context=, or --context-in). Plain json / python output does not need a sidecar.

Foreign document shapes can be normalized before encoding and restored after decode with a sidecar context.

flowchart LR raw[RawDoc] --> norm[Normalize] norm --> enc[Encode] enc --> jt[JtokenText] enc --> ctx[ContextSidecar] jt --> dec[Decode] ctx --> dec dec --> denorm[Denormalize] denorm --> out[Output]

Loading

import jtoken

raw_hit = {...} normalized, context = jtoken.normalize(raw_hit, source="elastic_hit") text = jtoken.encode(normalized) restored = jtoken.denormalize( jtoken.decode(text), target="elastic_hit", context=context, ) jtoken encode --input-format elastic_hit -f hit.json --context-out hit.ctx.json jtoken decode --output-format mongo_shell -f hit.jtoken --context-in hit.ctx.json

Input and output formats (reference tables) Use source= / target= in Python or --input-format / --output-format on the CLI. encode, stats, and count accept --input-format (default auto). decode accepts --output-format (default json).

Input (source / --input-format) Use when

auto Let jtoken detect the dialect from the text or object shape

json Standard JSON object

python Same JSON parser as json

mongo_extended MongoDB Extended JSON with $oid, $date, $numberInt, $numberLong, $numberDouble, $numberDecimal

mongo_shell MongoDB shell document with ObjectId(), ISODate(), NumberInt(), NumberLong()

elastic_hit Elasticsearch search hit with _source (and optional fields)

elastic_source _source payload only, or a document wrapped as {"_source": {...}}

Output (target / --output-format) Use when

python Python repr (Python API default)

json Pretty-printed JSON (CLI decode default)

mongo_extended Extended JSON; requires a context sidecar for BSON-like types

mongo_shell Mongo shell document; requires a context sidecar for BSON-like types

elastic_hit Full Elasticsearch hit envelope; requires a context sidecar

elastic_source JSON shaped like an Elasticsearch _source wrapper

With auto, jtoken picks mongo_shell when it sees ObjectId(...) or ISODate(...), elastic_hit when the object has a dict _source, mongo_extended when Extended JSON markers such as $oid or $date appear, and otherwise json. Write the normalization context to a sidecar on encode (--context-out / NormalizationContext.to_dict()) and pass it back on decode when the output dialect is not plain JSON or Python. The sidecar records list paths, dotted keys, Elasticsearch envelope metadata, and MongoDB type markers in typed_values (object_id, datetime, long).

MongoDB shell and Extended JSON Mongo shell input is parsed as JSON after rewriting shell literals: ObjectId("...") and ISODate("...") become Extended JSON, NumberInt(n) becomes a plain integer, and NumberLong(n) becomes {"$numberLong": "n"}. On normalize, object_id, datetime, and long values are stored in the context so mongo_extended and mongo_shell output can restore {"$oid": ...} / ObjectId(...), {"$date": ...} / ISODate(...), and {"$numberLong": ...} / NumberLong(...). $numberInt, $numberDouble, and $numberDecimal are coerced to Python scalars and are not tracked in typed_values. Elasticsearch hits elastic_hit encodes the merged _source document (plus any fields values that are not already present in _source) and stores _index, _id, _version, _score, _type, and _routing in the context for lossless elastic_hit output. CLI echo '{"name": "Alice", "active": true}' | jtoken encode echo 'name: Alice\ntrues: active' | jtoken decode echo '{"name": "Alice", "active": true}' | jtoken stats echo '{"name": "Alice", "active": true}' | jtoken count Use -f/--file for file input. encode, stats, and count accept --input-format. decode accepts --output-format and --context-in when restoring non-JSON dialects. stats and count accept --model and --backend. Token savings import jtoken

stats = jtoken.token_savings(data, model="gpt-4o", backend="tiktoken", json_indent=2) print(stats)

jtoken: 22 tokens | json: 36 tokens | saved: 14 (38.9%)

print(stats.jtoken_tokens, stats.json_tokens, stats.saved, stats.percent) count_tokens and count_text_tokens are also available. Savings compare the jtoken representation against pretty JSON by default (json_indent=2).

Measured token savings (reproducible benchmark) Measured with tiktoken (cl100k_base) on 50 synthetic documents per shape, encoded one document at a time (as they would be injected into a prompt). Every payload is verified lossless (encode_document → decode_document → equal). Re-run it with the bundled script: python3 benchmarks/benchmark.py

Payload (50 docs) JSON (pretty) jtoken Saved

Elasticsearch hits 12,038 10,671 11.4%

MongoDB documents (extended JSON) 9,437 7,630 19.1%

Nested API events 12,773 11,083 13.2%

Total 34,248 29,384 14.2%

Savings depend on structure: short prose-heavy values cap the wins, while repetitive, nested machine-generated JSON (logs, monitoring, index payloads) compresses substantially better. Run the script on your own payloads before drawing conclusions.

API reference

Expand full API list Package metadata

jtoken._version_ jtoken._author_

Core codec

encode(data: dict) -> str decode(text: str) -> dict dumps / loads

Normalization

parse_input(text, *, source="auto") normalize(data, *, source="auto", context=None) -> tuple[dict, NormalizationContext] denormalize(data, *, target="python", context) render_output(value, *, target="python") -> str encode_document(raw, *, source="auto", context=None) -> tuple[str, NormalizationContext] decode_document(text, *, target="python", context)

Token helpers

count_tokens(data, *, model="cl100k_base", backend="auto") -> int count_text_tokens(text, *, model="cl100k_base", backend="auto") -> int token_savings(data, *, model="cl100k_base", backend="auto", json_indent=2) -> TokenSavings

TokenSavings

jtoken_tokens json_tokens saved percent

NormalizationContext

source_format target_format typed_values lists dotted_keys elastic to_dict() / from_dict()

Format enums

InputFormat OutputFormat

Exceptions

JPackError JPackEncodeError JPackDecodeError NormalizationError DenormalizationError TokenCountError

Development git clone https://github.com/HermannSamimi/jtoken.git cd jtoken pip install -e ".[dev]" pytest pytest --cov=jtoken --cov-report=term-missing Contributing Pull requests are welcome. Install the dev extra (see Development), run pytest, and open a PR against the default branch with a short description of the change. Security If you discover a security issue, please report it privately via GitHub Security advisories for this repository rather than a public issue. License MIT — © 2026 Hermann Samimi

⭐ If jtoken saved you tokens (or money on your API bill), please star the repo — it helps other LLM developers find it. And if you measured savings on your payloads, an issue with the numbers (and shape of data) is very welcome.

source

github.com · 5 images · 106 links

Comments (0)

No comments yet