Skip to content

Development Setup ​

This page sets up a Magento project for working on Lynx-based code: your own modules, components and themes. For a plain store install, Installation is enough.

Requirements ​

Version
MagentoMagento Open Source 2.4
PHP8.2 or newer, within the versions your Magento release supports
Node.js22.12 or newer, with npm, wherever the frontend is built

Node.js is only needed to build. The store itself runs on PHP alone, unless you run the SSR renderer as a Node.js process.

Lynx is a storefront stack of its own and cannot be combined with Hyvä: the two render the storefront in different ways (Hyvä: layout XML and .phtml with Alpine.js; Lynx: Vue components on Inertia.js). Do not install both, and expect an extension's Hyvä compatibility module to do nothing on Lynx.

Installing the packages ​

Install Lynx as on a store, following Installation; the packages are listed in Packages. Turning off Magento's merging and Inline Translation applies to development stores too.

Keep packages inside the project root

The Vite dev server only serves files inside the Magento root. Modules and themes in app/code, app/design or vendor are fine.

Your own module ​

A module that adds Lynx pages or components depends on the Lynx modules it uses. Declare them in composer.json and in etc/module.xml, so your di.xml entries merge after theirs:

xml
<!-- etc/module.xml -->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Vendor_Module">
        <sequence>
            <module name="OOCS_LynxComponent"/>
            <module name="OOCS_LynxInertia"/>
            <module name="OOCS_LynxPageBuilder"/>
        </sequence>
    </module>
</config>

Frontend sources go in view/frontend/lynx/vue/src. See Creating Components.

Store configuration ​

  • Assign Lynx Vue (or your child theme) to the store view in Content › Design › Configuration.
  • Keep Magento's CSS merging, JS merging, JS bundling, "move JS to bottom" and Inline Translation off for Lynx store views. The commands are in Installation.
  • Keep Magento_Wishlist enabled: Lynx replaces its customer-data section.
  • Pick a design in Stores › Configuration › Lynx › Theme Settings (the default one works for development).

Setting up a theme ​

Every Lynx theme has a lynx/ folder with its package.json, Vite config and entry point. That folder is its own npm project with its own node_modules (about 470 MB for Lynx Vue). Modules contribute sources from view/frontend/lynx/vue/src.

The theme's lynx/package.json is committed and no command writes it. Besides the theme's own packages (ESLint, fonts…), it declares the key the setup needs:

json
"workspaces": [".lynx"]

Set up the themes you build:

bash
bin/magento lynx:theme:setup OOCS_LynxVue

The command writes <theme>/lynx/.lynx/package.json, a generated package (gitignored) that holds:

KeyContent
dependenciesThe npm packages of the Lynx build kit (@oocs/lynx-vue) and of every enabled module that has a view/frontend/lynx/vue/package.json. Packages the theme declares itself are left out.
lynx.modulesEvery enabled module that has a view/frontend/lynx/vue/src folder, mapped to its folder. Only these modules are compiled into the bundle.
lynx.parentsThe folders of the parent themes, so the build can resolve overrides

It then runs npm install in the theme's lynx/ folder when that package changed. When two sources (two modules, or a module and the theme) pin the same package to different versions, setup stops and names both. Without theme names, it sets up every theme set up before; --list shows the Lynx themes the installation has.

A module brings npm packages by listing them in its own view/frontend/lynx/vue/package.json; its sources are built either way. Nobody runs npm install in a module. To add a package to a theme only, run npm install <package> in the theme's lynx/ folder and commit its package.json.

Run it again when modules change

lynx:static:deploy and lynx:static:test install nothing. When a theme's installed packages no longer match the enabled modules and the build kit, they stop with Not set up for the enabled modules and the kit. Run lynx:theme:setup again after enabling or disabling a module, a composer update, a module changing its npm packages, or a change to the theme's own package.json (pulled from your repository, for example).

Building the frontend ​

bash
bin/magento lynx:static:deploy            # every theme set up
bin/magento lynx:static:deploy OOCS_LynxVue

lynx:static:deploy runs npm run build in each theme's lynx/ folder; you can also run npm run build there yourself. A theme build type-checks first (vue-tsc), so a type error fails the build.

Each theme prints one summary line, plus any warning and the chunks built from theme overrides:

[lynx] 94 chunks · JS 1250.9 kB (407.3 kB gzip) · CSS 118.7 kB (19.4 kB gzip) · 2.1s

Add -v (bin/magento lynx:static:deploy -v) for npm's full output, Vite's per-file table and the source of every chunk.

Before committing, run npm run lint (ESLint over the theme, its parent themes and the enabled modules; npm run lint -- --fix fixes what it can) and npm run format (Prettier; format:check only checks) in the theme's lynx/ folder.

Output goes to the theme's web/js/lynx/ and web/css/lynx/. Magento publishes those like any theme asset, so in production mode run bin/magento setup:static-content:deploy afterwards. Always build before the static content deploy; the other way round publishes the previous bundles.

SSR bundles ​

