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

Grid Laravel Package

prezent/grid

A Laravel package for building data grids and tables in PHP. Define columns and rows, control formatting and rendering, and display structured, searchable data in your Blade views with minimal configuration and reusable, customizable grid classes.

View on GitHub
Deep Wiki
Context7

Getting Started

prezent/grid is a framework-agnostic PHP library, not a Laravel package. There is no service provider, no config file, and no Blade views shipped. You wire it up yourself.

composer require prezent/grid

Register the factory once in AppServiceProvider:

use Prezent\Grid\GridFactory;
use Prezent\Grid\Extension\Core\CoreExtension;

$this->app->singleton(GridFactory::class, function () {
    $factory = new GridFactory();
    $factory->addExtension(new CoreExtension());

    return $factory;
});

Your first grid — an admin index table backed by an array:

use Prezent\Grid\GridFactory;
use Prezent\Grid\DataSource\ArrayDataSource;

public function index(GridFactory $factory)
{
    $grid = $factory->createGrid('users', function ($builder) {
        $builder->addColumn('id', null, ['property_path' => 'id']);
        $builder->addColumn('name', null, ['property_path' => 'name']);
        $builder->addColumn('email', null, ['property_path' => 'email']);
    });

    $view = $grid->createView(new ArrayDataSource(
        User::query()->orderBy('id')->get()->toArray()
    ));

    return view('users.index', ['grid' => $view]);
}

Look first at GridFactory, GridBuilder, the DataSource implementations (ArrayDataSource is the one you'll use with Eloquent), and Extension/Core for the built-in column type. Your first real use case is almost always "replace a hand-written <table> in an admin screen with a declarative column list."

Implementation Patterns

Define grids as classes, not closures. Subclass the library's grid type (or wrap the closure in a dedicated App\Support\Grids\UserGrid class) so the column definition is testable and reusable across controllers and exports.

Map Eloquent to arrays at the boundary. The data source consumes plain rows; call ->get()->toArray() or ->map(fn ($u) => [...]) before handing data over. This keeps lazy-loading surprises and N+1 queries inside your query layer where you can with() them, rather than inside cell rendering.

Use property_path for anything nested. The core column type delegates to symfony/property-access, so property_path => 'address.city' works for both arrays and objects. Use a closure/callable column when the value needs computation — don't compute in Blade.

Own sorting and pagination yourself. The grid renders what you give it. Read ?sort= and ?page= in the controller, apply them to the query builder, paginate, then feed $paginator->items() to the data source and pass the paginator to the view separately.

Keep actions as data. For an "Actions" column, build URLs in the controller (or a small presenter) and expose them as row keys, e.g. ['edit_url' => route('users.edit', $u)], then render <a> tags in your Blade partial. This avoids embedding routing into grid definitions.

One Blade partial per grid. Iterate $grid->getColumns() for the header and $grid->getRows() for the body. Because there's no template layer, this partial is your integration point — keep it dumb and escaped.

Compose with custom types and extensions. If you use the same status badge or date format in several grids, register a custom column type or a grid type extension on the factory in the service provider. That's the intended extension seam.

Test with ArrayDataSource. Grid definitions are cheap to unit test: build the grid, pass a fixed array, assert on column names and rendered row values. No database needed.

Gotchas and Tips

  • No framework integration whatsoever. No service provider, no facade, no Blade directives, no pagination. Budget for glue code; that's the main cost of this package in Laravel.
  • Low adoption (14 stars, 0 dependents). Pin the version in composer.json, and consider whether a small in-house table builder would be less risk than an unmaintained dependency for what is essentially column metadata plus a render loop.
  • Escaping is on you. The library does not escape cell output. Always {{ }} in Blade; never {!! !!} for raw column values.
  • Option typos fail quietly. Options are resolved loosely; a misspelled property_path typically yields null cells rather than an exception. When a column is blank, dump the first row's keys before suspecting the library.
  • Data sources are iterated, not cached. If you build a data source from a query builder and iterate it more than once (e.g., header + body in separate loops), verify you're not re-querying. Materialize rows once.
  • Custom types must be registered before grid creation. Adding a column type to the factory after a grid is built won't retroactively apply. Do all registration in the service provider's register().
  • property_path quirks. Missing paths and null intermediate objects behave per Symfony PropertyAccess — it returns null rather than throwing in the default configuration, which masks bad data. Assert on expected columns in tests.
  • Debugging tip: dump($grid->getColumns()) and dump(iterator_to_array($view->getRows())) early; most issues are the wrong data shape (Eloquent models vs. arrays) reaching the data source.
  • Don't reach for this when you need filtering UI, per-column sorting, or pagination out of the box. That's DataTables/Livewire territory. This package is a column-definition and rendering primitive — useful for consistent read-only tables and CSV exports that share column metadata.
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.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib