{"id":22750050,"url":"https://github.com/pwall567/json-kotlin-schema-codegen","last_synced_at":"2025-04-06T01:11:08.010Z","repository":{"id":41520461,"uuid":"287935667","full_name":"pwall567/json-kotlin-schema-codegen","owner":"pwall567","description":"Code generation for JSON Schema (Draft 07)","archived":false,"fork":false,"pushed_at":"2025-03-16T03:00:21.000Z","size":784,"stargazers_count":88,"open_issues_count":32,"forks_count":14,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-03-30T00:11:06.170Z","etag":null,"topics":["json-schema","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}},"created_at":"2020-08-16T12:04:08.000Z","updated_at":"2025-03-22T15:53:30.000Z","dependencies_parsed_at":"2024-03-11T01:28:09.996Z","dependency_job_id":"9cd0dd4b-499e-4202-a066-4954f60e41a9","html_url":"https://github.com/pwall567/json-kotlin-schema-codegen","commit_stats":null,"previous_names":[],"tags_count":105,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pwall567%2Fjson-kotlin-schema-codegen","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pwall567%2Fjson-kotlin-schema-codegen/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pwall567%2Fjson-kotlin-schema-codegen/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pwall567%2Fjson-kotlin-schema-codegen/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pwall567","download_url":"https://codeload.github.com/pwall567/json-kotlin-schema-codegen/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247419861,"owners_count":20936012,"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":["json-schema","kotlin"],"created_at":"2024-12-11T04:11:49.564Z","updated_at":"2025-04-06T01:11:07.991Z","avatar_url":"https://github.com/pwall567.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# json-kotlin-schema-codegen\n\n[![Build Status](https://github.com/pwall567/json-kotlin-schema-codegen/actions/workflows/build.yml/badge.svg)](https://github.com/pwall567/json-kotlin-schema-codegen/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/net.pwall.json/json-kotlin-schema-codegen?label=Maven%20Central)](https://central.sonatype.com/artifact/net.pwall.json/json-kotlin-schema-codegen)\n\nCode generation for JSON Schema (Draft 07).\n\n## NEW\n\nNew in version 0.117 \u0026ndash; the code output for `oneOf` groups has changed significantly; see\n[`oneOf` and Polymorphism](#oneof-and-polymorphism).\n\n**NOTE:** \u0026ndash; from version 0.110, the underlying JSON and YAML libraries have been switched from\n[`jsonutil`](https://github.com/pwall567/jsonutil) and [`yaml-simple`](https://github.com/pwall567/yaml-simple) to\n[`kjson-core`](https://github.com/pwall567/kjson-core) and [`kjson-yaml`](https://github.com/pwall567/kjson-yaml).\nThe change should be transparent to most users.\n\nAlso, the Mustache processor has been switched from [`kotlin-mustache`](https://github.com/pwall567/kotlin-mustache) to\n[`mustache-k`](https://github.com/pwall567/mustache-k), but this change will almost certainly not affect any users.\n\nNew in version 0.106 \u0026ndash; the `classNames` configuration option has been extended to allow the configuration of\ngenerated nested class names.\nSee [`classNames`](CONFIG.md#classnames) in the [Configuration Guide](CONFIG.md) for more details.\n\nNew in version 0.105 \u0026ndash; the generator will optionally validate `default` and `examples` entries against the schema\nin which they appear.\nSee the\n[`examplesValidationOption` and `defaultValidationOption`](CONFIG.md#examplesvalidationoption-and-defaultvalidationoption)\nsection in the [Configuration Guide](CONFIG.md).\n\nNew in version 0.100 \u0026ndash; the generator will produce classes that handle `additionalProperties` and\n`patternProperties`.\nSee the [`additionalProperties` and `patternProperties`](PROPERTIES.md) guide for more details.\n\nNew in version 0.87 \u0026ndash; the generator now recognises a special case of `anyOf` or `oneOf` to specify nullability.\nSee [below](#nullability).\n\nNew in version 0.84 \u0026ndash; the generator will now recognise the `not` schema for most validations, and will output\nreversed validation checks.\nFor example, `\"not\": { \"const\": \"error\" }` in a property sub-schema will test that a string is **not** equal to \"error\".\n\nAdded to the code generator \u0026ndash; the ability to configure generation options using a JSON or YAML file.\nSee the documentation at [CONFIG.md](CONFIG.md).\n\nAlso build tool support \u0026ndash; see [below](#build-tool-support).\n\nAlso, the ability to add annotations to generated classes \u0026ndash; see [`annotations`](CONFIG.md#annotations).\n\nAnd from version 0.86 onward, the ability to force the output of a companion object for all or selected classes \u0026ndash;\nsee [`companionObject`](CONFIG.md#companionobject).\n\n## Background\n\n[JSON Schema](https://json-schema.org/) provides a means of describing JSON values \u0026ndash; the properties of an object,\nconstraints on values etc. \u0026ndash; in considerable detail.\nMany APIs now use JSON Schema to specify the content of JSON parameters and response objects, either directly or as part\nof an [OpenAPI](https://www.openapis.org/) specification, and one way of ensuring conformity to the specified schema is\nto generate code directly from the schema itself.\n\nThis is not always possible \u0026ndash; some characteristics described by a schema may not be representable in the\nimplementation language.\nBut for a large subset of schema definitions a viable code representation is achievable, and this library attempts to\nprovide conversions for the broadest possible range of JSON Schema definitions.\n\nThe library uses a template mechanism (employing [Mustache](https://github.com/pwall567/mustache-k) templates), and\ntemplates are provided to generate classes in Kotlin and Java, or interfaces in TypeScript.\n\n## Quick Start\n\nSimply create a `CodeGenerator`, supply it with details like destination directory and package name, and invoke the\ngeneration process:\n```kotlin\n        val codeGenerator = CodeGenerator()\n        codeGenerator.baseDirectoryName = \"output/directory\"\n        codeGenerator.basePackageName = \"com.example\"\n        codeGenerator.generate(File(\"/path/to/example.schema.json\"))\n```\nThe resulting code will be something like this (assuming the schema is the one referred to in the introduction to\n[json-kotlin-schema](https://github.com/pwall567/json-kotlin-schema)):\n```kotlin\npackage com.example\n\nimport java.math.BigDecimal\n\ndata class Test(\n    /** Product identifier */\n    val id: BigDecimal,\n    /** Name of the product */\n    val name: String,\n    val price: BigDecimal,\n    val tags: List\u003cString\u003e? = null,\n    val stock: Stock? = null\n) {\n\n    init {\n        require(price \u003e= cg_dec0) { \"price \u003c minimum 0 - $price\" }\n    }\n\n    data class Stock(\n        val warehouse: BigDecimal? = null,\n        val retail: BigDecimal? = null\n    )\n\n    companion object {\n        private val cg_dec0 = BigDecimal.ZERO\n    }\n\n}\n```\nSome points to note:\n- the generated class is an immutable value object (in Java, getters are generated but not setters)\n- validations in the JSON Schema become initialisation checks in Kotlin\n- nested objects are converted to Kotlin nested classes (or Java static nested classes)\n- fields of type `number` are implemented as `BigDecimal` (there is insufficient information in the schema in this case\nto allow the field to be considered an `Int` or `Long`)\n- non-required fields may be nullable and may be omitted from the constructor (the inclusion of `null` in the `type`\narray will allow a field to be nullable, but not to be omitted from the constructor)\n- a `description` will be converted to a KDoc comment in the generated code if available\n\n## Multiple Files\n\nThe Code Generator can process a single file or multiple files in one invocation.\nThe `generate()` function takes either a `List` or a `vararg` parameter array, and each item may be a file or a\ndirectory.\nIn the latter case all files in the directory with filenames ending `.json` or `.yaml` (or `.yml`) will be processed.\n\nIt is preferable to process multiple files in this way because the code generator can create references to other classes\nthat it knows about \u0026ndash; that is, classes generated in the same run.\nFor example, if a `properties` entry consists of a  `$ref` pointing to a schema that is in the list of files to be\ngenerated, then a reference to an object of that type will be generated (instead of a nested class).\n\n## Clean Code\n\nIt is important to note that the output code will be \u0026ldquo;clean\u0026rdquo; \u0026ndash; that is, it will not contain\nannotations (unless specified in configuration) or other references to external libraries.\nI recommend the use of the [`kjson`](https://github.com/pwall567/kjson) library for JSON serialisation and\ndeserialisation, but the classes generated by this library should be capable of being processed by the library of your\nchoice.\n\nThere is one exception to this \u0026ndash; classes containing properties subject to \u0026ldquo;`format`\u0026rdquo; validations will\nin some cases cause references to the external library [`json-validation`](https://github.com/pwall567/json-validation)\nto be generated, and the latest version of this library must be included in the build of the generated code.\n\nThe format keywords that will lead to the requirement for this library are:\n\n`email`                 \n`hostname`              \n`ipv4`                  \n`ipv6`                  \n`json-pointer`          \n`relative-json-pointer` \n`uri-template`          \n\nThe `idn-email`, `idn-hostname`, `iri` and `iri-reference` format keywords are not currently implemented, and the use of\nthese keywords will have no effect.\n\n## `additionalProperties`\n\nThe default in the JSON Schema specification for `additionalProperties` is `true`, meaning that any additional\nproperties in an object will be accepted without validation.\nMany schema designers will be happy with this default, or will even explicitly specify `true`, so that future extensions\nto the schema will not cause existing uses to have problems.\n\nUnfortunately, for a class to accept properties with names not known in advance requires very much more complex code\nthan for a simple class, so in normal usage the code generator takes the `additionalProperties` setting to be `false`,\neven if it is specified otherwise.\n\nTo specify that the code generator is to interpret the `additionalProperties` keyword strictly as specified (including\ndefaulting to `true`), the configuration option [`additionalPropertiesOption`](CONFIG.md#additionalpropertiesoption)\nmust be set to `strict` (see the [`additionalProperties` and `patternProperties`](PROPERTIES.md) guide for more\ninformation).\n\nMost JSON deserialisation libraries have a means of specifying that additional properties are to be ignored; for the\n[`kjson`](https://github.com/pwall567/kjson) library, the `allowExtra` variable (`Boolean`) in `JSONConfig` must be set\nto `true`.\n\n## `data class`\n\nThe code generator will create a `data class` whenever possible.\nThis has a number of advantages, including the automatic provision of `equals` and `hashCode` functions, keeping the\ngenerated code as concise and readable as possible.\n\nUnfortunately, it is not always possible to use a `data class`.\nWhen the generated code involves inheritance, with one class extending another, the base class will be generated as an\n`open class` and the derived class as a plain `class`.\n\nIn these cases the code generator will supply the missing functions \u0026ndash; `equals`, `hashCode`, `toString`, `copy` and\nthe `component[n]` functions that would otherwise be created automatically for a `data class`. \n\n## Numbers\n\nTo ensure that the full range of values can be accommodated, any property or array item of type `number` or `integer`\nwill be generated as a `java.math.BigDecimal`, unless it includes validations that restrict the range of values to those\nthat will fit in an `Int` or a `Long` (see [Kotlin Multi-Platform (KMP)](#kotlin-multi-platform-kmp) for non-JVM uses), \n\nFor example:\n```yaml\n    month:\n      type: integer\n      minimum: 1\n      maximum: 12\n```\nThis will cause the property `month` to be generated as an `Int`, because the possible range of values will always fit\nin 32 bits.\n\nIt is always good practice to specify `minimum` and `maximum` constraints on `integer` properties to ensure that the\nappropriate form of storage is used.\n\n## Nullability\n\nThe standard way of specifying a value as nullable in JSON Schema is to use the `type` keyword:\n```json\n    { \"type\": [ \"object\", \"null\" ] }\n```\nWhen the code generator encounters a property or array item defined in this way, it will make the generated type\nnullable.\n\nA problem arises when we consider the interaction of this declaration of nullability with the `required` keyword.\nWhat should the generator produce for an object property that does not include `null` as a possible type, but is not in\nthe `required` list?\nThe solution adopted by the code generator is to treat the property as if it had been defined to allow `null`, and this\nseems to work well for the majority of cases, although strictly speaking, it is not an accurate reflection of the\nschema.\n\nIn particular, it helps with the case of utility sub-schema which is included by means of `$ref` in multiple places, in\nsome cases nullable and in some cases not.\nFor example, an invoice may have a billing address and an optional delivery address, both of which follow a common\npattern defined in its own schema.\nThe shared definition will have `\"type\": \"object\"`, but the delivery address will need to be nullable, so generating a\nnullable type for a reference omitted from the `required` list will have the desired effect.\n\nBut this solution does not work for all circumstances.\nFor example, it does not cover the case of an included sub-schema as an array item \u0026ndash; there is no `required` for\narray items.\n\nOne way of specifying such a schema using the full capabilities of JSON Schema is as follows:\n```json\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"billingAddress\": {\n      \"$ref\": \"http://example.com/schema/address\"\n    },\n    \"deliveryAddress\": {\n      \"anyOf\": [\n        { \"$ref\": \"http://example.com/schema/address\" },\n        { \"type\": \"null\" }\n      ]\n    }\n  },\n  \"required\": [ \"billingAddress\", \"deliveryAddress\" ]\n}\n```\nIt is not easy to generate code for the general case of `oneOf` or `anyOf`, but the code generator will detect this\nspecific case to output the `deliveryAddress` as nullable:\n\n1. The `anyOf` or `oneOf` array must have exactly two sub-schema items\n2. One of the items must be just `{ \"type\": \"null\" }`\n3. The `anyOf` or `oneOf` keyword must be the only keyword in the sub-schema that defines the property, other than\n   `default`, or documentary keywords such as `description`.\n\nIn this case, the code generator will generate code for the other sub-schema item (the one that is not\n`{ \"type\": \"null\" }`, often a `$ref`), and treat the result as nullable.\n\n## `oneOf` and Polymorphism\n\nThe `oneOf` keyword is often used to specify a polymorphic group of objects.\nThe following schema describes a `Contact` object, which may be a `PhoneContact` or an `EmailContact`:\n```json\n{\n  \"$schema\": \"http://json-schema.org/draft/2019-09/schema\",\n  \"$id\": \"http://example.com/contact\",\n  \"$defs\": {\n    \"PhoneContact\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"contactType\": {\n          \"type\": \"string\",\n          \"const\": \"PHONE\"\n        },\n        \"localNumber\": {\n          \"type\": \"string\",\n          \"pattern\": \"^[0-9]{2,16}$\"\n        }\n      },\n      \"required\": [ \"contactType\", \"localNumber\" ]\n    },\n    \"EmailContact\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"contactType\": {\n          \"type\": \"string\",\n          \"const\": \"EMAIL\"\n        },\n        \"emailAddress\": {\n          \"type\": \"string\",\n          \"format\": \"email\"\n        }\n      },\n      \"required\": [ \"contactType\", \"emailAddress\" ]\n    }\n  },\n  \"oneOf\": [\n    {\n      \"$ref\": \"#/$defs/PhoneContact\"\n    },\n    {\n      \"$ref\": \"#/$defs/EmailContact\"\n    }\n  ]\n}\n```\n\nIn a case like this, the code generator will generate an interface for the outer schema `Contact`, with each of the two\nclasses `PhoneContact` and `EmailContact` implementing that interface.\n\nA problem arises when there are additional properties in the outer object alongside the `oneOf`, since an interface is\nnot allowed to contain fields.\nIn this case, the implementing classes will have the properties from the outer class added at the start \u0026ndash; this may\nlead to the duplication of some fields but the code is likely to be clearer and easier to work with.\n\nAnyone seeking to make use of `oneOf` may need to experiment with different combinations to find the one that gives the\nbest result.\n\n## Custom Classes\n\n(**NOTE** \u0026ndash; the configuration file may be a simpler way to specify custom classes, particularly when combined with\nother configuration options.  See the [Configuration Guide](CONFIG.md).)\n\nThe code generator can use custom types for properties and array items.\nThis can be valuable when, for example, an organisation has its own custom classes for what are sometimes called\n\"domain primitives\" \u0026ndash; value objects representing a fundamental concept for the functional area.\n\nA common example of a domain primitive is a class to hold a money value, taking a `String` in its constructor and\nstoring the value as either a `Long` of cents or a `BigDecimal`.\n\nThere are three ways of specifying a custom class to the code generator:\n\n1. URI\n1. Custom `format` types\n1. Custom keywords\n\n### URI\n\nAn individual item in a schema may be nominated by the URI of the element itself.\nFor example, in the schema mentioned in the [Quick Start](#quick-start) section there is a field named `price`.\nTo specify that the code generator is to use a `Money` class for this field, use:\n```kotlin\n        codeGenerator.addCustomClassByURI(URI(\"http://pwall.net/test#/properties/price\"), \"com.example.Money\")\n```\nThe base URI can be **either** the URL used to locate the schema file **or** the URI in the `$id` of the schema.\n\nA distinct advantage of this technique is that when a `$ref` is used to share a common definition of a field type, the\ndestination of the `$ref` can be specified to the code generator function shown above, and all references to it will use\nthe nominated class.\nIt is also the least obtrusive approach \u0026ndash; it does not require modification to the schema or non-standard syntax.\n\n### Format\n\nThe JSON Schema specification allows for non-standard `format` types.\nFor example, if the specification of the property in the schema contained `\"format\": \"x-local-money\"`, then the\nfollowing will cause the property to use a custom class:\n```kotlin\n        codeGenerator.addCustomClassByFormat(\"x-local-money\", \"com.example.Money\")\n```\n\n### Custom Keyword\n\nThe JSON Schema specification also allows for completely non-standard keywords.\nFor example, the schema could contain `\"x-local-type\": \"money\"`, in which case the following would invoke the use of the\ncustom class:\n```kotlin\n        codeGenerator.addCustomClassByExtension(\"x-local-type\", \"money\", \"com.example.Money\")\n```\n\n## Kotlin Multi-Platform (KMP)\n\nMost uses of the code generator target the JVM versions of Kotlin (and the code generator itself runs only on the JVM),\nbut with the right configuration it can be used to generate code for any environment.\nThe main areas that require configuration are:\n1. The default classes for strings with `format: date`, `format: time` and `format:date-time` are classes from the JVM\n   `java.time` package (`java.time.LocalDate`, `java.time.OffsetTime` and `java.time.OffsetDateTime` respectively).\n   Schema files using these formats must include [`customClasses`](CONFIG.md#customclasses) configuration, specifying\n   alternative classes (the [`kotlinx-datetime`](https://kotlinlang.org/api/kotlinx-datetime/) library my be suitable,\n   although it does not have exact matches for the JVM classes).\n2. Decimal values use `java.math.BigDecimal` on the JVM, and this can **not** be configured using `customClasses`.\n   Starting from version 0.107, the [`decimalClassName`](CONFIG.md#decimalclassname) configuration setting allows the\n   specification of an alternative class for decimal values.\n\n## JSON Schema Version\n\nThis code generator targets the Draft-07 of the JSON Schema specification, and it includes some features from Draft\n2019-09.\n\nIt also includes support for the `int32` and `int64` format types from the\n[OpenAPI 3.0 Specification](https://swagger.io/specification/).\n\n## API Reference\n\nA `CodeGenerator` object is used to perform the generation.\nIt takes a number of parameters, many of which can be specified either as constructor parameters or by modifying\nvariables in the constructed instance.\n\n### Parameters\n\n- `targetLanguage` \u0026ndash; a `TargetLanguage` `enum` specifying the target language for code generation (the options are\n`KOTLIN`, `JAVA` or `TYPESCRIPT` \u0026ndash; TypeScript coverage is not as advanced as that of the others at this time)\n- `templateName` \u0026ndash; the primary template to use for the generation of a class\n- `enumTemplateName` \u0026ndash; the primary template to use for the generation of an enum\n- `basePackageName` \u0026ndash; the base package name for the generated classes (if directories are supplied to the\n`generate()` function, the subdirectory names are used as sub-package names)\n- `baseDirectoryName` \u0026ndash; the base directory to use for generated output (in line with the Java convention, output\ndirectory structure will follow the package structure)\n- `derivePackageFromStructure` \u0026ndash; a boolean flag (default `true`) to indicate that generated code for schema files\nin subdirectories are to be output to sub-packages following the same structure\n- `generatorComment` \u0026ndash; a comment to add to the header of generated files\n- `markerInterface` \u0026ndash; a \u0026ldquo;marker\u0026rdquo; interface to be added to every class\n\n### Functions\n\n#### `configure()`\n\nThe `configure()` function takes a `File` or `Path` specifying a configuration file.\nSee [CONFIG.md](CONFIG.md) for details of the configuration options.\n\n#### `generate()`\n\nThere are two `generate()` functions, one taking a `List` of `File`s, the other taking a `vararg` list of `File`\narguments.\nAs described above, it is helpful to supply all the schema objects to be generated in a single operation.\n\n#### `generateClass()`, `generateClasses()`\n\nWhile the `generate()` functions take a file or files and convert them to an internal form before generating code, the\n`generateClass()` and `generateClasses()` functions take pre-parsed schema objects.\nThis can be valuable in cases like an OpenAPI file which contains a set of schema definitions embedded in another file.\n\n#### `generateAll()`\n\nThe `generateAll()` function allows the use of a composite file such as an OpenAPI file containing several schema\ndefinitions.\nFor example, an OpenAPI file will typically have a `components` section which contains definitions of the objects input\nto or output from the API.\nUsing the `generateAll()` function, the set of definitions can be selected (and optionally filtered) and the classes\ngenerated for each of them.\n\n## Build Tool Support\n\nTo simplify the use of the code generator in conjunction with the common build tools the following plugins will perform\ncode generation as a pre-pass to the build of a project, allowing classes to be generated and compiled in a single\noperation:\n\n- [`json-kotlin-gradle`](https://github.com/pwall567/json-kotlin-gradle)\n- [`json-kotlin-maven`](https://github.com/pwall567/json-kotlin-maven)\n\n## Dependency Specification\n\nThe latest version of the library is 0.118, and it may be obtained from the Maven Central repository.\n\n### Maven\n```xml\n    \u003cdependency\u003e\n      \u003cgroupId\u003enet.pwall.json\u003c/groupId\u003e\n      \u003cartifactId\u003ejson-kotlin-schema-codegen\u003c/artifactId\u003e\n      \u003cversion\u003e0.118\u003c/version\u003e\n    \u003c/dependency\u003e\n```\n### Gradle\n```groovy\n    implementation 'net.pwall.json:json-kotlin-schema-codegen:0.118'\n```\n### Gradle (kts)\n```kotlin\n    implementation(\"net.pwall.json:json-kotlin-schema-codegen:0.118\")\n```\n\nPeter Wall\n\n2025-03-16\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpwall567%2Fjson-kotlin-schema-codegen","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpwall567%2Fjson-kotlin-schema-codegen","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpwall567%2Fjson-kotlin-schema-codegen/lists"}