Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Liform Bundle Laravel Package

rezozero/liform-bundle

Symfony bundle that converts Symfony form definitions into JSON Schema, letting front-end apps render forms from a single source of truth. LiFormBundle serializes form types, fields and options into portable JSON, keeping server-side and client-side forms in sync.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit — the framework mismatch is the first gate, not a footnote. Despite the "Laravel/PHP package" framing in the intake record, rezozero/liform-bundle is a Symfony bundle with zero Laravel applicability as packaged. It exists to register the liform library (Symfony Form type → JSON Schema converter) into a Symfony kernel: a bundle class, DI service definitions, configuration tree, and Twig form-theme support. Laravel has no equivalent lifecycle — no bundle registration, no Twig, no Symfony container. The only salvageable asset is the underlying liform/liform library, which carries symfony/form as a hard runtime dependency. So "leveraging" this package in a Laravel codebase is not configuration; it is standing up Symfony's Form component as a subsystem to obtain a serialization feature. As a TPM, treat that as the decision boundary: the question is not "should we install this bundle," it is "do we want a second form abstraction and a second validation story in our deployable."

What the underlying capability genuinely delivers. Given a Symfony Form type, liform emits a JSON Schema describing field names, types, and a subset of constraints (required, enum, minLength, pattern, numeric bounds). That has real product value in exactly one scenario: one team owns form definitions server-side, a second team renders them client-side with a schema-driven renderer (react-jsonschema-form, Formily, JSON Forms), and you want to collapse a hand-maintained contract into a single artifact. It also supports API contract and documentation generation, and gives a build-vs-buy signal — this is a thin MIT-licensed adapter, not a platform. Effort to replicate the concept in-house is days to a couple of weeks depending on form-type exoticism.

Where the abstraction leaks — this is the technical risk that decides the business case. Symfony Form is a stateful, event-driven, entity-aware object graph; JSON Schema is static and declarative. Fidelity degrades silently in the cases that matter most:

  • EntityType/ChoiceType behind a query builder, PRE_SET_DATA/PRE_SUBMIT listeners, and collection types with prototypes have no faithful schema representation.
  • Data transformers (date string ↔ DateTime, ID ↔ entity) mean the schema describes the transformed shape, not the payload the client actually posts.
  • Validation constraints live in the Validator component, not the Form component. Only constraints liform explicitly maps surface as keywords. The emitted schema is therefore permissive relative to actual server validation — the client will happily accept input the server rejects. For a TPM, that is a UX and trust risk, not just a technical nicety.
  • Draft support matters: liform historically tracks draft-04 semantics with partial later-draft coverage. Modern renderers assume draft-07/2020-12 keywords (if/then, dependentRequired, $defs). Verify against the chosen renderer before anyone commits.

