Library / SDK
plokhotnyuk/jsoniter-scala avatar
plokhotnyuk/jsoniter-scala

jsoniter-scala: Compile-Time JSON Codecs Generated by Scala Macros

Scala macros for compile-time generation of safe and ultra-fast JSON codecs + circe booster

820 stars114 forksScalaMIT

At a glance

What is it?
jsoniter-scala is a MIT licensed Scala library that generates JSON parsers and serializers at compile time with macros, and it also ships a booster for circe. It suits teams on the JVM, Scala.js or Scala Native who need throughput on hot serialization paths and want codecs derived from case classes rather than hand written.
Who is it for?
jsoniter-scala fits a Scala team whose serialization sits on a hot path and whose data types are case classes, since a macro-generated codec removes the reflection and the hand written parser from the profile. It is the wrong choice if your models are irregular enough that a derivation macro cannot express them, or if you would rather not accept a library whose internal number handling is this specialised.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly Scala, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Codecs derived at compile time, not looked up at runtime

jsoniter-scala describes itself as Scala macros for compile-time generation of safe and ultra-fast JSON codecs. The mechanism is the whole point: the library inspects your types while the Scala compiler runs and emits parser and serializer code, so the JSON handling in your application is ordinary compiled code rather than a runtime lookup. The repository is split into `jsoniter-scala-core`, `jsoniter-scala-macros`, `jsoniter-scala-circe`, `jsoniter-scala-examples` and `jsoniter-scala-benchmark`, with a separate `jsoniter-scala-next-tests` module, and the build is driven by `build.sbt` alongside `project/`, `release.sbt` and `version.sbt`. The library started as macros that reused the json-iterator reader and writer for Java, then grew its own core of parsing and serialization mechanics, so the current code is not a thin wrapper around another project's parser.

The borrowed ideas explain where the speed comes from

The acknowledgements section is unusually informative, because it names the specific algorithms the library relies on rather than giving a general credit list. The idea of generating codecs by Scala macros came from Kryo Macros, originally developed by Alexander Nemish, and was adapted for the JSON domain. Other macro features were looked at in AVSystem Commons and magnolia, and the approach to the most efficient parsing and serialization of `java.time.*` values was inspired by DSL-JSON's implementation for `java.time.OffsetDateTime`. Numbers get their own lineage: XJB is credited as the most efficient and concise way to serialize doubles and floats, based on the Schubfach algorithm, rust-lexical for parsing floats and doubles precisely, big-math for parsing `BigInt` and `BigDecimal` at `O(n^1.5)` instead of Java's `O(n^2)`, and James Anhalt's algorithm for printing integers into decimal strings.

Eight byte at a time on the JVM

The parsing hot path leans on SWAR techniques, meaning work is done on several bytes at once rather than one character at a time. The credited sources are borer for fast parsing of JSON strings by 8-byte words, simdjson for fast checking of a string for digits by 8-byte words, FastDoubleParser for fast parsing of numbers by 8-byte words, and Johnny Lee's article for fast time string to seconds conversion. The platform-specific parts are what make this more than a portable trick: on the JVM the SWAR technique tricks are implemented for that platform specifically, and the library relies on low-level JVM intrinsics to get the expected throughput. The result is a parser whose hot loops are not the kind of loop you would write by hand, which is also why the code is hard to review casually.

Circe users can keep circe and change the codec

The `jsoniter-scala-circe` module exists for teams already on circe, and the project describes it as a circe booster. The practical distinction matters: adopting jsoniter-scala does not require rewriting every call site if your code already speaks circe's API, since the booster swaps the underlying codec generation. The same approach appears for play-json, where a separate booster project is credited in the benchmark comparison list, so the pattern of keeping an existing library's surface while changing what sits underneath has been repeated at least twice. The benchmark list also includes fory-json-scala, which is the Apache Fory JSON implementation for Scala, and that pairing is worth noting because it means the comparison covers both the macro-generated and the non-macro approaches to the same problem.

What the benchmarks compare, and on what hardware

The project publishes benchmark results for the JVM and for browsers, and the JVM comparison covers borer, circe, circe with the jsoniter-scala booster, fory-json-scala, jackson-module-scala, json4s-jackson, json4s-native, play-json, play-json with the booster, smithy4s-json, spray-json, uPickle, weePickle, zio-blocks, zio-json and zio-schema-json. The browser comparison is narrower, with circe, the circe booster, play-json, the play-json booster, smithy4s-json, uPickle, zio-blocks, zio-json and zio-schema-json, since not every JVM library has a Scala.js counterpart. The JVM libraries are compiled by Scala 3.9.0 with the `-opt -opt-inline:**,!java.**` options for optimization and inlining.

The hardware is specified just as precisely: an Intel Core Ultra 9 285K at 3.7GHz with a boost to 5.7GHz, 64GB of DDR5-6400 RAM, Ubuntu Server 25.04 on Linux 7.0, and the latest versions of JDK 17, 21, 25 and 28ea alongside GraalVM Community and GraalVM JDK builds at 17, 21 and 25. The browser results were produced with Scala.js 1.21.0 targeting ES 2021 with GCC v20220202 optimizations, on an Apple M5 Pro at 3.0GHz with 64GB of LPDDR5X-9600, running macOS and the latest browsers.

One codebase across JVM, Scala.js and Scala Native

The topic tags cover scala-js, scala-native and scala3 alongside jvm and json-library, and the benchmark split between the JVM and the browser confirms at least two of those targets are genuinely supported rather than aspirational. That matters for anyone choosing a serialization library, since a library that only runs on the JVM forces you to keep two JSON stacks in a project that also ships a frontend. The Scala.js side compiles to ES 2021, which tells you what output you get and therefore which browser baseline to target. The Scala Native tag is present in the repository metadata, though the benchmark documentation covers the JVM and the browser rather than Native, so performance claims for that target should be treated as unverified here.

Reading the source before you adopt the dependency

The repository is laid out so you can inspect what you are depending on, and the macro modules are the part to look at first. `jsoniter-scala-macros` holds the code generation, `jsoniter-scala-core` holds the runtime support the generated code calls into, and `jsoniter-scala-benchmark` holds the benchmark harness that produces the published numbers. `jsoniter-scala-examples` is the place to see intended usage, and `jsoniter-scala-next-tests` covers the newer language versions separately from the main test set. There is a `.jvmopts` file at the root, which is the kind of detail that tells you the build expects specific JVM settings to run its own tests. The project is on Maven Central, with the artifact path shown in the release badge as com/github/plokhotnyuk/jsoniter-scala/, and the badge tracks version 2.41.6, which matches the newest published release in the record. The readme links a How to use section, and the surrounding chapters cover goals, features and limitations, known issues and how to develop, so the usage guidance lives in the project documentation rather than in the repository root.

A fast release cadence and an MIT licence

Maintenance is the strongest part of this project's story. The last push was on 2026-10-18, and the recent releases are v2.41.6 on 2026-10-17, v2.41.5 on 2026-10-12 and v2.41.4 on 2026-10-10, so the patch line moves several times a month. For a library that generates code into your build, that cadence has an upside and a downside: you get fixes quickly, and you also get to re-run your builds often. The repository carries a Scala Steward badge, which indicates the dependency updates of the project itself are handled automatically, and there is a Gitter chat badge for questions. The licence is MIT, which places no obligations on a company shipping the library in a closed-source product beyond keeping the notice, and that is a different position from libraries under copyleft. The default branch is master rather than main.

Editorial conclusion

jsoniter-scala fits a Scala team whose serialization sits on a hot path and whose data types are case classes, since a macro-generated codec removes the reflection and the hand written parser from the profile. It is the wrong choice if your models are irregular enough that a derivation macro cannot express them, or if you would rather not accept a library whose internal number handling is this specialised. Before adopting it, run the project's own benchmark suite on your hardware rather than relying on the published numbers, which come from a specific CPU and JVM combination.

Frequently asked questions

What does jsoniter-scala do that a plain JSON library does not?

It uses Scala macros to generate JSON parsers and serializers at compile time from your case classes, so the codec is ordinary compiled code rather than a runtime lookup. It also ships a booster that swaps the codec underneath an existing circe setup.

Which platforms does jsoniter-scala support?

The repository topics cover the JVM, Scala.js and Scala Native, and the published benchmarks cover both the JVM and the browser, where the Scala.js build targets ES 2021 using Scala.js 1.21.0.

Which JSON libraries does the project benchmark against?

On the JVM the comparison set includes borer, circe, circe with the jsoniter-scala booster, fory-json-scala, jackson-module-scala, json4s-jackson, json4s-native, play-json, the play-json booster, smithy4s-json, spray-json, uPickle, weePickle, zio-blocks, zio-json and zio-schema-json.

How are fast number parsing and printing implemented?

The library credits XJB, based on the Schubfach algorithm, for serializing doubles and floats, rust-lexical for parsing them precisely, big-math for BigInt and BigDecimal parsing at O(n^1.5) rather than Java's O(n^2), and James Anhalt's algorithm for printing integers into decimal strings.

What licence is jsoniter-scala released under?

MIT. The project publishes to Maven Central, the current release badge shows version 2.41.6, and the last push was on 2026-10-18 with three releases in the preceding week.

Official sources

  1. Issues
  2. License: MIT
  3. plokhotnyuk/jsoniter-scala on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/plokhotnyuk-jsoniter-scala.svg)](https://hysenlabs.com/projects/plokhotnyuk-jsoniter-scala)

Was this useful?