A powerful and flexible grid system for Magento 2 that provides an easy way to create and manage data grids in the admin panel.
Our grid implementation offers several advantages over Magento's legacy grid system:
Supports modern JavaScript features and async/await
Better Performance:
Reduced server load with client-side processing
Enhanced Flexibility:
Simple integration with Magento's UI components
Improved Developer Experience:
Easier to extend and maintain
Better User Experience:
Better mobile support
Advanced Features:
Dynamic data loading
Integration with Magento:
Mage Grid is designed from the ground up to be AI-first. This means:
The design of the Mage Grids makes it easy for AI tools to work with your code. Its open code and simple API allow AI models to read, understand, and generate new components.
You can use AI tools like Cursor to: - Add new data processors (e.g., for custom formatting, badges, or links) - Add or modify grid fields and templates - Inject new JS/HTML for popups, modals, or custom actions - Refactor or optimize code for performance or maintainability
Tip: - The more you describe your intent (in comments, commit messages, or AI prompts), the better the AI can help you extend or refactor the grid.
The Mage Grid module includes an advanced AI Assistant that helps users interact with the grid using natural language queries. The AI Assistant:
cp -r app/code/Mage/Grid /path/to/magento/app/code/
bin/magento module:enable Mage_Grid
bin/magento setup:upgrade
bin/magento cache:clean
view/adminhtml/layout/your_module_grid_index.xml):<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceContainer name="content">
<block class="Mage\Grid\Block\MageGridBlock" name="your_grid">
<arguments>
<argument name="viewModel" xsi:type="object">Mage\Grid\ViewModel\GenericViewModelGrid</argument>
<argument name="collectionClass" xsi:type="string">Your\Module\Model\ResourceModel\YourCollection</argument>
<argument name="fields" xsi:type="array">
<item name="id" xsi:type="string">ID</item>
<item name="name" xsi:type="string">Name</item>
<item name="created_at" xsi:type="string">Created At</item>
</argument>
</arguments>
</block>
</referenceContainer>
</body>
</page>
Controller/Adminhtml/YourGrid/Index.php):<?php
namespace Your\Module\Controller\Adminhtml\YourGrid;
use Magento\Backend\App\Action;
use Magento\Framework\View\Result\PageFactory;
class Index extends Action
{
protected $resultPageFactory;
public function __construct(
Action\Context $context,
PageFactory $resultPageFactory
) {
parent::__construct($context);
$this->resultPageFactory = $resultPageFactory;
}
protected function _isAllowed()
{
return $this->_authorization->isAllowed('Your_Module::your_grid');
}
public function execute()
{
$resultPage = $this->resultPageFactory->create();
$resultPage->setActiveMenu('Your_Module::your_grid');
$resultPage->getConfig()->getTitle()->prepend(__('Your Grid Title'));
return $resultPage;
}
}
The module uses GridJS with Preact for rendering custom column cells. Here's how to create custom column cells:
require(['jquery', 'gridjs'], function($, grid) {
jQuery("#yourGrid").Grid({
columns: [
'Name',
'Email',
{
name: 'Actions',
formatter: (_, row) => html`<button onclick="editItem(${row.cells[0].data})">Edit</button>`
}
],
data: [
['John Doe', 'john@example.com'],
['Jane Smith', 'jane@example.com']
]
});
});
require(['jquery', 'gridjs'], function($, grid) {
jQuery("#yourGrid").Grid({
columns: [
'Order ID',
'Customer',
{
name: 'Status',
formatter: (cell, row) => {
const status = cell;
const color = status === 'Complete' ? 'green' : 'red';
return html`<span style="color: ${color}">${status}</span>`;
}
},
{
name: 'Actions',
formatter: (_, row) => {
const orderId = row.cells[0].data;
return html`
<button onclick="viewOrder('${orderId}')">View</button>
<button onclick="editOrder('${orderId}')">Edit</button>
<button onclick="deleteOrder('${orderId}')">Delete</button>
`;
}
}
],
data: [
['10001', 'John Doe', 'Complete'],
['10002', 'Jane Smith', 'Pending']
]
});
});
require(['jquery', 'gridjs'], function($, grid) {
jQuery("#yourGrid").Grid({
columns: [
'Order ID',
{
name: 'Customer Details',
formatter: async (_, row) => {
const orderId = row.cells[0].data;
const response = await fetch(`/rest/V1/orders/${orderId}`);
const data = await response.json();
return html`
<strong>${data.customer_firstname} ${data.customer_lastname}</strong>
<small>${data.customer_email}</small>
`;
}
}
],
data: [
['10001'],
['10002']
]
});
});
require(['jquery', 'gridjs', 'Magento_Ui/js/modal/alert'], function($, grid, alert) {
jQuery("#yourGrid").Grid({
columns: [
'Order ID',
{
name: 'Actions',
formatter: (_, row) => {
const orderId = row.cells[0].data;
return html`
<button onclick="showOrderDetails('${orderId}')">Details</button>
`;
}
}
],
data: [
['10001'],
['10002']
]
});
window.showOrderDetails = function(orderId) {
alert({
title: 'Order Details',
content: `Loading order ${orderId}...`,
actions: {
always: function() {
// Load order details via AJAX
}
}
});
};
});
require(['jquery', 'gridjs'], function($, grid) {
jQuery("#yourGrid").Grid({
columns: [
'Order ID',
{
name: 'Status',
formatter: (cell, row) => {
const orderId = row.cells[0].data;
return html`
<select onchange="updateStatus('${orderId}', this.value)">
<option value="pending" ${cell === 'pending' ? 'selected' : ''}>Pending</option>
<option value="processing" ${cell === 'processing' ? 'selected' : ''}>Processing</option>
<option value="complete" ${cell === 'complete' ? 'selected' : ''}>Complete</option>
</select>
`;
}
}
],
data: [
['10001', 'pending'],
['10002', 'processing']
]
});
});
The grid supports various configuration options:
<argument name="collectionClass" xsi:type="string">Your\Module\Model\ResourceModel\YourCollection</argument>
<argument name="tableName" xsi:type="string">your_table_name</argument>
$ claude mcp add magento_gridjs \
-- python -m otcore.mcp_server <graph>