Adoption risk is the headline for a TPM. Zero stars, zero dependents, single-maintainer provenance (an agency publishing a wrapper around Limenius' liform). Not disqualifying for an internal tool, but it means: no community CVE triage, no Stack Overflow corpus, no guarantee of a Symfony 7 / PHP 8.3+ release, and no external users to absorb the cost of discovering sharp edges. A composer audit against a stale transitive tree is a live concern for anything internet-facing.

Key questions to answer before funding engineering time:

  1. Is the requirement genuinely "single source of truth for form shape across backend and frontend," or narrower — an API contract for one admin surface? If narrower, hand-written schemas or an OpenAPI-first approach is cheaper and lower-risk.
  2. Does a frontend team already consume JSON Schema, or is the schema aspirational? No committed consumer means no business case.
  3. What does composer.json actually constrain, and what is the last-commit date? Does it install cleanly against a security-supported Symfony Form version on our PHP baseline?
  4. What constraint and field types do our real forms use? Heavy EntityType + custom constraints means cosmetic schema and a failed spike.
  5. Will we accept a fork? If no, maintenance risk is unmitigated and the answer is no.

Verdict. Low architectural fit for a Laravel codebase, unproven maintenance posture, and a value proposition entirely contingent on a schema-driven frontend that may not exist. Not a default-adopt. Worth a timeboxed spike only if the frontend contract problem is real and recurring.

Integration Approach

Stack fit. Poor as packaged, moderate if you extract the library and discard the bundle. The decision is really about whether liform/liform + symfony/form earns a place in a Laravel service — the bundle layer has no Laravel analogue and should be ignored entirely.

Three viable paths, ascending cost:

Path What it means Cost When it wins
A. Direct library use composer require liform/liform symfony/form; author Symfony Form types for affected resources; wrap in a Laravel service returning schema JSON 1–2 sprint-weeks incl. spike Frontend already consumes JSON Schema; small, static form surface
B. Laravel-native adapter Translate Laravel FormRequest rules or a small schema DSL to JSON Schema; no Symfony 2–4 sprint-weeks You want zero cross-framework dependency and full coverage control
C. Schema-first Author JSON Schema / OpenAPI components; validate server-side with opis/json-schema ~1 sprint-week Forms are few, or the contract genuinely is the product

Path B is the right long-term answer for a Laravel shop. Path A is the fastest way to prove the concept's value before paying for B. Fund A as a throwaway spike with an explicit kill criterion.

Migration path (Path A) — greenfield coexistence, not migration. Sequence:

  1. Isolation first. Install into a dedicated module and namespace, behind an interface such as FormSchemaGenerator::for(string $formKey): array. Nothing else in the app may touch Symfony classes. This is the single most important architectural decision: it makes the whole thing swappable for Path B or C at one seam.
  2. Register the Symfony Form factory manually. Do not boot the bundle or a kernel. Construct Forms::createFormFactoryBuilder() in a Laravel singleton with minimal extensions, avoiding the Symfony event dispatcher unless proven necessary.
  3. Enumerate a fixed, small catalogue. 3–5 representative form types as plain PHP classes. Resist database-driven dynamic form registration — that is exactly where the stateful/declarative mismatch bites.
  4. Emit through an endpoint (GET /api/schemas/{formKey}) with HTTP caching and a schema version field. Do not embed schemas in Blade views; runtime embedding bypasses caching.
  5. Add golden-file contract tests per form. This is your only regression net against a dependency you don't control.

Compatibility checks before committing. Pin exact versions and commit composer.lock. Verify three things: the Symfony Form major available for our PHP baseline; liform's JSON Schema draft level against the chosen renderer; and whether the dependency tree's PHPUnit / PHP-CS-Fixer / PSR constraints conflict with the app's. If the package forces a Symfony Form version out of security support, that alone kills Path A.

Sequencing against delivery. Do not put this on a critical path. Run it as a parallel spike alongside the admin-surface build. Gate broader rollout on two things: the spike showing ≥80% constraint coverage on our real forms, and the frontend team confirming the schema is sufficient to render including error states — JSON Schema carries no server-side validation messages, so error UX must be solved separately.

Operational Impact

Maintenance. The dominant cost, and it is not the code you write — it is the dependency tree you inherit. You will maintain a Symfony Form factory inside Laravel, a mapping layer whose fidelity requires continuous verification, and a third-party package with no visible maintenance. Realistic budget: 0.1–0.2 FTE ongoing for patching and drift, spiking sharply on any PHP major upgrade or a Symfony Form security release upstream has not absorbed. If upstream goes quiet, you fork; budget that explicitly rather than discovering it at upgrade time.

Support. Effectively zero external support — no maintainer community to escalate to, no issue-tracker velocity to read, no downstream users who have already hit your bug. The real hazard is internal knowledge concentration: one engineer understands the Symfony Form → JSON Schema translation, and when they leave the module becomes a black box. Mitigate with the golden-file tests, written design notes on the mapping decisions, and deliberate pairing.

Scaling. Scales fine on throughput — schema generation is a cacheable, build-time-ish operation. It does not scale on breadth: every new form type, custom constraint, or dynamic field adds mapping work, and coverage degrades quietly as forms grow more stateful. Plan for the schema catalogue to be a curated subset, not "all forms."

Failure modes to monitor.

  • Silent permissiveness: schema accepts what the server rejects → client-side validation becomes false confidence and error UX degrades.
  • Silent incompleteness: a new form field type maps to a permissive default with no alert. Contract tests catch this only if someone writes the case.
  • Upstream abandonment: no release compatible with a future PHP/Symfony Form security patch; you fork under time pressure.
  • Draft mismatch: renderer ignores emitted keywords, producing a form that looks right and validates wrong.
  • Cross-framework runtime surprises: service-container assumptions in Symfony Form (event dispatcher, property access) failing in an unfamiliar Laravel boot path.

Ramp-up. Roughly one to two weeks for a mid-level Laravel engineer unfamiliar with Symfony Form, because the conceptual overhead (form types, extensions, data transformers, event subscribers) is not transferable from Laravel knowledge. The JSON Schema side is easier — a day or two. Budget a spike plus a written handover artifact; do not leave this undocumented and single-owner.

Recommendation for the roadmap. Do not adopt the bundle. Run a one-to-two sprint spike on the pattern (Path A), with a pre-agreed kill criterion of <80% constraint coverage on real forms. If the spike passes and a frontend consumer is confirmed, migrate immediately to Path B (Laravel-native adapter) rather than shipping Path A to production — the adapter is a few weeks of work and permanently removes the cross-framework dependency, the unmaintained package, and the security-patching exposure. If the spike fails, take Path C and move on.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin