UI components are how Magento builds admin grids and forms - the product grid, the order grid, every edit form in the backend. They are also famously intimidating: XML files that generate JavaScript configurations that render KnockoutJS templates. Once you see the pipeline, though, they become predictable. This is the mental model that makes them tractable.
The Three Layers
A UI component has three cooperating parts:
- XML declaration (
view/adminhtml/ui_component/*.xml): declares the structure - columns, fields, data source, buttons - PHP DataProvider: supplies data to the component from your models or collections
- Generated JS configuration: Magento merges the XML into a JSON config consumed by its JS component registry (
uiRegistry)
The key insight: the XML is not a template. It is a configuration that Magento transforms into a nested JavaScript component tree. Debugging means reading the generated JSON in the browser (the uiRegistry), not staring at XML alone.
A Minimal Grid
view/adminhtml/ui_component/acme_location_listing.xml:
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<argument name="data" xsi:type="array">
<item name="js_config" xsi:type="array">
<item name="provider" xsi:type="string">acme_location_listing.acme_location_listing_data_source</item>
</item>
</argument>
<dataSource name="acme_location_listing_data_source">
<argument name="dataProvider" xsi:type="configurableObject">
<argument name="class" xsi:type="string">Acme\Locations\Ui\DataProvider\Listing</argument>
<argument name="name" xsi:type="string">acme_location_listing_data_source</argument>
</argument>
</dataSource>
<columns name="spinner_columns">
<column name="name">
<settings>
<label translate="true">Name</label>
<sortable>true</sortable>
</settings>
</column>
</columns>
</listing>
The DataProvider wraps your collection and returns rows in the shape the component expects. Filters, sorting and paging come from request parameters Magento applies for you if you let the provider extend the standard classes.
Forms Work the Same Way
A form component declares fieldset and field nodes; its DataProvider loads the entity and supplies data keyed by field name. Modifiers (Magento\Ui\DataProvider\Modifier\ModifierInterface) let PHP alter form data per request - the standard way to add dynamic options or conditional fields without hacking the XML.
Debugging Survival Kit
- In browser console:
require('uiRegistry').get('acme_location_listing.acme_location_listing_data_source')to inspect the live component tree - Most “my column doesn’t show” bugs are a
providername mismatch betweenjs_configand the dataSource - Clear
var/view_preprocessedand the generated metadata when XML changes seem ignored - The core’s own
product_listing.xmlis the best reference implementation in existence - copy its patterns before inventing your own
UI components have a steep first day and a flat second year. Build one grid and one form following the core’s own files, and every admin interface after that is the same recipe with different fields.