Customizing a Magento 2 store without modifying core files is best accomplished through a child theme. This tutorial covers every step, from choosing a parent theme and setting up the directory structure to registering the theme, overriding styles and templates, and activating it in the admin panel.
Why Use a Child Theme?
A child theme lets you customize your Magento 2 storefront while inheriting all assets from a parent theme. Because you never touch the parent files directly, core and third-party updates can be applied without overwriting your work.
Quick Navigation
- Step 1: Choose the Parent Theme
- Step 2: Create the Directory Structure
- Step 3: Create theme.xml
- Step 4: Create registration.php
- Step 5: (Optional) composer.json
- Step 6: Inherit & Override Assets
- Step 7: Enable & Apply the Theme
- Step 8: Verify & Troubleshoot
Step 1: Choose the Parent Theme
Pick the parent you want to extend -- for example Magento/blank or a third-party theme. Using Magento/blank gives you maximum flexibility.
Step 2: Create the Directory Structure
Create your theme folder under:
app/design/frontend/<Vendor>/<ChildTheme>
Example:
app/design/frontend/MyCompany/CustomTheme
Replace MyCompany and CustomTheme with your own vendor and theme names.
Step 3: Create theme.xml
Place this file at app/design/frontend/MyCompany/CustomTheme/etc/theme.xml:
<?xml version="1.0"?>
<theme xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Config/etc/theme.xsd">
<title>Custom Theme</title>
<parent>Magento/blank</parent>
</theme>
Make sure the <parent> value matches the identifier of the parent theme you chose in Step 1.
Step 4: Create registration.php
Place this at the theme root -- app/design/frontend/MyCompany/CustomTheme/registration.php:
<?php
use Magento\Framework\Component\ComponentRegistrar;
ComponentRegistrar::register(
ComponentRegistrar::THEME,
'frontend/MyCompany/CustomTheme',
__DIR__
);
The path passed to ComponentRegistrar::register must match your folder structure exactly.
Step 5: (Optional) composer.json
Adding a composer.json allows Composer-driven installations:
{
"name": "mycompany/customtheme",
"description": "Magento 2 Child Theme",
"require": {
"php": "~8.1.0",
"magento/theme-frontend-blank": "100.0.*"
},
"type": "magento2-theme",
"version": "1.0.0",
"autoload": { "files": ["registration.php"] }
}
Adjust the PHP version and parent dependency to match your environment.
Step 6: Inherit & Override Assets
Override Styles
Create web/css/source/_extend.less:
// app/design/frontend/MyCompany/CustomTheme/web/css/source/_extend.less
.button { background-color: #F0582A; }
Override Templates
Copy the module template you want to change, keeping the same relative path:
app/design/frontend/MyCompany/CustomTheme/Module_Name/templates/file.phtml
Preserving the directory hierarchy is essential for the override to take effect.
Step 7: Enable & Apply the Theme
Run these commands from the Magento root:
php bin/magento setup:upgrade
php bin/magento setup:static-content:deploy -f
php bin/magento cache:flush
Then in the Admin panel navigate to Content > Design > Configuration and select your new theme.
Step 8: Verify & Troubleshoot
Clear both browser and Magento caches, then refresh the storefront. If styles or templates do not appear, confirm that static content was deployed and caches were flushed.
Always back up your work and test in a development environment before deploying changes to production.
Frequently asked questions
How do I create a Magento 2 child theme?
Create a folder at app/design/frontend/<Vendor>/<ChildTheme>, add etc/theme.xml naming the parent theme, and add registration.php at the theme root. A composer.json is optional. Then run php bin/magento setup:upgrade, php bin/magento setup:static-content:deploy -f and php bin/magento cache:flush, and select the new theme in the Admin under Content > Design > Configuration.
What is the benefit of a child theme in Magento 2?
A child theme inherits all assets from its parent, so the storefront can be customized without touching the parent files. Core and third-party updates can then be applied without overwriting the customizations. Only the files being changed need to live in the child theme, such as an _extend.less file or a copied template.
Which parent theme should a Magento 2 child theme extend?
Magento/blank is the common choice and gives the most flexibility, though a third-party theme can serve as the parent too. The choice is set in the parent element of etc/theme.xml. If the child theme also ships a composer.json, its parent dependency should match, for example magento/theme-frontend-blank for Magento/blank.
What goes in theme.xml for a Magento 2 child theme?
The theme.xml file sits at app/design/frontend/MyCompany/CustomTheme/etc/theme.xml and holds two values, the theme title and its parent. A minimal file has a theme element pointing to urn:magento:framework:Config/etc/theme.xsd, with the title Custom Theme and the parent Magento/blank. The parent value has to match the identifier of the parent theme.
What does registration.php do in a Magento 2 theme?
The registration.php file registers the theme by calling ComponentRegistrar::register with ComponentRegistrar::THEME, the path 'frontend/MyCompany/CustomTheme' and __DIR__. Place the file at the theme root, for example app/design/frontend/MyCompany/CustomTheme/registration.php. The path passed to ComponentRegistrar::register must match the folder structure exactly.
Does a Magento 2 child theme need a composer.json file?
No, composer.json is optional for a Magento 2 child theme. Adding one allows Composer-driven installation. A typical file sets the type to magento2-theme, requires PHP and the parent package magento/theme-frontend-blank, and autoloads registration.php. Adjust the PHP version and the parent dependency to match the environment.
How do I override CSS and templates in a Magento 2 child theme?
For styles, create web/css/source/_extend.less inside the child theme and add the custom rules there. For templates, copy the module template into the child theme under the same relative path, such as app/design/frontend/MyCompany/CustomTheme/Module_Name/templates/file.phtml. Keeping the directory hierarchy identical is what makes a template override take effect.
Why are Magento 2 child theme changes not showing on the storefront?
Clear both the browser cache and the Magento cache, then refresh the storefront. If styles or templates still do not appear, confirm that static content was deployed with php bin/magento setup:static-content:deploy -f and that php bin/magento cache:flush ran afterwards. A template override also needs the same relative directory path as the original file, or it will not take effect.
Read how we handle it in DevOps for e-commerce.
Related Articles
How to Configure Varnish for Magento So It Stops Caching the Wrong Thing
Varnish in front of Magento serves anonymous pages without touching PHP. The wrong Varnish in front of Magento serves one shopper's cart to everybody, which is worse than having no cache at all. Magento generates its own configuration and most of the work is using that rather than something copied from a forum. This covers what the generated file refuses to cache and why, how invalidation actually works as a ban rather than a purge, the two ways it silently fails, and how to prove a page came from cache.
MagentoMagento 2 on Kubernetes: Is It Worth It in 2026?
An honest analysis of running Magento 2 on Kubernetes in 2026, covering persistent storage challenges, Varnish and Elasticsearch in K8s, cost analysis, and when traditional hosting still wins.
MagentoMagento 2 B2B Features: Implementation Guide
Implement Magento 2 B2B commerce features including company accounts, shared catalogs, negotiated quotes, and purchase order workflows for enterprise.