GenSON infers a JSON Schema from your objects and merges the results
GenSON is a powerful, user-friendly JSON Schema generator built in Python.
At a glance
- What is it?
- GenSON is a Python library that takes JSON objects and JSON Schemas and produces a single schema describing them, with merging as its distinguishing feature. It works in one direction only, inference, and it deliberately uses a small subset of JSON Schema keywords, so it fits teams that want a starting schema rather than a guarantee.
- Who is it for?
- Adopt GenSON when you have a pile of sample documents, or documents plus partial schemas, and need one schema that covers them, because merging is the capability the library exists for and the CLI can do it straight from files or stdin. Do not adopt it as a validator or as a full JSON Schema implementation: there is no schema validation, $ref and id are unsupported, and the keyword set is deliberately small.
- 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 109 days ago.
- What is it written in?
- Mainly Python, 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
Merging is the feature, not inference alone
Several libraries can infer a schema from a JSON document. What the GenSON documentation claims as its distinguishing trait is the ability to merge. The core function is to take JSON objects and generate schemas that describe them, and the library was originally built to describe the common structure of a large number of JSON objects, so it uses that merging ability to generate a single schema from any number of JSON objects and schemas. In practice that means the interesting input is not one document but a corpus: a set of API responses, a directory of exported records, a set of schemas that were written by different teams and never reconciled. The library treats those as inputs to be combined rather than as files to be compared, which is why the class is called SchemaBuilder and why it can be fed both objects and schemas.
Three guiding rules, and the exception that breaks them
The behaviour of the builder is defined by three rules. Every object it is given must validate under the generated schema. Any object that is valid under any schema it is given must also validate under the generated schema. And the generated schema should be as strict as possible given the first two rules. The documentation is candid that there are gotchas it does not always resolve the way you would want. The most visible one is that inputs of the same broad type always merge into a single schema: two object inputs become one object schema holding the union of their properties, never an anyOf of the two. anyOf appears only when the structures are fundamentally different, such as an object and an array. The escape hatch is documented too. If you want alternatives kept separate, generate a schema per shape with separate builders and combine them yourself using {"anyOf": [...]}, and the library describes itself as extensible so that you can make a different choice in many of these cases.
A small keyword vocabulary, on purpose
GenSON is compatible with JSON Schema Draft 6 and above, but it uses only a subset of the specification. The reason given is deliberate: the library does not know the specifics of your data model and tries to avoid guessing them, so its purpose is to generate basic structure and let you fill in the details. The keywords it deals with are $schema, type, items, properties, patternProperties, required, anyOf, and enum, where enum only appears when a seed schema is used. Two consequences follow. The limited vocabulary can cause GenSON to violate its own first two rules, and if you feed it schemas with advanced keywords it passes them on blindly to the final schema. $ref and id are not supported, so linked nodes are never dereferenced during construction. The documentation is also slightly inconsistent about the version floor: one part states Draft 6 and above while the command line help text describes compatibility with Draft 4 and above.
The builder accumulates input, then serialises
SchemaBuilder is the basic generator class, and instances can be loaded up with existing schemas and objects before being serialized. The API surface described in the documentation is small. The constructor takes an optional schema_uri, which becomes the value of the $schema keyword, and defaults to the value of the first available $schema keyword on an added schema, or else to http://json-schema.org/schema#. Passing False or None leaves the keyword out. add_schema accepts a dict or another SchemaBuilder and merges it in. add_object adds a JSON object for inference. to_schema returns the schema as a Python dict and to_json returns it as a JSON string, with an indent argument. A short session looks like this:
>>> from genson import SchemaBuilder
>>> builder = SchemaBuilder()
>>> # Add some objects to infer their schema.
>>> builder.add_object({"hi": "there"})
>>> builder.add_object({"hi": 5})Merging a schema into the same builder widens the accepted types:
>>> builder.add_schema({
"type": "object",
"properties": {
"hi": {"type": "boolean"}
}
})One warning is attached to add_schema and it deserves emphasis: there is no schema validation, so if you pass in a bad schema you might get back a bad schema. The builder is a transformer, not a checker.
The genson executable reads files, stdin or existing schemas
The package ships a genson executable that exposes the same functionality from a shell, and its own help text describes it as generating one unified JSON Schema from one or more JSON objects and schemas. Positional arguments are files containing JSON objects, and they default to stdin when no arguments are passed, which makes the tool easy to chain. The option set is what you would expect from a filter. A delimiter can be set when the input files contain multiple JSON objects, and if it is omitted the parser tries to auto-detect boundaries. An encoding can be given instead of the system default. The output can be pretty-printed with an indent width. Schemas can be supplied as files to merge, and the option can be given more than once. Finally the $schema keyword value can be overridden, and passing NULL there removes the keyword from the result entirely.
$ genson --helpThat help output also records the draft compatibility wording that differs from the prose documentation, which is worth checking against the version you install if draft level matters to your validators.
Where GenSON is the wrong tool
Three cases stand out. First, if your goal is to produce JSON rather than to describe it, this is the wrong library. The documentation says so directly: GenSON is not the Python equivalent of the Java Genson library, and anyone coming from Java who needs to create JSON objects in Python should use Python's builtin json library. Second, if your documents reference shared definitions through $ref or id, the library will not dereference those linked nodes, and the blind pass-through of advanced keywords means the output may not behave the way your validator expects. Third, if you need the generated schema to be as strict as possible, be aware that the strictness rule yields to the two validity rules, that the same broad type always merges rather than staying as alternatives, and that no schema validation happens along the way. The last case is the one people hit in practice: a schema that accepts too much is a normal outcome here, not a bug.
MIT licensed, with a release process that predates modern tooling
The project is MIT licensed, and the repository root carries a LICENSE file alongside AUTHORS.rst, HISTORY.rst and a RELEASING.md that describes how a release is cut. There are no GitHub releases, so the version history lives in HISTORY.rst rather than in tags, and the repository is not archived. The last push was on 2026-07-06, which means the code you install is not necessarily the newest published version, so read HISTORY.rst before assuming you have the latest behaviour. Packaging is still setuptools based. There is a setup.py that calls setuptools.setup(), a setup.cfg, and a pyproject.toml that only declares the build system with setuptools>=44 and wheel. Tests are driven through tox.ini, and the source lives in a genson/ directory with a test/ directory beside it. For a library with a stable, narrow purpose that is a reasonable amount of infrastructure, but it is not a project that has been modernised recently.
Editorial conclusion
Adopt GenSON when you have a pile of sample documents, or documents plus partial schemas, and need one schema that covers them, because merging is the capability the library exists for and the CLI can do it straight from files or stdin. Do not adopt it as a validator or as a full JSON Schema implementation: there is no schema validation, $ref and id are unsupported, and the keyword set is deliberately small. Verify first that your inputs do not rely on advanced keywords, decide how you want same-shaped alternatives handled since GenSON merges them into one object schema, and check the version you install against the draft compatibility the documentation and the CLI help text each describe.
Frequently asked questions
How do I install GenSON and generate a schema from JSON files?
Install the package with pip install genson, then run the genson executable with one or more file names containing JSON objects, or pipe JSON into it on stdin when no arguments are given. Use the schema option more than once to merge existing schema files into the result.
How do I keep two different object shapes as alternatives in GenSON?
GenSON merges inputs of the same broad type into a single object schema with the union of their properties, and only reaches for anyOf when the structures are fundamentally different. To keep alternatives separate, generate a schema per shape with separate builders and combine them yourself with {"anyOf": [...]}.
Does GenSON validate the schemas I give it?
No. The documentation states there is no schema validation, and warns that if you pass in a bad schema you might get back a bad schema. Advanced keywords are passed through blindly rather than being interpreted.
Which JSON Schema keywords does GenSON support?
The documented set is $schema, type, items, properties, patternProperties, required, anyOf, and enum, where enum only appears when a seed schema is used. $ref and id are not supported, so linked nodes are not dereferenced while building a schema.
How do I get a JSON Schema string with indentation from the Python API?
Call to_json on the SchemaBuilder and pass an indent value, for example print(builder.to_json(indent=2)). The to_schema method returns the same schema as a Python dict instead of a string.
Official sources
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.
[](https://hysenlabs.com/projects/wolverdude-genson)Was this useful?