Jane: generating PHP models and API clients from a schema
:seedling: Jane is a set of libraries to generate Models & API Clients based on JSON Schema / OpenAPI specs
At a glance
- What is it?
- Jane is a set of PHP libraries that turn a JSON Schema or an OpenAPI document into model classes and an API client, maintained by JoliCode under the MIT licence. Version 8 arrived in October 2026, and the project now also ships agent skills so a coding assistant can produce the same code you would have written by hand.
- Who is it for?
- Adopt Jane if you work in PHP and consume an API that ships a JSON Schema or OpenAPI document, since the generated client and models will save more work than the generator configuration costs. Do not adopt it for an API with no machine readable description, because the whole tool depends on that document existing, and do not adopt it if your team intends to hand-write the client, since a generated client and a hand-tuned one diverge in ways your tests will have to cover.
- 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 received new commits within the last day.
- What is it written in?
- Mainly PHP, 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
A generator that starts from a machine readable description
Jane is a set of libraries to generate models and API clients based on JSON Schema and OpenAPI specifications. The project is developed by JoliCode, who sponsor it, and the documentation lives at its own site rather than in the repository README, which is deliberately short.
The problem it addresses is the one every API integration runs into. You have a service that publishes an OpenAPI document, and you need PHP classes for the payloads and a client that sends requests and parses responses. Writing those by hand is slow, it goes stale the moment the service changes a field, and the hand-written version quietly diverges from the document. A generator turns the document into code, and the code is regenerated when the document changes.
The JSON Schema side of the story is the other half. A schema describes a payload shape without describing an API, and the same schema might come from a database schema, a config file or a third party event format. Generating models from it gives you typed PHP objects with validation behaviour rather than arrays of mixed values.
The repository topics list psr18 and sdk alongside json-schema, openapi and php, which tells you the shape of the output: an SDK whose HTTP layer follows the PSR-18 request and response interfaces, so the generated client can be used with any PSR-18 implementation rather than being welded to a particular HTTP library.
A monorepo with a documentation site of its own
The repository layout shows a project with several moving parts, and it is worth reading it as a map of the workflow.
There is a src/ directory for the code and a docs/ directory for the documentation source, with mkdocs.yaml at the root configuring the site. The docs are built with MkDocs and a Poetry managed toolchain, and the pyproject.toml in the repository root is for that documentation project rather than for the PHP packages: it declares the name janephp-doc, requires Python 3.11 and later, and pulls in mkdocs, a documentation theme, markdown callouts, the literate nav plugin and mike, which is the tool that publishes versioned documentation. The docs site is therefore versioned, which matches a project on a numbered major version with a compatibility-sensitive audience.
The PHP side is managed with Composer, and castor.php with castor.composer.json and castor.composer.lock is a task runner for the repository's own maintenance commands. A .php-cs-fixer.php config and a phpstan.neon config sit at the root, along with phpunit.xml, so the project lints, analyses and tests its own output with the same tools a consumer would use.
The corpus/ and cache/ directories are the interesting ones for understanding how a generator is tested. The corpus holds fixtures, and there are scripts named generate-manifest-fixtures.php, clear-all-generated-files.sh and replace-all-expected-fixtures.sh. A generator that produces code is only trustworthy if you can regenerate and diff, and that is what a corpus of expected outputs and a script to refresh them is for.
Agent skills for the three jobs Jane does
The most recent addition is a set of agent skills, and the approach is worth describing because it is a different way to ship documentation.
Instead of a tutorial, the project ships instructions that a coding agent can load, and the README gives the three commands:
npx skills add janephp/janephp --skill jane-openapi-sdk # PHP SDK from an OpenAPI spec
npx skills add janephp/janephp --skill jane-json-schema-models # PHP models from a JSON Schema
npx skills add janephp/janephp --skill jane-upgrade # upgrade a Jane 7.x project to 8.xThree skills, three distinct jobs. The first generates a PHP SDK from an OpenAPI specification, the second generates PHP models from a JSON Schema, and the third is a migration path, guiding an existing Jane 7.x project to 8.x. The README frames the audience as coding agents, naming Claude Code, OpenCode, Codex and Cursor.
The upgrade skill is the one that tells you the most about how this project is used. A generator with a major version boundary is only useful if there is a supported way across that boundary, and a skill that walks an agent through the upgrade is effectively an automated migration guide that runs in the tool the developer already has open. The skills/ directory at the repository root holds them, alongside an AGENTS.md file for the repository's own agent instructions.
The split into two generation skills rather than one also reflects the two halves of the project, which matters when you are deciding whether to adopt Jane at all. A team that only needs typed models for a payload format does not need the OpenAPI SDK, and the smaller dependency is the better one.
Version 8 and what a major release costs a consumer
The release history is short and current. v8.0.0 was published on 2026-10-01, v8.0.1 on 2026-10-06, and v7.14.4 on 2026-09-26, which puts the 8.0 release days after the last 7.x release rather than months after it.
The default branch is next, which tells you something about the project's rhythm: development happens on next, and the released versions are cut from it. The changes are recorded in a CHANGELOG.md in the repository root, and the README points at it directly rather than summarising the release notes, so the detail is in the repository rather than in a release page.
A major version for a code generator is not like a major version for a library, because the output changes. The generated classes, the constructor signatures, the trait and method names, the namespace layout: a consumer's application code calls those generated names, so a major version is a coordinated rewrite of the call sites. That is exactly why the jane-upgrade skill exists, and it is the cost you should weigh before upgrading rather than after.
The licence is MIT and the project is hosted under the janephp organisation, with the packagist namespace shown in the README badges as jane-php, including a json-schema-runtime package in that namespace. The PHP version requirement is surfaced as a badge rather than in the README text, so check the packagist entry for the exact constraint before you plan an upgrade.
Where a generator is the wrong answer
The first limitation is obvious and worth stating plainly: Jane needs a JSON Schema or an OpenAPI document. If the service you integrate with ships neither, there is nothing to generate from, and the tool is not an option. In that situation the realistic options are to ask the provider for a document, to write a hand-rolled client, or to use a dynamic client that works from a runtime description.
The second limitation is the generated-code quality question. A generator produces code that is consistent, which is its main virtue, but consistent is not the same as idiomatic for your codebase. The generated namespace layout, the way optional fields are represented, whether value objects exist for nested structures, how enums are modelled: these are decisions the generator makes once, for everyone, and your team may want them different. The repository answers part of this by shipping php-cs-fixer, phpstan and phpunit configurations, so the output can be formatted and analysed, but the shape of the API is still the generator's choice.
The third limitation is the regeneration loop. Generated code in version control is fine as long as it is regenerated on every spec change, and that discipline is what keeps it useful. Teams that let generated files drift, or that hand-edit them because the generator cannot express something, end up with a codebase where the generator is not the source of truth anymore and the whole benefit is gone. The corpus of expected fixtures and the refresh scripts are aimed squarely at that problem.
The real alternative, and the one most teams should compare against, is writing the client by hand for a small API. A hand-written client against an HTTP interface that follows PSR-18 is not much code, it fits your conventions exactly, and it has no generation step in your build. Jane pays for itself when the API is large, has many endpoints, or has a spec that is guaranteed to stay current. For three endpoints, the generator is a dependency and a build step in exchange for very little.
Editorial conclusion
Adopt Jane if you work in PHP and consume an API that ships a JSON Schema or OpenAPI document, since the generated client and models will save more work than the generator configuration costs. Do not adopt it for an API with no machine readable description, because the whole tool depends on that document existing, and do not adopt it if your team intends to hand-write the client, since a generated client and a hand-tuned one diverge in ways your tests will have to cover. Before you commit, check the generated code against your coding standards, since the repository carries php-cs-fixer, phpstan and phpunit configurations for exactly that purpose, and read the v8 changelog if you are upgrading from a 7.x project rather than starting fresh.
Frequently asked questions
What is Jane?
Jane is a set of PHP libraries to generate models and API clients based on JSON Schema and OpenAPI specifications, developed by JoliCode under the MIT licence. The repository topics include psr18 and sdk, and the packagist namespace is jane-php.
How do I install the Jane agent skills?
The README lists three commands: npx skills add janephp/janephp --skill jane-openapi-sdk, npx skills add janephp/janephp --skill jane-json-schema-models, and npx skills add janephp/janephp --skill jane-upgrade, which upgrades a Jane 7.x project to 8.x. The skills teach a coding agent to build PHP clients and models with Jane.
What is the difference between Jane's OpenAPI and JSON Schema skills?
The jane-openapi-sdk skill generates a PHP SDK from an OpenAPI specification, while the jane-json-schema-models skill generates PHP models from a JSON Schema. A project that only needs typed models for a payload format does not need the OpenAPI SDK.
Is Jane still maintained?
The repository is not archived and the last push was on 2026-10-19. The default branch is next, and recent releases are v8.0.1 from 2026-10-06, v8.0.0 from 2026-10-01 and v7.14.4 from 2026-09-26, with the changes recorded in CHANGELOG.md.
Where is the Jane documentation?
The documentation is published at jane.jolicode.com, built with MkDocs and a Poetry managed toolchain, and versioned with mike. The docs source lives in the docs/ directory of the repository, alongside the mkdocs.yaml configuration.
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/janephp-janephp)Was this useful?