yavin/symfony-form-tree
A Symfony bundle providing a Tree form type for editing hierarchical data, such as nested collections or Doctrine tree entities, with recursive child rendering, dynamic add/remove of nodes, and standard form validation support.
Architecture fit
The package is a Symfony Form extension, not a Laravel one. It provides a custom form type that extends Symfony's ChoiceType and flattens a hierarchical data set into indented <option> labels (typically using non-breaking spaces or dashes to represent depth). Laravel does not use the Symfony Form component — Laravel ships Console, HttpFoundation, Routing, Translation, Process, Finder, and Mime from Symfony, but not symfony/form, symfony/options-resolver, or the Twig form bridge. Adopting this package therefore means importing a foreign form-rendering paradigm into a framework that already has Blade, Laravel validation, old() repopulation, and Livewire/Inertia conventions.
The architecture fit is therefore poor as a direct dependency and good as a reference design. The actual value proposition — "recursively flatten a tree into a depth-indented choice list" — is roughly 100–200 lines of Laravel-native code (an Eloquent/repository-to-flat-array transformer plus a Blade partial). That is a build-vs-buy decision the TPM should force early.
Integration feasibility
Two paths exist:
composer require symfony/form symfony/twig-bridge and wiring a Symfony form factory into the Laravel container. You then have two parallel form systems, two validation systems (Symfony Constraints vs Laravel Validator), and a Blade/Twig bridge to maintain. Repopulation via old() breaks unless manually shimmed. This is feasible in a mixed-framework shop but is a multi-week integration with ongoing friction.App\Support\TreeOptions builder plus a reusable Blade component. This aligns with the stack, preserves old(), keeps Laravel validation, and removes the abandoned-dependency risk entirely.Technical risk
High, driven by adoption signals rather than code quality. 14 stars and 0 dependents means effectively zero production validation, no issue triage history, and no downstream compatibility pressure. The likely risk is a stale composer.json pinning Symfony Form 3.x/4.x, which will not resolve against a modern Laravel 10/11 stack on PHP 8.2+. MIT licensing is clean. The indentation approach also carries a subtle accessibility cost: screen readers announce padded labels verbatim, and native <select> cannot express hierarchy semantics (<optgroup> is flat, ARIA tree patterns require custom widgets).
Key questions
composer.json declare, and does it resolve against our Laravel/PHP matrix?parent_id loop the recursion?<select> is the wrong UX regardless of package choice.Stack fit
Assume Laravel 10/11, PHP 8.2+, Eloquent models with parent_id self-references (adjacency list) or a nested-set package. The Symfony Form component is architecturally foreign: no Laravel old() integration, no @error directives, no FormRequest binding. Stack fit is low for adoption, high for porting.
Migration path
Recommended: treat the repository as a specification, not a dependency.
TreeOptionsRepository — an adjacency-list-to-flat-array transformer with an explicit depth field, memoized per request and cached (Cache::remember) keyed by tenant/scope plus a model saved/deleted invalidation hook.<x-tree-select> Blade component rendering <option value="id"> with str_repeat('— ', $depth) or padding, passing selected from old().Rule::in() / exists validation rule against the same flattened set so validation and rendering share one source of truth.If a hard requirement forces Symfony Form usage (e.g., an existing Symfony module being bolted onto Laravel), isolate it behind a single service provider and a single Blade bridge view; do not let it leak into the rest of the application.
Compatibility
Verify: PHP constraint, symfony/form version range, whether the type is registered as a service via a bundle (Symfony bundles do not auto-register in Laravel — you would register the type manually with a hand-built FormFactory). Twig is not present in a standard Laravel install; the form theme would need porting to Blade regardless, which further erodes the adoption case.
Sequencing
composer require in a throwaway branch; record resolution failures and PHP/Symfony constraint mismatches.Maintenance
Direct adoption transfers ownership of an unmaintained dependency to our team — we would be the de facto maintainers of a fork with no upstream. Porting is a smaller, better-shaped maintenance surface: ~200 lines we wrote, under our test coverage, upgradeable with the framework. Either way the TPM should record the package in the SBOM and set a review date.
Support
No vendor, no SLA, 14 stars, 0 dependents — community support is effectively zero. Internal escalation path must be a named engineer who has read the source. Any production incident is ours to diagnose.
Scaling
Two dimensions matter. Data scale: recursive flattening is O(n) per request; cache aggressively and invalidate on tree mutation, or the admin page becomes a per-request tree walk. UI scale: native <select> with more than a few hundred options is unusable and slow on mobile browsers; depth beyond ~6 levels makes indentation illegible. If the tree exceeds those thresholds, the correct answer is a searchable async widget (Select2/Choices.js/Livewire combobox), not this package. Note the opportunity score (8.96) reflects gap-in-market potential, not production readiness — do not let it be read as a quality signal.
Failure modes
parent_id pointing at a deleted row) → silently dropped subtrees.old() mismatch → user selections silently lost on validation error, a high-visibility UX defect.aria-label or a breadcrumb-style title attribute.Ramp-up
Engineers need no new mental model to port the logic — a mid-level Laravel developer is productive in under a day. Adopting Symfony Form inside Laravel requires familiarity with Form types, OptionsResolver, form themes, and the Twig bridge: roughly 1–2 weeks of ramp-up for a team with no Symfony background, for a feature that could be built natively in 3–5 days. That ratio alone should settle the decision: use yavin/symfony-form-tree as a design reference and implement the indented tree select natively, reserving direct adoption only for teams already running Symfony Form inside their Laravel application.
How can I help you explore Laravel packages today?