com-lihaoyi/upickle
58.1
Adequate · 28 September 2026
13.2k
lines of production code
Scala
with Java
2
measurements over time
What this system is
This system is a high-performance, cross-platform serialization library for Scala that supports JSON and MessagePack formats. It provides automatic derivation of readers and writers for case classes and sealed traits via Scala 2 and 3 macros, alongside fine-grained configuration through annotations. The library features a unified visitor-based architecture for efficient, zero-allocation data traversal and includes adapters for interoperability with Circe, Argonaut, and Json4s ASTs.
How it got here
2014–2018 — Architecture modernization and platform expansion
16 changes.
The project underwent a significant architectural overhaul by introducing ujson and upack modules with a Visitor-based pattern, replacing legacy serialization components and build tools. This period focused on expanding platform support to JavaScript and Scala Native, adding native MessagePack serialization, and integrating adapters for major JSON libraries like Circe and Json4s.
2020–2023 — Scala 3 support and core refactoring
9 changes.
The project underwent a significant core refactoring to support Scala 2.12/2.13+ and introduced a new configuration infrastructure, including a global Config trait and annotation-based serialization controls. This period also saw the implementation of Scala 3-specific macro derivation for automatic type handling, alongside extensive test coverage additions and platform-specific improvements for Scala Native and JVM environments.
2025–2026 — Scala 3 support and JSON Schema generation
5 changes.
This period focused on enhancing uPickle's compatibility with Scala 3 by introducing support for named tuples and a simplified import syntax. It also added a new JSON Schema generation module to automatically derive schema definitions for serialized types, accompanied by comprehensive test coverage for these new features and platform-specific behaviors.
Features
Add Circe JSON AST support
Users can now directly read and write Circe \Json\ ASTs using ujson. A new \CirceJson\ adapter in the \ujson/circe\ module implements the \AstTransformer\ interface, enabling seamless conversion between ujson's internal representation and Circe's data structures for objects, arrays, strings, numbers, and booleans.
ujson/circe, ujson/play · high confidence
Add JSON Schema generation for uPickle types
The \upickle/jsonschema\ module now provides a new \JsonSchema\ trait and macro-based implementation that generates JSON Schema (Draft 2020-12) definitions for Scala types handled by uPickle. This allows users to automatically derive schema documents for case classes, sealed traits (ADTs), enums, tuples, and named tuples, including support for flattened collections, default values, and custom key annotations.
upickle/jsonschema · high confidence
Add JVM benchmark suite for upickle performance testing
The \bench/src-jvm\ module now includes a new \Main.scala\ entry point that runs a comprehensive set of benchmarks for the upickle library. This suite measures performance across various data types (integers, doubles, short/long/unicode strings, case classes, sequences) and serialization formats (default, byte array, binary), allowing users to track and compare the library's encoding and decoding speeds.
bench/src-jvm · high confidence
Add JavaScript-specific JSON parsing and serialization via WebJson
A new \WebJson\ trait is introduced for the Scala.js target, providing \upickle.web.read\ and \upickle.web.write\ methods that bridge upickle with the native browser \JSON\ object. This allows users to parse JSON strings using \js.JSON.parse\ and serialize objects using \js.JSON.stringify\, leveraging the \ujson\ library for the transformation layer.
upickle/src-js · high confidence
Add Scala Native WebJson trait
A new \WebJson\ trait has been added to the Scala Native implementation of uPickle. This trait extends \upickle.core.Types\ and requires the implementing class to extend \upickle.core.Config\, providing a base for web-specific JSON handling in Scala Native environments.
upickle/src-native · high confidence
Add native support for Argonaut and Json4s JSON ASTs
Users can now directly transform ujson values into Argonaut and Json4s ASTs via new \ArgonautJson\ and \Json4sJson\ adapters. The Json4s adapter includes configuration options to control numeric precision, allowing users to choose between \BigDecimal\ for doubles and \BigInt\ for longs.
ujson/json4s · high confidence
Add serialization support for ujson and MessagePack types
New implicit readers and writers are now available for ujson value types (Obj, Arr, Str, Num, Bool, Null) and MessagePack messages (upack.Msg). This allows users to directly serialize and deserialize these specific data structures using the standard upickle API without needing custom adapters.
upickle/src · high confidence
Add support for Scala 3 named tuples
This change introduces a new \upickle.implicits.namedTuples\ module that enables automatic serialization and deserialization of Scala 3 named tuples. By importing the appropriate implicits (e.g., \upickle.implicits.namedTuples.default.given\), users can now read and write named tuples directly to JSON, with support for both the default and legacy upickle configurations. The implementation handles nested named tuples, various primitive types, sequences, and options, and includes a strict mode for validation during reading.
upickle/implicits/named-tuples · high confidence
Added JavaScript and Scala Native benchmark suites
New benchmark entry points have been added for the JavaScript (\bench/src-js/Main.scala\) and Scala Native (\bench/src-native/Main.scala\) targets. These suites execute standard serialization and deserialization performance tests (including upickle default, byte array, and binary modes for integers, doubles, sequences, strings, and case classes) to allow users to compare runtime performance across these platforms.
bench/src-js · high confidence
Added benchmark suite for upickle and comparison libraries
New benchmark files (Common.scala, Micro.scala, NonNative.scala) have been added to the bench/src directory to measure serialization performance. These benchmarks include sample data structures and test upickle's legacy and default APIs for both JSON and binary formats, as well as performance comparisons against external libraries like Circe and Play JSON.
bench/src · high confidence
Introduce upack MessagePack backend
Adds a new \upack\ module providing a complete MessagePack serialization backend for the upickle library. This includes a streaming \MsgPackReader\ and a buffered \MsgPackWriter\ that implement the \Visitor\ interface to read and write MessagePack binary data, along with a \Readable\ trait and package-level API (\read\, \write\, \validate\) to integrate this backend with existing upickle \Msg\ structures.
upack/src · high confidence
New annotation-based configuration for serialization behavior
The upickle implicits module now introduces several annotations to allow fine-grained control over serialization and deserialization. The \@key\ annotation can override field names, customize discriminator keys for sealed traits, or change the discriminator field name itself. The \@serializeDefaults\ and \@allowUnknownKeys\ annotations enable field-level or class-level configuration of default value serialization and unknown key handling, overriding global pickler settings. Additionally, the \@flatten\ annotation allows fields of case classes or specific iterables to be flattened into the parent object's level during serialization, with corresponding unflattening during deserialization.
upickle/implicits · high confidence
Scala 3-specific macro derivation for case classes and sealed hierarchies
This change introduces Scala 3-specific implementation files (MacroImplicits, Readers, Writers, macros) that enable automatic derivation of JSON readers and writers for case classes and sealed traits using Scala 3's \deriving.Mirror\ and quote macros. Users can now use \ReadWriter.derived\ or \Writer.derived\ to automatically generate serialization logic for their types, supporting features like configurable tag names, unknown key handling, and field flattening via annotations.
upickle/implicits/src-3 · high confidence
Removals
Removal of the Picklite JSON serialization library
The shared module has removed the entire Picklite library, including its core serialization components (Implicits, Json, Types, and package definitions) and all associated unit tests (PrimitiveTests, StructTests, TestUtil). This eliminates the ability to serialize and deserialize Scala types such as primitives, collections, tuples, options, and case classes to and from JSON format within this codebase.
shared · high confidence
Architecture
Introduction of ujson and upack modules with Visitor-based architecture
The library introduces dedicated \ujson\ and \upack\ modules, providing in-memory AST representations (\ujson.Value\ and \upack.Msg\) for JSON and MessagePack data respectively. These modules are built on a new \Visitor\ pattern (\upickle.core.Visitor\) that replaces the previous \Walker\/\Facade\ approach, enabling efficient, zero-allocation traversal and transformation of structured data. The \ujson\ module includes a \Readable\ trait for streaming input from various sources (Strings, Files, ByteBuffers) and \Renderer\ classes for output, while \upack\ defines a comprehensive \Msg\ type hierarchy supporting binary data, extended types, and specific integer/float sizes. This architectural shift unifies the internal representation across JSON and MessagePack backends, allowing shared logic in \BufferedValue\ for operations like key sorting and providing a consistent API for reading and writing structured data.
repository · high confidence
Behavioural changes
New macro-based derivation implementation for Scala 2
The \upickle/implicits/src-2\ module now provides a new implementation of the macro-based automatic derivation logic for Scala 2. This change introduces \MacroImplicits\ and \Macros2\ to handle the generation of \Reader\, \Writer\, and \ReadWriter\ instances for case classes and sealed traits. The new implementation supports features such as the \@flatten\ annotation for nested structures, configurable field names via the \@key\ annotation, and proper handling of default values, replacing the previous macro logic to ensure compatibility with Scala 2's macro system.
upickle/implicits/src-2 · high confidence
Platform-specific timeout handling for slow tests
The test suite now uses platform-specific implementations to handle operation timeouts. On the JVM, slow tests are wrapped in a 2-minute timeout using asynchronous execution, while on Scala.js and Scala Native, timeout enforcement is skipped due to platform limitations, allowing operations to run without interruption.
upickle/testSlow · high confidence
Support \`upickle.\*\` import syntax in Scala 3
Scala 3 users can now import the \upickle\ package directly (e.g., \import upickle.\\) as an alternative to the existing \upickle.default.\\ syntax. This change adds a \NonDefaultExport.scala\ file that re-exports all members from the \default\ package, allowing code to reference upickle functionality without the \.default\ qualifier.
upickle/src-3 · high confidence
Update documentation to uPickle 4.4.3
The project documentation has been updated to reflect version 4.4.3, including the addition of experimental JSON Schema support for Scala 3 and the inclusion of example tests for cross-library conversions.
upickleReadme · medium confidence
Upickle core refactored to support Scala 2.12 and 2.13+ with new configuration and parsing infrastructure
The upickle core library has been significantly restructured to introduce a new \Config\ trait that allows global configuration of serialization behaviors, such as the \tagName\ used for sealed trait discrimination, whether to serialize default values, and how to handle unknown keys. To support both Scala 2.12 and 2.13+, the codebase now includes version-specific compatibility shims in \upickle/core/compat\ for collection factories and sorting utilities. Additionally, the parsing engine has been overhauled with new \BufferingInputStreamParser\ and \BufferingElemParser\ traits to improve memory management and support parsing files larger than 2GB by managing buffer indices and offsets. New visitor implementations like \LogVisitor\, \TraceVisitor\, and \NoOpVisitor\ have been added to aid in debugging and validation, while \LinkedHashMap\ is now a custom wrapper around \java.util.LinkedHashMap\ for security and compatibility.
upickle/core · high confidence
ujson library refactored with new parsers, renderers, and WebJson support
The ujson module has been significantly restructured to improve performance and expand platform support. A new \WebJson\ component is introduced for Scala.js, enabling direct transformation between JavaScript objects and ujson values. Parsing capabilities are expanded with dedicated parsers for \String\, \CharSequence\, \ByteBuffer\, \Array\[Byte\]\, and \InputStream\, allowing more flexible input handling. Rendering performance is enhanced by introducing a \BaseElemRenderer\ and specialized \DoubleToDecimal\/\FloatToDecimal\ utilities (vendored from Jackson) for precise floating-point conversion. Additionally, an \AstTransformer\ trait and \JsVisitor\ type are added to streamline AST manipulation and visitor patterns, while a new \utf8.json\ resource file provides test data for Unicode handling.
ujson · high confidence
Test coverage
Added comprehensive test suite for ujson parsing and value handling; Added core unit tests and test infrastructure; Added tests for JSON Schema generation coverage; Added tests for UTF-8 byte handling in JSON and MessagePack readers; Expanded test coverage for MsgPack parsing and serialization; Expanded test coverage for Scala 3 derivation, enums, and platform-specific behaviors.
Dependencies
Migrate build configuration to SBT 1.9.7 and update scalatex plugin
The project build has been migrated from the legacy Scala-based Build.scala definition to the modern SBT structure. The build now uses SBT version 1.9.7 (defined in project/build.properties) and includes the scalatex-sbt-plugin version 0.3.11 (defined in project/plugins.sbt). The previous Build.scala file, which configured cross-compilation for Scala 2.10/2.11, JVM/JS targets, and publishing settings, has been removed.
project · high confidence
Mill build tool upgraded to 1.1.2 with Sonatype Central publishing support
The project's build system has been upgraded to Mill version 1.1.2, as specified in the new \.mill-version\ file and the updated \mill\ launcher script. This update includes the necessary changes to support Sonatype Central publishing syntax, replacing the previous Bintray resolver configuration. The \build.mill\ file has been restructured to use the new Mill 1.x module definitions and includes updated Scala version defaults (2.12.20, 2.13.16, 3.3.7) and dependencies.
(repo-wide) · high confidence
Removed legacy SBT plugins from project build definition
The project has removed the \scalajs-sbt-plugin\ (version 0.4.3) and \utest-js-plugin\ (version 0.1.3) from the \project/build.sbt\ file. This change indicates that the project no longer relies on these specific legacy SBT plugins for its build process, likely having migrated to a different testing or Scala.js configuration method.
(dependencies) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
Score
- CAI 59 → 58 (-1.1)
- Rubric changed (rubric-2026.09.8 → rubric-2026.09.16) — scores are not directly comparable.
Lenses
- Code Health 93 → 92 (-0.4)
- Architecture 98 → 82 (-16.4)
- Maturity 50 → 50 (+0.0)
- Readiness 56 → 56 (+0.0)
- Security 67 → 67 (+0.0)
Resolved (2)
- Documentation: no installation or build instructions (README.md)
- Documentation: no usage examples (README.md)
New (8)
- Duplicated block (10 lines × 2) (ujson/templates-jvm/DoubleToDecimalElem.java)
- Duplicated block (12 lines × 2) (ujson/templates-jvm/DoubleToDecimalElem.java)
- Duplicated block (13 lines × 2) (ujson/templates-jvm/DoubleToDecimalElem.java)
- Duplicated block (15 lines × 2) (ujson/templates-jvm/DoubleToDecimalElem.java)
- Duplicated block (19 lines × 2) (ujson/templates-jvm/DoubleToDecimalElem.java)
- Duplicated block (19 lines × 2) (ujson/templates-jvm/DoubleToDecimalElem.java)
- Duplicated block (9 lines × 2) (ujson/templates-jvm/DoubleToDecimalElem.java)
- Projects may be oversized for their cohesion
Architecture
- Unchanged — 0 containers · 1 contexts · 0 edges
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
com-lihaoyi/upickle was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 28 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 87e0b24b8c811e174ebd680839e4edf1e62abe71 — the exact code this score is about.
- Scored under rubric-2026.09.16 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-2d9048c36d26.