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

Cascader Laravel Package

vlados/cascader

A cascading dropdown for Laravel Livewire and Alpine.js, inspired by Ant Design's Cascader. It renders a two-column desktop dropdown with search and a mobile bottom sheet, supports light and dark mode, two-level option arrays, and standard wire:model binding.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

vlados/cascader is a presentation-layer package: a Blade component, an Alpine.js component, and Tailwind-styled published views. It has no migrations, no persistence, no queues, no external services, and no server-side runtime. That makes it architecturally cheap to adopt and cheap to remove — it touches only the view layer of a Laravel + Livewire + Alpine + Tailwind application.

Fits: Laravel 11–13 apps using Livewire 3/4 with a Tailwind + Alpine front end, forms that need a hierarchical single-select (category → subcategory → item), and teams already comfortable publishing and compiling vendor assets.

Does not fit: Inertia/Vue/React SPAs (the component assumes Livewire and a global Alpine), Bootstrap- or CSS-module-based design systems, Livewire 2, or any form where the cascader must support multi-select, async/server-side search, or very large taxonomies.

Integration feasibility

The install is composer require plus asset publishing, but it has three independent failure points that all present identically as "the component renders nothing":

  1. Alpine registration ordering — the component must be registered via alpine:init before Alpine.start(). Livewire 3/4 bundles and starts Alpine itself, so teams that also import Alpine from 'alpinejs' and call Alpine.start() will double-instantiate and break both the cascader and Livewire reactivity.
  2. Tailwind content scanning — vendor views must be in the content globs (v3) or covered by @source (v4), or every class gets purged and the dropdown renders unstyled.
  3. Publish step for the JS — the script lands in resources/js/vendor/cascader/, i.e. unreviewed third-party JavaScript is copied into our compiled bundle.

Realistic estimate: half a day for a spike by a developer who knows Livewire/Alpine, one to two sprints to harden (wrapper component, a11y pass, docs, tests).

Technical risk

  • Bus factor / validation: 0 stars, 0 dependents, single maintainer, no evidence of production use anywhere. Maturity signals (readme, changelog, releases) are documentation only — no CI or test signal is reported. Treat as unproven.
  • Supply chain: a Composer package that additionally injects a JS file into our source tree. Pin to an exact version, composer audit in CI, and require a human review of the published JS before it merges.
  • Version-matrix fragility: the stated matrix spans PHP 8.2–8.3+, Laravel 11/12/13, Livewire 3/4, Alpine 3, Tailwind 3/4. The release date (2026-08-02) and "Laravel 13" reference are forward-dated relative to this assessment — verify the tag actually resolves on Packagist and isn't a dev branch, and confirm Tailwind v4 support rather than assuming it.
  • Accessibility: "Ant Design-inspired" is a visual reference, not a conformance claim. Keyboard navigation, ARIA combobox semantics, focus trap and scroll lock in the mobile bottom sheet, and screen-reader announcements for search results are all unverified. WCAG 2.2 AA is a gating requirement for most enterprise customers.
  • Blast radius is genuinely small: a UI-only component cannot corrupt data or take down a service. The worst case is a broken form field, which is why the risk is "annoying" rather than "critical" — and why it should be isolated behind an internal wrapper.

Key questions

  • How does selection bind back to Livewire — wire:model, $wire.set, an event? Is it Livewire-deferred, and does it work with wire:model.live validation?
  • Is the option tree a static PHP array, or can it load asynchronously per level? What is the practical node-count ceiling before payload/DOM cost bites?
  • Is search client-side only? Is it configurable (placeholder, no-results text, debounce, min characters)?
  • Does it support clearable, disabled nodes, preselected values, and a "change" hook for dependent-field resets?
  • Are translations publishable, or are strings hard-coded in Blade?
  • Does the package ship tests, and what is the maintainer's stated support policy and response expectation?
  • Is the JS CSP-safe (no inline handlers), and what is its gzipped size?

Integration Approach

Stack fit

