pentiminax/ux-datatables
Symfony UX DataTables integration that adds interactive, AJAX-powered tables to Twig with server-side processing, configurable columns, and a simple PHP API for Symfony applications.
Architecture fit
AbstractColumn, Filter, BulkActionContext, Doctrine-backed providers, with a Stimulus controller for the frontend. This aligns well with a Symfony app that already owns its query layer; it is a poor fit for apps that expect the table library to own persistence or that use a non-Doctrine data layer.openspout/openspout for server-side CSV/XLSX keeps the core lean; symfony/serializer is now required for Ajax payload mapping, which is a real (if small) dependency addition.Integration feasibility
demo/ Symfony app covering columns, filters, layouts, bulk actions, exports, formatting, row events, theming. The demo materially de-risks evaluation and is the fastest path to a go/no-go.1.2.0; teams must own asset rebuild/publish in their pipeline.Technical risk
customizeQueryBuilder(). Custom providers must opt in via ScopedIdentifierProviderInterface; API Platform tables and providers without that interface still require handlers to enforce scope themselves. Any table in our estate using a custom or API Platform provider carries residual cross-tenant risk until audited.withCredentials now publish private updates, but existing custom publishers only emit a warning when used for a private table. Warning-only enforcement is a silent-exposure path if logs aren't monitored.formatValueUsing() emits a lossy or redacted representation, users will search and sort on the transformed value, not the truth. Escaping remains default-on unless a column opts into trusted HTML — that opt-in is a review gate.10^decimals used consistently for cents-backed display, plus boolean edit fields mapped to checkboxes. Any handler expecting prior submission shape is a breaking change.TernaryFilter default semantics flipped to compare true/false; NULL semantics now require explicit nullable(). Silent filter-result drift.confirm() will fail.Key questions
withCredentials with custom publishers today?symfony/serializer requirement collide with an existing constraint?Stack fit
customizeQueryBuilder() and per-row permissions. The security docs explicitly place Ajax route protection and per-row permissions on the application — that ownership boundary must be accepted up front.Migration path
1.1.x as the safe pin. Upgrade on a branch against the demo app plus our highest-risk table first (one with bulk actions, exports, and money columns).ColumnResolver::removeDeniedColumnValues() with deniedColumnPaths() + removePaths(); delete deep imports of filterFeature.js, filterLayout.js, bulkActionsFeature.js, bulkActionsLayout.js (the controller installs both bars automatically); replace confirmBulkAction() with confirmAction().Compatibility
symfony/serializer explicitly; do not rely on transitive resolution.openspout/openspout only for tables that actually need server-side CSV/XLSX — keep it out of the global require if exports are a narrow use case.1.2.0 with a rebuilt, republished asset set and cache-bust.Sequencing
symfony/serializer, openspout, DBAL, Symfony ceiling).ScopedIdentifierProviderInterface adoption for custom providers.PrivateUpdatePublisherInterface where tables are private.1.1.x output for a representative table.Maintenance
ColumnResolver::removeDeniedColumnValues(), and confirmBulkAction() are on a 2.0 removal clock. Budget cleanup work in the current cycle rather than deferring to the upgrade.Support
Scaling
DISTINCT root-entity paging for to-many joins (which previously produced short, overlapping pages — a correctness bug at pagination boundaries), and appending the identifier to break ordering ties.Failure modes
ScopedIdentifierProviderInterface and without handler-level scope. Highest-severity, lowest-visibility failure in this release.TernaryFilter comparing true/false where NULL semantics were assumed.Ramp-up
demo/ Symfony app is the single best onboarding asset — it exercises formatting, filters, layouts, bulk actions, exports, row events, and theming in a runnable form. Make "run the demo, then reproduce one of our tables in it" the first onboarding task.How can I help you explore Laravel packages today?