{"id":13801558,"url":"https://github.com/gzoller/ScalaJack","last_synced_at":"2025-05-13T11:31:26.245Z","repository":{"id":8996239,"uuid":"10746383","full_name":"gzoller/ScalaJack","owner":"gzoller","description":"Fast JSON parser/generator for Scala","archived":false,"fork":false,"pushed_at":"2025-05-07T04:17:42.000Z","size":3765,"stargazers_count":113,"open_issues_count":1,"forks_count":9,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-05-07T05:23:54.868Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gzoller.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2013-06-17T20:20:56.000Z","updated_at":"2025-04-28T01:09:58.000Z","dependencies_parsed_at":"2023-10-23T06:25:42.761Z","dependency_job_id":"4612b258-a228-4330-aab3-d37ab7406b38","html_url":"https://github.com/gzoller/ScalaJack","commit_stats":null,"previous_names":[],"tags_count":55,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gzoller%2FScalaJack","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gzoller%2FScalaJack/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gzoller%2FScalaJack/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gzoller%2FScalaJack/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gzoller","download_url":"https://codeload.github.com/gzoller/ScalaJack/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253932891,"owners_count":21986473,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-04T00:01:24.341Z","updated_at":"2025-05-13T11:31:26.236Z","avatar_url":"https://github.com/gzoller.png","language":"Scala","funding_links":[],"categories":["Table of Contents","JSON"],"sub_categories":["JSON"],"readme":"# ScalaJack\n\n[![license](https://img.shields.io/github/license/mashape/apistatus.svg?maxAge=86400)](https://opensource.org/licenses/MIT)\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/co.blocke/scalajack_3/badge.svg)](https://search.maven.org/artifact/co.blocke/scalajack_3/8.0.0/jar)\n[![Coverage Status](https://coveralls.io/repos/github/gzoller/ScalaJack/badge.svg?branch=master)](https://coveralls.io/github/gzoller/ScalaJack?branch=master)\n\nScalaJack 8 is an all-new ScalaJack serializer implemenation built on Scala 3. For Scala 2.13 ScalaJack, please use the frozen version 6.2.0. ScalaJack 8 is built \nusing Scala 3.5.2 on JDK 21 LTS version. This is done to be as current as possible and also because Scala 3.5.2 provides improvements to code test coverage instrumentation.\n\nScalaJack is a very fast, seamless serialization engine for non-schema data designed to require a bare minimum of extra code \nto serialize a class. ScalaJack currently only supports JSON, however when we looked at adding MsgPack support to our great surprise benchmarks\nshowed that MsgPack serialization had about 25% slower write performance and 45% slower read performance than JSON, so we're sticking with JSON for the time being.\n\n## Use\nScalaJack is extremely simple to use.\n\nInclude the following in your build.sbt:\n```\nlibraryDependencies ++= Seq(\"co.blocke\" %% \"scalajack\" % SJ_VERSION)\n```\nNow you're good to go! Let's use ScalaJack in your project to serialize/deserialize a case class object into JSON:\n```scala\n// File1.scala\ncase class Person(name: String, age: Int)\n\n// File2.scala\nimport co.blocke.scalajack.*\n\ngiven sjPerson: ScalaJack[Person] = sjCodecOf[Person] // create a re-usable Person codec\n...\nval inst = Person(\"Mike\",34)\nval js = sjPerson.toJson(inst) // \"\"\"{\"name\":\"Mike\",\"age\":34}\"\"\"\nsjPerson.fromJson(js) // re-constitutes original Person\n```\nCouldn't be simpler!\n\n| **NOTE:** Classes must be defined in a different file from where ScalaJack is called.\n| This is a Scala macro requirement, not a ScalaJack limitation.\n\n### A word about performance...\n\nCompared to pre-8.0 ScalaJack, which used Scala 2.x runtime reflection, ScalaJack is dramatically faster in almost every case. How does this work? ScalaJack 8 uses compile-time macros to generate all the serialization code for you (the codecs). It's very much like writing hand-tooled, field-by-field serialization code yourself, except ScalaJack does it at compile-time.  Wherever you see ```sjCodecOf``` is where the compiler will generate all the serialization code.  **(That also means you should try not to use sjCodecOf more than once for any given class or you'll generate a lot of redundant code!)**\n\n### Easy codecs\nYou only need to worry about generating codecs for your top-most level classes.  Some serialization libraries require all nested classes in an object hierarchy to be \nspecifically called out for codec generation, which can get pretty burdensome.  ScalaJack doesn't require this.  For example:\n\n```scala\ncase class Dog(name: String, numLegs: Int)\ncase class Person(name: String, age: Int, dog: Dog)\n\n// create a re-usable Person codec (includes Dog for free!)\ngiven sjPerson: ScalaJack[Person] = sjCodecOf[Person] \n```\nIn this example, the contained Dog class is automatically detected and genrated by ScalaJack, so if all you care about is Person, and would never serialize a Dog as a top-level value, then Persion is the only codec you need.\n\n### A word about macros...\n\nScalaJack 8 uses Scala 3 macros to the fullest extent possible to do the hard work of reflecting on types. Macros impact the compile/test cycle in ways that are non-intuitive at first. Think of this example:\n\n```scala\n// File1.scala\ncase class Foo(name: String)\n\n// File2.scala\ngiven sjFoo: ScalaJack[Foo] = sjCodecOf[Foo] \nval js = sjFoo.fromJson(someJson)\n```\n\nIn a non-macro program (e.g. something using Scala 2 runtime reflection) let's say you add a new field to class Foo in File1.scala. You naturally expect sbt to re-compile this file, and anything that depends on Foo, and the changes will be picked up in your program, and all will be well.\n\nThat's **not** necessarily what happens with macros! Remember, the macro code is run/expnded at compile-time. File2.scala needs to be re-compiled because the macro that gets expanded at sjCodecOf[Foo] needs to be re-generated to pick up your changes to Foo class in File1.scala. **Unfortunately sbt can't detect this dependency!** If you don't know any better you'll just re-run your program after a change to File1.scala, like normal, and you'll get a spectacular exception with exotic errors that won't mean much to you. The simple, but non-intuitive, solution is you need to also recompile File2.scala.\n\nThis means you will be doing more re-compiling with macro-based code than you would without the macros. It's an unfortunate cost of inconvenience, but the payoff is a *dramatic* gain in speed at runtime, and in the case of reflection in Scala 3, using macros is the only way to accomplish reflection, so there really isn't an alternative.\n\n## Features\n* [Case Classes and Traits](doc/classesAndTraits.md)\n* [Non-Case Classes and Java Class Support](doc/noncase.md)\n* [Re-name Case Class Fields](doc/mapname.md)\n* [Any Support](doc/any.md)\n* [Value Class Support](doc/valueClass.md)\n* [Parameterized Classes](doc/parameterized.md)\n* [Trait Type Hint Customization](doc/typeHint.md)\n* [Null and None treatment](doc/nullAndNone.md)\n* [NeoType Support](doc/neotype.md)\n* [Union type](doc/union.md)\n* [Custom Codecs (overrides)](doc/customCodec.md)\n* [Gimme Speed!](benchmark/README.md)\n\n### Notes:\n\n* 8.1.0 -- New!\n    * Added ability to have user-provided custom codecs\n    * Reduce need for type hints for seal trait classes (set SJConfig.preferTypeHints to force type hints)\n    * Self-references work: case class Person(name: String, age: Int, supervisor: Option[Person])\n    * Write performance tweaks\n* 8.0.3 -- Attempt to fix the frequently-broken CICD pipeline\n* 8.0.2 -- Rebuild on Scala 3.5.2 and support for Maps that preserve insertion order\n* 8.0.0 -- Rebuild on Scala 3.4.2 and deep refactor of ScalaJack 7.0\n* 7.0.3 -- Rebuild on Scala 3.2.1\n* 7.0.1 -- GA release of ScalaJack 7 for Scala 3.\n* 7.0.0-M2 -- Initial release for Scala 3\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgzoller%2FScalaJack","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgzoller%2FScalaJack","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgzoller%2FScalaJack/lists"}