kevinpapst/tabler-bundle
Symfony bundle integrating the Tabler.io admin template, with Twig helpers, vertical and horizontal layouts, security pages, event-driven menus, a context helper, and translations—speeding up backend development on Bootstrap 5.
Architecture fit — this is the headline finding: kevinpapst/tabler-bundle is a Symfony bundle, not a Laravel package. It ships a TablerBundle::class registered in config/bundles.php, extends Symfony's bundle/DI extension system, and delivers its entire surface area as Twig functions, filters, embeds, macros and includes. None of that executes in a Laravel/Blade stack. There is no service provider, no Blade view namespace, no config publish tag, and no Laravel-oriented facade. Composer will install it (it is a plain PHP package), but nothing will register, and every helper it exists to provide is Twig-only. A TPM should treat the dependency as non-installable in the target stack and reframe the evaluation around what is portable: the Tabler.io theme assets, the component taxonomy, the translation catalogue, and the layout/menu/notification patterns as design references.
What is genuinely portable is substantial. The package is a well-curated inventory of ~30 admin UI components (cards, alerts, dropdowns, accordions, progress bars, status badges, timelines, modals, avatars, user-notification dropdowns, task lists), two primary layouts (vertical and horizontal), and security layouts (login, register, forgot/reset password). Those map cleanly onto Blade components and are the real value to lift.
Integration feasibility (native Symfony): Low friction. Four steps — composer require, copy config/packages/tabler.yaml, register the bundle, read docs/. Requirements are Symfony ≥ 6.0 and PHP ≥ 8.1, with confirmed support up to Symfony 8 / PHP 8.4–8.5. Webpack Encore integration is first-class, and the demo repo (TablerBundle-Demo) provides a working starting point. If any Symfony exists in the estate, this is a same-day integration.
Integration feasibility (Laravel): High effort, no upstream support. Requires either a fork that replaces the Twig layer with Blade components and the bundle extension with a service provider, or a clean-room port that treats the repo as a specification. The event-driven menu/task/notification system (Symfony EventDispatcher subscribers) would need rebuilding on Laravel events or a container-bound menu builder. A fork is the wrong call — see Operational Impact.
Technical risk register:
| Risk | Severity | Evidence |
|---|---|---|
| Wrong framework | Blocking for Laravel | Twig-only helpers, Symfony bundle registration |
| Upstream theme version pin | High | Release 2.4.1 explicitly pins Tabler ≤ 1.4 and states incompatibility with Tabler 1.5 — the bundle lags the theme it wraps |
| Single-maintainer / bus factor | High | 133 stars, 0 listed dependents, author is also the primary consumer (Kimai) |
| BC churn in templates | Medium-High | 2.0.0 introduced documented BC breaks: url → href option, camelCase vs kebab-snake file renames, NotificationInterface merge, container class removal |
| Icon set breakage | Medium | 1.1.0 bumped Font Awesome 5.15.4 → 6.5.0 as a flagged BC break; icon class strings are embedded in templates and caller code |
| Client-side performance | Low-Medium | 1.2.1 added an option to disable modal blur because it degraded performance on real workstations |
| Accessibility drift | Low-Medium | WCAG fixes are reactive and incremental (aria-expanded values, mobile zoom, aria labels) across 1.2.x |
Positive engineering signals should be recorded too: PHPStan level 9 (v2), PHP-CS-Fixer hygiene, Twig deprecation fixes landed promptly (1.5.1, 1.6.1, 1.8.0, 1.8.1), CSRF tokens added to reset-password, autocomplete attributes added to security forms, and 2.1.0 de-coupled templates from app.session/app.request. The project is maintained carefully within its means.
Key questions for the author/owner before any decision:
Stack fit. Assume Laravel + Blade + Vite (or Mix). The Symfony bundle does not fit. The underlying Tabler.io theme (Bootstrap 5.3) fits any stack — it is static HTML/CSS/JS and framework-agnostic. The bundle's contribution over raw Tabler is Twig sugar and opinionated layout scaffolding, i.e. exactly the layer we must own anyway.
Recommended path — port the patterns, discard the dependency.
x-tabler.layout ← vertical/horizontal layouts, page_wrapper and title-action blocksx-tabler.card ← card with headerBorderNone, bodyScrollable optionsx-tabler.alert, x-tabler.button, x-tabler.dropdown, x-tabler.accordion (with bodyClasses, before/after), x-tabler.progress, x-tabler.status, x-tabler.avatar, x-tabler.modal (no-footer variant)parent sub-menu item type added in 2.2.0 and the disabled item option) becomes a MenuBuilder service populated by Laravel listeners or a config tree, rendered by one Blade partial. This is the single largest port item — budget for it explicitly rather than discovering it mid-sprint.lang/en/*.php or JSON. Low effort, real payoff, and it avoids re-keying UI strings later.Migration path. There is no migration — nothing to migrate from since the bundle cannot run. Treat this as a greenfield admin-UI component library where the bundle repo serves as an open-source specification and the demo application as a visual acceptance suite we can diff against.
Compatibility. Track Tabler.io upstream directly; pin the theme version in package.json and review its changelog — the upstream project's own 1.4 → 1.5 transition broke this bundle, which tells us 1.5 has meaningful CSS/markup changes (full-page layout, security, error pages per the 0.17 notes). Bootstrap 5.3 and Font Awesome 6 should be declared as explicit, singly-owned versions rather than inherited.
Sequencing (indicative).
Maintenance. Owning a Blade port means owning the code, but it is shallow code — presentational components with thin logic, low coupling, low defect surface. That is a materially better position than maintaining a fork of a Twig bundle, where every upstream Symfony or Tabler bump forces a rebase against a divergent template tree with no upstream path for our patches. Recommendation: do not fork. Porting ~20 presentational components is cheaper than a permanent fork-and-rebase tax on ~60 Twig templates plus a Symfony bundle extension.
Support. Upstream support is best-effort from a single maintainer, funded by his own product (Kimai). Historically responsive and disciplined, but SLA-free. Under the port-the-patterns approach this is fine: we consume Tabler.io's issue tracker and community instead, and we control our own patch turnaround. Record the bundle's licence (MIT) and retain attribution for any copied template structure or translation strings.
Scaling. Rendering scales identically to any server-rendered Blade application — no new scaling axis. Two real scaling considerations: (1) component governance — a homegrown kit will accrete one-off variants unless a TPM enforces a contribution review, otherwise the "many includes, embeds and macros" convenience that makes the bundle attractive inverts into inconsistency; (2) theme drift — decide once whether Tabler is the design system or a starting point, because unbounded customisation forfeits the upgrade path. The bundle's own history (0.17 "fixes for changed CSS rules in Tabler Beta 19 — especially full-page layout, security and error") is a direct warning about how much churn a heavily-customised admin theme generates.
Failure modes to monitor.
icon prop and a single FA major version.Ramp-up. Low for any Laravel developer — Blade components and Bootstrap 5.3 are commodity skills. The only specialised knowledge is the Tabler component taxonomy, which the bundle's docs and demo app document well enough to serve as onboarding material. Contrast with the native-Symfony path, which additionally requires Twig macro/embed fluency and Symfony bundle-event knowledge. Estimate 2–3 days for a mid-level developer to be productive on the port.
Bottom line for the TPM. The score (33/100, 0 dependents, 133 stars) understates the code quality and overstates the strategic value simultaneously. The package is competently maintained but structurally unusable in a Laravel estate and pinned behind the theme it wraps. Spend two days on a Tabler-on-Vite spike; if that succeeds, adopt the theme, port the component patterns, reuse the translations, and leave the dependency out of composer.json entirely. That converts a blocked dependency into a two-to-three-week, low-risk UI investment with no single-maintainer exposure.
How can I help you explore Laravel packages today?