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

Ux Common Laravel Package

krystal-sf/ux-common

A shared UX toolkit for Laravel/PHP projects, offering common UI helpers and conventions that keep interfaces consistent across Krystal applications. Use it as a lightweight foundation for reusable front-end patterns and smoother developer workflows.

View on GitHub
Deep Wiki
Context7

Getting Started

Before you write a single line of integration code, confirm what you actually have: despite being listed under a Laravel evaluation, krystal-sf/ux-common is a Symfony UX companion package (Twig templates, Stimulus controllers, front-end assets, possibly a *Bundle class + DI extension). For a Laravel developer the day-to-day leverage is real but narrow — you are harvesting assets and patterns, not installing a Laravel package.

Minimal steps:

  1. Clone, don't require (unless you're on Symfony). git clone https://gitlab.com/krystal-sf/ux-common and read the tree. In a Laravel app, composer require pulls symfony/framework-bundle, twig/twig, and symfony/ux-* into a container you will never use — redundant at best, resolution conflicts at worst.
  2. Look first at, in order: composer.json (version constraints, license, dev-main vs tagged, what symfony/ux-* packages it pins), README.md, src/ (is there a *Bundle.php, a DI Extension, or just helpers?), templates/ (Twig components), and assets/ or resources/js (Stimulus controllers — the portable gold).
  3. Check the licensing and provenance before reuse of any kind. "Common files for Krystal projects" often embeds org-specific assumptions (asset hosts, auth, hosting) that won't survive copy-paste.
  4. Register in a Symfony host (if that's you): add the bundle to config/bundles.php if one exists; otherwise register the Twig namespace in config/packages/twig.yaml (paths: { vendor path: ux_common }) and the asset path in importmap.php (AssetMapper) or webpack.config.js (Encore), then php bin/console assets:install.
  5. In a Laravel host: copy Stimulus controllers into resources/js/controllers/, styles into resources/css/, and port any Twig components one-to-one into anonymous Blade components under resources/views/components/.

First use cases that actually pay off:

  • Copy a Stimulus controller into resources/js/controllers/ and register it in resources/js/app.js with app.register('name', Controller).
  • Lift a design token / CSS base layer into your Vite pipeline and own it from day one.
  • Read the Twig component structure as a reference for how to factor a shared Blade component package if you decide to build one internally.

Implementation Patterns

Pick one of three modes up front and be explicit in your PR — the wrong mode is where the time gets lost.

Mode A — Read-only reference (recommended default). Never add the package as a dependency. Inspect, extract, and own:

resources/js/ux-common/controllers/   # copied Stimulus controllers, one file each
resources/css/ux-common/             # base styles / tokens
resources/js/app.js                  # import and register explicitly

Keep the copied files under a single subdirectory and re-export from a thin resources/js/ux-common/index.js so a future upstream diff is a directory-level compare, not a grep across your app.

Mode B — Private fork + path repo. If the portable slice is substantial, fork into a private GitLab repo, add a composer.json with your own version, and consume via a Composer path or vcs repository without pulling Symfony deps (strip the bundle class, DI extension, and symfony/* requires). Pin a commit SHA for provenance. Assign an owner and a changelog. This is the only mode where you can schedule fixes.

Mode C — Full Symfony UX consumption. Only if you actually run a Symfony app: bundle registration, Twig namespace, AssetMapper/Encore wiring, and assets:install. If you're also introducing Turbo, do not mix it with Livewire in the same app — Turbo's navigation model and Livewire's SPA navigation fight each other in ways that reproduce as intermittent, hard-to-trace UI bugs.

Twig → Blade translation pattern. For each Twig component, create a matching anonymous Blade component. Name the slot/props identically so the mental model stays one-to-one:

{{-- resources/views/components/ux/button.blade.php --}}
<button {{ $attributes->merge(['class' => "ux-btn ux-btn--{$variant}"]) }}>
    {{ $slot }}
</button>

Keep the CSS class names exactly as upstream ships them — that's what keeps the ported CSS working without edit. Only rename when you have a specific reason, and note every rename in a PORTING.md.

Stimulus registration pattern. Copy controllers verbatim, then register explicitly rather than relying on controllers/index.js auto-discovery (that convention belongs to Symfony's StimulusBundle, not your Laravel app):

import { application } from './bootstrap';
import UxDropdown from './ux-common/controllers/dropdown_controller';
application.register('ux-dropdown', UxDropdown);

Integration tips.

  • If you already run a design system (Flux, TallStack UI, Blade UI Kit), assume 60–80% of this package is duplicative and stop before you build a parallel stack.
  • Time-box a single representative component (the most complex Stimulus controller) as a spike. If it ports in under a day and adds value, continue; if it fights your pipeline, close the evaluation.
  • Document the ported directory as a fork you own — with README, PORTING.md, and a last-synced commit SHA — before the first PR lands, or the next developer will assume it's upgradeable.

Gotchas and Tips

  • Transitive dependency blow-up. composer require in a Laravel app drags Symfony FrameworkBundle, Twig, and UX packages into a container that already has equivalents. Resolution conflicts and orphaned-service overhead are the practical cost; asset vendoring sidesteps both.
  • No semver, no CHANGELOG. Assume dev-main consumption and pin a commit SHA on day one. Upstream bumps to Symfony or Twig majors land with no notice and no migration guide.
  • Zero dependents = no battle-testing. You will be the one finding the rough edges. Budget for it, or don't take the code.
  • Twig namespace collisions. If you do register the Twig path in a Symfony host, use a distinct namespace (ux_common) — the default templates/ namespace collides with app templates unpredictably.
  • Three different asset worlds. Encore (yarn encore dev), AssetMapper (importmap:install + assets:install), and Vite (npm run dev) have completely different idioms. Nothing in this package will "just work" across them; the copy into Vite is manual and should be.
  • Turbo vs Livewire. If Turbo is in the payload, decide once which navigation model you're on. Running both is a known source of morphing and back-button bugs that only reproduce under specific link patterns.
  • Twig-to-Blade drift. Your ported components will diverge from upstream the moment you touch a class name or add a prop. Re-syncing becomes a manual diff; either accept the fork permanently or don't take the dependency on at all.
  • License and provenance. Verify the license explicitly permits internal redistribution. "Common files" often embed Krystal-specific config (asset hosts, auth assumptions) that is fine to read but not to copy.
  • Debugging tips.
    • Symfony host: bin/console debug:twig lists namespaces; bin/console debug:container | grep ux_common confirms the bundle loaded; assets:install --symlink reveals the real asset path.
    • Laravel host: php artisan view:clear after copying components (stale compiled views are the #1 "why isn't my component rendering" cause); check resources/js/app.js actually registers the controller; check Vite's build.rollupOptions.input includes the copied subdirectory.
  • Extension points worth knowing.
    • Twig namespace overrides: a package template can be shadowed by placing a same-named file at templates/bundles/UxCommonBundle/ (Symfony convention).
    • Stimulus controller override: register the same identifier twice — the last register wins — so you can swap a controller without touching the copied file.
    • Bundle DI config: config/packages/ux_common.yaml may expose knobs; read the extension class before assuming defaults.
  • Fork rot. If you go Mode B, name an owner and a review cadence before the first merger. A private fork with no owner is a stale snapshot waiting to happen.

Net for a Laravel developer: treat this as a pattern and asset source, not a dependency. One week of triage and a single component spike is the entire evaluation; if the portable slice is small or overlaps your existing design system, build internally and log the pattern as the takeaway.

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.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console