folklore/eloquent-json-schema
Generate JSON Schema definitions directly from your Eloquent models. This package inspects attributes, casts, and relationships to build accurate schemas, making it easy to document APIs, validate payloads, and generate typed clients.
Architecture fit. The package is a single Eloquent cast: a model attribute holding a JSON Schema document is hydrated into a typed object instead of a raw array or string. That is a deliberately narrow seam, and it fits exactly one architecture — Laravel applications that already treat schemas as data rather than as files or config. Candidate products are form builders, tenant-configurable settings, low-code/workflow definition tables, API contract registries, and integration payload catalogs. It does not fit request validation, it does not enforce anything at the database boundary, and it does not validate inbound payloads against a schema. Any stakeholder expecting "JSON Schema support for Laravel" in the validator sense will be disappointed, and that expectation gap is worth killing in the first meeting rather than the third.
Integration feasibility. Mechanically trivial: composer require folklore/eloquent-json-schema, one class, one $casts entry. The real feasibility question is dependency compatibility, not code complexity. With 3 stars and 0 dependents there is no evidence of anyone running this against a current Laravel or PHP release; the illuminate/* constraints in composer.json are the first thing to inspect and the most likely blocker. Budget a half-day spike, not a half-hour — and treat the spike as an evaluation of the underlying validator as much as of the package.
Technical risk. High, and concentrated in abandonment rather than in defects:
justinrainbow/json-schema, opis/json-schema, or similar). That library — not this package — determines draft support (draft-04 vs draft-07 vs 2020-12), $ref resolution behavior, format assertion semantics, and error quality. The package's age likely pins an old validator major version, which caps what we can build on top of it.toArray(), toJson(), save(), and bulk upsert paths.Key questions to answer before any commitment.
$refs, and over what transport?illuminate/* and PHP constraints, and does it implement CastsAttributes (Laravel 7+) or the older castable convention?cursor(), chunk(), lazy()) and serialization, or only single-model retrieval?Stack fit. Adopt only if all three hold: Laravel with first-class custom-cast support; schemas persisted as model attributes rather than files or a config service; and explicit team acceptance of code ownership. If schemas live in files or a remote registry, the package adds nothing — use the validator directly. If the goal is rejecting bad inbound requests, use Laravel's json validation rule or a dedicated validator. This package is for the "schema as a row" pattern and nothing else.
Migration path. Do not migrate to it. Introduce it at a single seam behind an internal contract — e.g. a SchemaDocument interface plus a cast that returns it — so the implementation underneath is swappable. That interface is the migration path both in and out: if the package dies, we rewrite roughly fifty lines behind the same contract and no calling code changes. Backfill by scanning existing rows for valid and invalid documents before enabling the cast on any model already in production; the scan is the cheap insurance against a read-path 500 discovered by a customer.
Compatibility. Treat the package as version-locked until proven otherwise. Pin a commit SHA, vendor a fork into our namespace (App\Support\Casts\JsonSchema) if the license permits, and run it against our actual Laravel and PHP versions in CI before it reaches a shared branch. Expect to either patch the illuminate constraint or replace the validator dependency. Both are small edits to a small codebase — but both require someone to own the fork, which is the actual commitment being asked for.
Sequencing.
opis/json-schema. This is the honest comparison, not a fallback.Maintenance. Upstream maintenance is effectively zero and there is no community pressure to keep it current. Ownership transfers to us on day one. Budget a small but permanent line item for dependency bumps (validator library, Laravel majors) and for re-testing on every framework upgrade. Vendoring is the honest way to price this into the roadmap — a "free" composer require is a hidden recurring cost here.
Support. No issue triage, no release notes, no documented behavior beyond a README. Our internal runbook is the support model: what the cast does on invalid input, how to diagnose a hydration failure, how to roll back a model to raw JSON. Write it before rollout, because otherwise the first incident gets diagnosed by reading vendor source under pressure.
Scaling. Per-attribute schema compilation or validation on every hydrate puts CPU work on the hottest path in a Laravel app — model retrieval. Costs compound in collection endpoints, queue workers processing thousands of models, and serialization-heavy APIs. Mitigate with a compiled-schema cache keyed by schema hash, avoid enabling the cast on models that are read in bulk but never need the schema object, and never let it stand in for write-side validation. Note also that it protects nothing at the data layer: writes from other services, migrations, or raw SQL bypass it entirely.
Failure modes.
$ref resolution or format assertion behavior → previously valid documents start failing.toArray()/toJson() payloads drift and break API consumers.$ref resolution introduces network latency and a new dependency into model hydration if not explicitly disabled.Ramp-up. Low for the mechanics — one developer reads the source in an hour and can extend or replace it. Non-trivial for the domain: draft differences, $ref/$id semantics, format as annotation versus assertion, and error-reporting quality are specialist territory. The real ramp-up cost is not the package, it is the schema expertise the package assumes. If nobody on the team owns that expertise, the cast becomes a liability that gets enabled once and then quietly distrusted.
Bottom line for a TPM. Integration cost is negligible; ownership cost is not. With 3 stars, 0 dependents, and an opportunity score that signals no ecosystem pull, this is a reference implementation to read, not a dependency to adopt. The equivalent functionality is a small custom cast we control, and the deciding factors should be draft support and caching behavior in our chosen validator — not this package's convenience. Frame it to stakeholders as a time-boxed spike that de-risks a schema-flexible feature, with a fork-and-own plan required before anything reaches the critical path.
How can I help you explore Laravel packages today?