{"id":22324635,"url":"https://github.com/pwall567/kjson","last_synced_at":"2025-08-01T04:33:56.640Z","repository":{"id":57735724,"uuid":"389599808","full_name":"pwall567/kjson","owner":"pwall567","description":"Reflection-based JSON serialization and deserialization for Kotlin","archived":false,"fork":false,"pushed_at":"2025-06-09T15:26:30.000Z","size":523,"stargazers_count":9,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-07-29T17:35:00.340Z","etag":null,"topics":["json","kotlin"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pwall567.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2021-07-26T10:50:28.000Z","updated_at":"2025-06-09T15:26:03.000Z","dependencies_parsed_at":"2024-09-07T02:31:55.570Z","dependency_job_id":"f4f5d3ab-29a1-45e3-bb85-4fbc17d0806f","html_url":"https://github.com/pwall567/kjson","commit_stats":null,"previous_names":[],"tags_count":54,"template":false,"template_full_name":null,"purl":"pkg:github/pwall567/kjson","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pwall567%2Fkjson","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pwall567%2Fkjson/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pwall567%2Fkjson/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pwall567%2Fkjson/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pwall567","download_url":"https://codeload.github.com/pwall567/kjson/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pwall567%2Fkjson/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268171053,"owners_count":24207407,"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","status":"online","status_checked_at":"2025-08-01T02:00:08.611Z","response_time":67,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["json","kotlin"],"created_at":"2024-12-04T02:08:00.722Z","updated_at":"2025-08-01T04:33:56.611Z","avatar_url":"https://github.com/pwall567.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# kjson\n\n[![Build Status](https://github.com/pwall567/kjson/actions/workflows/build.yml/badge.svg)](https://github.com/pwall567/kjson/actions/workflows/build.yml)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Kotlin](https://img.shields.io/static/v1?label=Kotlin\u0026message=v2.0.21\u0026color=7f52ff\u0026logo=kotlin\u0026logoColor=7f52ff)](https://github.com/JetBrains/kotlin/releases/tag/v2.0.21)\n[![Maven Central](https://img.shields.io/maven-central/v/io.kjson/kjson?label=Maven%20Central)](https://central.sonatype.com/artifact/io.kjson/kjson)\n\nReflection-based JSON serialization and deserialization for Kotlin.\n\nThis library is an evolution of the [`json-kotlin`](https://github.com/pwall567/json-kotlin) library.\nUsers of that library should find the transition relatively painless \u0026ndash; in most cases just a change to the\ndependency specifications and the `import` statements.\n\nThis document provides introductory information on the `kjson` library; fuller information is available in the\n[User Guide](USERGUIDE.md).\n\n**IMPORTANT:**\nVersion 5.0 introduced changes to the API for deserialization which may be breaking changes for some users (and version\n6.0 included further changes of a similar nature).\nThis document describes the API for version 6.0 and subsequent versions; see [`kjson` 6](KJSON6.md) for further details,\nincluding the reasons behind the changes.\n\nAlso, version 7.0 introduced changes to custom serialization and deserialization; see the\n[Custom Serialization and Deserialization](CUSTOM.md) guide for more information.\n\nVersion 8.0 is the result of a major restructuring of the library, primarily for performance reasons (and version 9.0\nadds further changes along the same lines).\nSee [`kjson` 8](KJSON8.md) for more information.\n\n## Background\n\nThis library provides JSON serialization and deserialization functionality for Kotlin.\nIt uses Kotlin reflection to serialize and deserialize arbitrary objects, and it includes code to handle most of the\nKotlin standard library classes.\n\nWhen instantiating deserialized objects it does not require the class to have a no-argument constructor, and unlike some\nJSON libraries it does not use the `sun.misc.Unsafe` class to force instantiation (which bypasses constructor validity\nand consistency checks).\n\n**New in Version 3.0** \u0026ndash; the library now supports non-blocking output.\nThe `JSONCoStringify` object and the `coStringifyJSON` function allow the full functionality of the library to be used\nin a coroutine setting.\n\n## Supported Classes\n\nSupport is included for the following standard Kotlin classes:\n\n- `String`, `StringBuilder`, `CharSequence`, `Char`, `CharArray`\n- `Int`, `Long`, `Short`, `Byte`, `Double`, `Float`, `UInt`, `ULong`, `UShort`, `UByte`\n- `Array`, `IntArray`, `LongArray`, `ShortArray`, `ByteArray`, `DoubleArray`, `FloatArray`\n- `Boolean`, `BooleanArray`\n- `Collection`, `List`, `ArrayList`, `LinkedList`, `Set`, `HashSet`, `LinkedHashSet`, `Sequence`\n- `Map`, `HashMap`, `LinkedHashMap`\n- `Pair`, `Triple`\n- `Enum`\n- `Duration`\n- `Channel`, `Flow` (from version 3.0 on; output using `coStringifyJSON()` or `JSONCoStringify` only)\n\nAlso, support is included for the following standard Java classes:\n\n- `java.math.BigDecimal`, `java.math.BigInteger`\n- `java.net.URI`, `java.net.URL`\n- `java.util.Enumeration`, `java.util.Bitset`, `java.util.UUID`, `java.util.Date`, `java.util.Calendar`\n- `java.sql.Date`, `java.sql.Time`, `java.sql.Timestamp`\n- `java.time.Instant`, `java.time.LocalDate`, `java.time.LocalTime`, `java.time.LocalDateTime`,\n  `java.time.OffsetTime`, `java.time.OffsetDateTime`, `java.time.ZonedDateTime`, `java.time.Year`,\n  `java.time.YearMonth`, `java.time.MonthDay`, `java.time.Duration`, `java.time.Period`\n- `java.util.stream.Stream`, `java.util.stream.IntStream`, `java.util.stream.LongStream`,\n  `java.util.stream.DoubleStream`\n\n## Quick Start\n\n### Serialization\n\nTo serialize any object (say, a `data class`):\n```kotlin\n    val json = dataClassInstance.stringifyJSON()\n```\nThe result `json` is a `String` serialized from the object, recursively serializing any nested objects, collections\netc.\nThe JSON object will contain serialized forms of all of the properties of the object (as declared in `val` and `var`\nstatements).\n\nFor example, given the class:\n```kotlin\n    data class Example(val abc: String, val def: Int, val ghi: List\u003cString\u003e)\n```\nand the instantiation:\n```kotlin\n    val example = Example(\"hello\", 12345, listOf(\"A\", \"B\"))\n```\nthen\n```kotlin\n    val jsonString = example.stringifyJSON()\n```\nwill yield:\n```json\n{\"abc\":\"hello\",\"def\":12345,\"ghi\":[\"A\",\"B\"]}\n```\n\nAnd starting with version 3.0 of this library, any object may be output to a non-blocking destination:\n```kotlin\n    example.coStringifyJSON { ch -\u003e nonBlockingFunction(ch) }\n```\n\n### Deserialization\n\nDeserialization is slightly more complicated, because the target data type must be specified to the function.\nThis can be achieved in a number of ways (the following examples assume `jsonString` is a `String` containing JSON):\n\nThe type can be inferred from the context:\n```kotlin\n    val example: Example = jsonString.parseJSON()\n```\n\nThe type may be specified as a type parameter:\n```kotlin\n    val example = jsonString.parseJSON\u003cExample\u003e()\n```\n\nThe type may be specified as a `KClass` (because this form does not convey nullability, the result `example` will be of\ntype `Example?`):\n```kotlin\n    val example = jsonString.parseJSON(Example::class)\n```\n\nThe type may be specified as a `KType`:\n```kotlin\n    val example = jsonString.parseJSON(Example::class.starProjectedType) as Example\n```\n(This form is generally only needed when deserializing parameterized types where the parameter types can not be\ninferred; the `as` expression is needed because `KType` does not convey inferred type information.)\n\n## Sealed Classes\n\nThe library includes special handling for Kotlin sealed classes.\nSee the [User Guide](USERGUIDE.md#sealed-classes) for more details.\n\n## Customization\n\n### Annotations\n\n#### Change the name used for a property\n\nWhen serializing or deserializing a Kotlin object, the property name discovered by reflection will be used as the name\nin the JSON object.\nAn alternative name may be specified if required, by the use of the `@JSONName` annotation:\n```kotlin\n    data class Example(val abc: String, @JSONName(\"xyz\") val def: Int)\n```\n\n#### Ignore a property on serialization\n\nIf it is not necessary (or desirable) to output a particular field, the `@JSONIgnore` annotation may be used to prevent\nserialization:\n```kotlin\n    data class Example(val abc: String, @JSONIgnore val def: Int)\n```\n\n#### Include properties when null\n\nIf a property is `null`, the default behaviour when serializing is to omit the property from the output object.\nIf this behaviour is not desired, the property may be annotated with the `@JSONIncludeIfNull` annotation to indicate\nthat it is to be included even if `null`:\n```kotlin\n    data class Example(@JSONIncludeIfNull val abc: String?, val def: Int)\n```\n\nTo indicate that all properties in a class are to be included in the output even if null, the\n`@JSONIncludeAllProperties` may be used on the class:\n```kotlin\n    @JSONIncludeAllProperties\n    data class Example(val abc: String?, val def: Int)\n```\n\nAnd to specify that all properties in all classes are to be output if null, the `includeNulls` flag may be set in the\n`JSONConfig`:\n```kotlin\n    val config = JSONConfig {\n        includeNulls = true\n    }\n    val json = example.stringifyJSON(config)\n```\n\n#### Allow extra properties in a class to be ignored\n\nThe default behaviour when extra properties are found during deserialization is to throw an exception.\nTo allow (and ignore) any extra properties, the `@JSONAllowExtra` annotation may be added to the class:\n```kotlin\n    @JSONAllowExtra\n    data class Example(val abc: String, val def: Int)\n```\n\nTo allow (and ignore) extra properties throughout the deserialization process, the `allowExtra` flag may be set in the\n`JSONConfig`:\n```kotlin\n    val config = JSONConfig {\n        allowExtra = true\n    }\n    val example = jsonString.parseJSON\u003cExample\u003e(config)\n```\n\n#### Using existing tags from other software\n\nIf you have classes that already contain annotations for the above purposes, you can tell `kjson` to use those\nannotations by specifying them in a `JSONConfig`:\n```kotlin\n    val config = JSONConfig {\n        addNameAnnotation(MyName::class, \"name\")\n        addIgnoreAnnotation(MyIgnore::class)\n        addIncludeIfNullAnnotation(MyIncludeIfNull::class)\n        addIncludeAllPropertiesAnnotation(MyIncludeAllProperties::class)\n        addAllowExtraPropertiesAnnotation(MyAllowExtraProperties::class)\n    }\n    val json = example.stringifyJSON(config)\n```\n\nThe `JSONConfig` may be supplied as an optional final argument on most `kjson` function calls (see the\n[User Guide](USERGUIDE.md) or the KDoc or source for more details).\n\n### Custom Serialization\n\nThe `JSONConfig` is also used to specify custom serialization:\n```kotlin\n    val config = JSONConfig {\n        toJSON\u003cExample\u003e { obj -\u003e\n            obj?.let {\n                JSONObject.build {\n                    add(\"custom1\", it.abc)\n                    add(\"custom2\", it.def)\n                }\n            }\n        }\n    }\n```\nOr deserialization:\n```kotlin\n    val config = JSONConfig {\n        fromJSON { json -\u003e\n            require(json is JSONObject) { \"Must be JSONObject\" }\n            Example(json[\"custom1\"].asInt, json[\"custom2\"].asInt)\n        }\n    }\n```\n\nThe `toJSON` function must supply a lambda with the signature `(Any?) -\u003e JSONValue?` and the `fromJSON` function must\nsupply a lambda with the signature `(JSONValue?) -\u003e Any?`.\n`JSONValue` is the interface implemented by each node in the [`kjson-core`](https://github.com/pwall567/kjson-core)\nlibrary (see below).\n\nBoth `toJSON` and `fromJSON` may be specified repeatedly in the same `JSONConfig` to cover multiple classes.\n\n## More Detail\n\nThe deserialization functions operate as a two-stage process.\nThe JSON string is first parsed into an internal form using the [`kjson-core`](https://github.com/pwall567/kjson-core)\nlibrary; the resulting tree of `JSONValue` objects is then traversed to create the desired classes.\n\nIt is possible to perform serialization using the same two-stage approach, but it is generally more convenient to use\nthe `JSONStringify` functions to stringify direct to a string, or, if the `appendJSON()` function is used, to any form\nof `Appendable` including the various `Writer` classes.\nAs always, the KDoc, the source or the unit test classes provide more information.\n\nThis information is of significance when custom serialization and deserialization are required.\nRegardless of whether the `JSONStringify` functions are used to output directly to a string, if custom serialization is\nused it is still required to create the internal `JSONValue`-based form.\nThis ensures that errant serialization functions don\u0026rsquo;t disrupt the remainder of the JSON, for example by omitting\na trailing quote or bracket character.\n\nSee the [Custom Serialization and Deserialization](CUSTOM.md) guide for more information.\n\n## Dependency Specification\n\nThe latest version of the library is 9.9, and it may be obtained from the Maven Central repository.\n\n### Maven\n```xml\n    \u003cdependency\u003e\n      \u003cgroupId\u003eio.kjson\u003c/groupId\u003e\n      \u003cartifactId\u003ekjson\u003c/artifactId\u003e\n      \u003cversion\u003e9.9\u003c/version\u003e\n    \u003c/dependency\u003e\n```\n### Gradle\n```groovy\n    implementation 'io.kjson:kjson:9.9'\n```\n### Gradle (kts)\n```kotlin\n    implementation(\"io.kjson:kjson:9.9\")\n```\n\nPeter Wall\n\n2025-06-10\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpwall567%2Fkjson","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpwall567%2Fkjson","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpwall567%2Fkjson/lists"}