Layer Requirement Our position
PHP 8.2+ (8.3+ for Laravel 13) Verify per app
Laravel 11 / 12 / 13 Confirm minor-version support
Livewire 3 or 4 Do not co-install a second Alpine
Alpine 3 Already present via Livewire
Tailwind v3 or v4 Confirm @source path for v4
Icons FontAwesome by default, resolver-configurable Prefer mapping to our existing icon set

The icon resolver is the main design-system seam — plan to swap FontAwesome for our icon component rather than shipping FA purely for this dropdown.

Migration path

Do not replace an existing cascader directly. Build an internal <x-ui.cascader> wrapper that owns the public API (options, model, placeholder, change event) and delegates to the vendor Blade component. That wrapper is the swap seam: if the package stalls, we reimplement behind the same props without touching call sites.

Parity checklist before any replacement: keyboard-only operation, type-ahead search, clearable, preselected/deep-linked values, disabled nodes, required-field validation messaging, mobile behavior on iOS Safari and Android Chrome, and empty/error states. Where parity is missing, decide explicitly: accept, wrap, or block.

Compatibility and sequencing

  1. Spike (branch, feature-flagged). Install, publish both tags, register on alpine:init, add the vendor path to Tailwind, render a static three-level tree next to the incumbent control on one low-traffic internal form.
  2. Harden. Review the published JS, pin the exact version, add composer audit, map icons to our set, wrap the component, add a11y fixes (focus trap, Escape, ARIA) if needed.
  3. Prove binding. Validate wire:model round-trips, dependent-field resets on change, server-side validation errors, and preselection from the database.
  4. Pilot. One real form, one release cycle, instrumented for client errors and form abandonment.
  5. Roll out behind the wrapper, with the incumbent control retained until two releases pass without incident.

Keep the feature flag until step 5 completes; the whole point is that reverting is a config change, not a code change.

Operational Impact

Maintenance

Ownership sits with the front-end/platform team, not the package author. Budget: ~1–2 days per quarter for dependency bumps and Tailwind/Alpine/Livewire compatibility checks, plus the wrapper's own tests. Policy: exact-version pin, no automatic minor upgrades, composer audit and a JS-diff review in CI. Pre-approve a fork: if the maintainer goes quiet, we vendor the repo and patch in-house rather than block on upstream.

Support

No vendor, no SLA, no support contract — a single author and zero dependents means issues are effectively ours. Define L1/L2 internally and document the known failure signatures (below) in the team runbook so on-call isn't diagnosing a purged Tailwind class at 2 a.m.

Scaling

No server-side load: the tree ships to the client and search runs in the browser. That is fine for tens to low hundreds of nodes and progressively worse beyond that — payload size, DOM count on the mobile sheet, and O(n) filtering on low-end devices. For large catalogs, plan to prune the tree server-side per request or fall back to a different control; do not assume async loading exists.

Failure modes to document

  • Component renders inert → Alpine component not registered, or registered after Alpine.start().
  • Dropdown visible but unstyled → Tailwind not scanning vendor/vlados/cascader (or missing @source on v4).
  • Livewire stops reacting after page load → duplicate Alpine instance started by app code.
  • Icons missing, dropdown functional → icon resolver not mapped.
  • CSP violation → inline script/style in the published views.
  • Stale JS after upgrade → published script not re-published/reviewed.
  • Bottom sheet traps or loses focus on mobile → a11y regression; verify per release.

Ramp-up

Low for a Laravel/Livewire team: half a day to first render, one sprint to production-grade (wrapper, a11y, tests, docs, runbook). Write a two-page internal doc covering the three registration gotchas and the icon override; that single artifact removes most of the recurring support cost. Given the package's immaturity (0 stars, 0 dependents, low opportunity score), adopt it only as a swappable UI convenience — never let it become load-bearing for a customer-facing flow without the wrapper and feature flag in place.

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.
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc
animalyoung/laravel-influxdb
onix-solutions/sms-telera
lonely-lights/prosetta
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log