pajak/ui
A Laravel UI package from Pajak offering reusable interface components and helpers to speed up building consistent, styled web interfaces in PHP applications.
Install and publish
composer require patrikjak/pajak-ui
php artisan vendor:publish --provider="PatrikJak\PajakUi\PajakUiServiceProvider"
Publishing typically drops a config/pajak-ui.php and a set of assets/views under resources/views/vendor/pajak-ui. Read the config file first — it's the map of what the package will and won't do for you (asset loading, component prefix, default theme options). Then list the shipped Blade components (ls vendor/patrikjak/pajak-ui/resources/views/components) before writing any markup; the component names are the real API surface, not the README.
Wire it into your layout once
Add the package's stylesheet/script entry to your Vite setup (or include the published CSS/JS directly) in resources/views/layouts/app.blade.php, and add the vendor path to tailwind.config.js:
content: [
'./resources/**/*.blade.php',
'./vendor/patrikjak/pajak-ui/resources/views/**/*.blade.php',
],
First use case
The highest-value first swap is a hand-rolled CRUD index page: replace the <table> loop and the create/edit <div class="modal"> with the package's table and modal components in a single Blade view. That exercises the table, form controls, modal, and flash-message pieces in one shot and tells you quickly whether the package's opinions match your app's.
Blade-first, with a builder layer. Most usage is <x-pajak-ui::table :data="$users" :columns="$columns" />-style calls driven from the controller or a Livewire component. Keep column definitions in a small dedicated class or a private method (private function userColumns(): array) rather than inline in the view — you'll reuse them for exports and tests.
Form components + Laravel validation. Bind package inputs to old() and surface @error state so they behave like native inputs. If the components don't forward attributes automatically, pass :value="old('email', $user->email)" explicitly. Validate in a FormRequest as usual; don't let the UI layer become the validation layer.
Modal + form + redirect flow. The common pattern: a table row action opens a modal containing a form, the form posts to a normal controller action, the controller redirects back with ->with('status', ...), and the layout renders the package's toast/alert from the session flash. Avoid returning JSON from these actions for a Blade modal — full redirects keep it simple and avoid stacking AJAX handling on top of Alpine.
Layout-level integration. Load package assets exactly once, in the base layout. If you extend multiple layouts (app, guest, print), extract a @include('partials.pajak-assets'). Duplicate script includes are the most common cause of "my modal opens twice."
Version pinning. In composer.json use a caret on the minor: "patrikjak/pajak-ui": "^0.6". Pre-1.0 packages treat a minor bump as a potential breaking change, so lock the exact version in production and upgrade deliberately.
https://github.com/patrikjak/pajak-ui/compare/v0.5.0...v0.6.0. Check resources/views, config/, and any composer.json peer constraints for renamed components, changed slot names, or bumped Tailwind/Alpine requirements.content in tailwind.config.js. Verify by checking whether a class like the package's button class appears in the compiled CSS.vendor:publish --force will clobber your customized component views. Prefer overriding individual components into resources/views/vendor/pajak-ui/... (Laravel's view override resolution) and keep a note of which files you own so upgrades don't silently revert them.php artisan view:clear && php artisan config:clear, and rebuild assets. Stale compiled views referencing removed components produce confusing "unable to locate component" errors.defer) and not double-included. With Livewire, add a stable wire:key to any component inside a loop so modals don't inherit stale state after a re-render.php artisan view:cache will fail loudly on any component name you got wrong — run it in CI rather than discovering the typo at runtime.resources/views/components that compose the package's pieces. Wrapping rather than editing means an upstream release is a composer bump, not a merge./pull/8 for 0.6) and any open issues about breaking changes before you adopt the version across a team.How can I help you explore Laravel packages today?