Overview¶
Magento's stock admin describes a grid or a form as a UI Component: an XML tree that the server turns into a JSON configuration, which a Knockout.js application in the browser turns into HTML. Nebula describes the same screen as a JSON definition that PHP renders into HTML on the server. Alpine.js adds interactivity to that HTML, and Tailwind CSS 4 styles it.
Stock admin Nebula
----------- ------
ui_component/*.xml view/adminhtml/{grid,form,snippet}/*.json
→ XML reader → Loader (one file per module, merged)
→ UI Component JSON config → Merger + SnippetResolver
→ RequireJS + Knockout in browser → Block\Grid / Block\Form + .phtml on the server
→ HTML → HTML, then Alpine.js for state
What is different for you¶
You write JSON, not XML and JavaScript. A grid is a map of columns; a form is a map of fieldsets and fields. Types, filters, sorting, validation rules and options are keys on those maps.
Overlays replace copies. Any module can ship a file with the same name as an existing definition. The engine deep-merges them in module load order. Adding a column to the product grid is a file with one column in it.
Data comes through registered aliases. A definition never names a PHP class. It names a provider alias such as grid.collection and a collection alias such as customer_group.collection, and both are bound in di.xml. That is what keeps a JSON file from instantiating arbitrary classes.
Access is default-deny. Every grid and form carries an acl key. A definition without one is refused for every administrator.
Nothing in Nebula uses Knockout or RequireJS. One core dialog, the shipping label packaging dialog on New Shipment, still bootstraps RequireJS, and only when the order's carrier can print labels. A gate keeps that list from growing.
The pieces¶
| Layer | Lives in | Role |
|---|---|---|
| Definition engine | Nebula_Component |
Loads, merges, resolves and caches definitions. Registries for providers, collections, option sources, renderers and snippet view models. Access control. Lifecycle events. |
| Grid engine | Nebula_Grid |
Renders a grid definition: filters, sort, paging, search, mass actions, export, saved views, quick edit. |
| Form engine | Nebula_Form |
Renders a form definition: fieldsets, 17 field types, layout trees, EAV forms, save pipeline. |
| Shell | Nebula_Core |
The forced admin theme, menu, command palette, configuration screens, dashboard. |
| Content pack | Nebula_Theme and the screen modules |
The definitions, data providers, layout handles and snippets that replace core screens. |
| Theme | design/adminhtml/Nebula/backend |
Tokens, the Tailwind stylesheet, the compiled TypeScript bundles, the page templates. |
The module map lists all 26 modules.
Where interactivity comes from¶
Every admin page loads one core bundle that installs Alpine.js and the primitives every page needs: the model store that owns form values, the validator, toasts, the modal and confirm dialogs, the field components, and the column renderers. Pages that need more load a page bundle on top. Alpine components register on the alpine:init event. Interactivity leads with native HTML: <details> for panels, <dialog> for modals, the Popover API for menus. Alpine is used only where there is real reactive state.
Where styling comes from¶
The theme compiles one stylesheet with Tailwind 4. Design tokens are CSS custom properties named --nebula-*, declared with light-dark() so dark mode is a class on the root element rather than a second stylesheet. A skin is a JSON file that overrides tokens and is injected as an inline style after the stylesheet. See Skins and theming.