RendererBuild
Node.jsbin/magento lynx:static:deploy --ssr, or npm run build:ssr in the theme's lynx/ folder. Output: lynx/dist/ssr/nodejs/server.mjs.
Cloudflare Workernpm run build:ssr:worker in the theme's lynx/ folder, then npm run deploy:ssr:worker.

Rebuild and restart (or redeploy) the renderer whenever you rebuild the client, so both run the same code. See Running the renderer.

The editor ​

The PageBuilder editor in the admin is a separate build, outside the storefront themes. It ships prebuilt in view/adminhtml/web/js/pagebuilder/ of OOCS_LynxPageBuilder, so a store does not build it. Rebuild it only after changing its sources in view/adminhtml/pagebuilder, or for an enabled editor extension that does not ship its bundle prebuilt:

bash
bin/magento lynx:pagebuilder:build

It runs npm ci and npm run build in the editor of OOCS_LynxPageBuilder and of every enabled extension, stopping at the first failure. Run it before setup:static-content:deploy, and commit the output with the sources.

Compiling module XML ​

bash
bin/magento lynx:compile

On every config cache miss, Magento merges the XML files of all modules (events.xml, routes.xml, config.xml, webapi.xml, acl.xml, translations, the lynx_*.xml layouts of each Lynx theme…), and some files such as view.xml are read on every request. lynx:compile performs those merges once and writes the results as PHP files in generated/lynx_compile/; Magento's readers are replaced by versions that load the file when it exists and merge as usual when it does not. It is optional, and the store works without it, only slower on cache misses; run it when the store goes live. Once used, it is a snapshot: run it again after every change to module XML, including in third-party modules. setup:upgrade, module:enable and module:disable delete generated/lynx_compile together with generated/code, so run it again after those too. Run it after setup:upgrade and setup:di:compile, since the translation step needs stores and themes in the database. To drop the snapshot, use Flush Lynx Compile in System › Cache Management, or delete generated/lynx_compile. Pass names to compile only some parts, such as bin/magento lynx:compile events routes; bin/magento lynx:compile --help lists them.

TIP

In development, simply do not run lynx:compile, or flush it after XML changes. A forgotten snapshot is the usual reason an observer, route or config value "does nothing".

Day-to-day workflow ​

You changedThen run
A .vue or .ts filenpm run build (or bin/magento lynx:static:deploy), then reload the page. In production mode also setup:static-content:deploy.
di.xml (components, settings, providers, pools, plugins)bin/magento cache:clean config full_page. In production mode also setup:di:compile.
events.xml, routes.xml, config.xml or other module XMLbin/magento cache:clean config, plus lynx:compile if you use it
A lynx_*.xml layout filebin/magento cache:clean layout full_page, plus lynx:compile layout if you use it
Layout rows written by a data patch or directly in the databasebin/magento cache:clean lynx_component full_page
An etc/components/*.graphqls file, or a module enabled or disabledbin/magento cache:clean lynx_component full_page, then bin/magento lynx:static:deploy (props types, containers and events)
What a provider returnsbin/magento cache:clean full_page (the full page cache holds both the HTML and the Inertia JSON)
A CSV translationbin/magento cache:clean translate full_page, plus lynx:compile translate if you use it
Enabled, disabled or added a module with frontend sources, ran composer update, or changed a module's npm packagesbin/magento lynx:theme:setup <themes>, then build

Lynx uses Magento's static deployment version as its asset version. When it changes, open tabs reload the page on their next click instead of mixing old JavaScript with new props.

CLI reference ​

CommandArguments and optionsWhat it does
lynx:theme:setup[theme...] themes to set up, such as OOCS_LynxVue; none means every theme set up before
--list list Lynx themes and stop
--npm=<binary> npm to run (default: LYNX_NPM, then npm on PATH)
Writes each theme's lynx/.lynx/package.json from the build kit and the enabled modules, then runs npm install in the theme's lynx/ folder.
lynx:static:deploy[theme...] themes to build; none means every theme set up
--ssr also build the Node.js SSR bundle (npm run build:ssr)
--list, --npm as above
Runs npm run build in each theme's lynx/ folder. Stops when a theme is not set up for the enabled modules.
lynx:pagebuilder:build--npm=<binary> npm to run (default npm)Runs npm ci and npm run build for the PageBuilder editor and every enabled extension. Only needed after changing the editor's sources: it ships prebuilt.
lynx:compile[type...] parts to compile; none means all (listed in --help)Writes merged module XML and translations to generated/lynx_compile.
lynx:mcp:serve--host address to listen on (default 127.0.0.1)
--port (default 7361)
--max-children requests handled at the same time (default 8)
--timeout seconds before a request is killed (default 120)
Runs the MCP server. See MCP Server.
lynx:mcp:tools--details full description and input schema
--json everything, as JSON
Lists the MCP tools.

Theme names are the theme code with _ instead of / (frontend/OOCS/LynxVue → OOCS_LynxVue). A theme counts as buildable when it has a lynx/package.json.