Create and Activate a Custom Drupal Theme
How to create a custom Drupal theme from scratch and set it as the default.
Generate with Drush
The fastest way to scaffold a theme is with Drush’s code generator:
1
ddev drush generate theme
It will prompt you for:
- Theme name
- Machine name
- Base theme (
stable9recommended for Drupal 10/11) - Whether to include a
*.libraries.yml,*.theme, and starter templates
It outputs the full directory structure into web/themes/custom/. From there, skip to Enable and Set as Default.
If you prefer to build it manually, the structure is as follows.
Directory Structure
Create your theme inside web/themes/custom/:
1
2
3
4
5
6
7
8
9
web/themes/custom/mytheme/
├── mytheme.info.yml
├── mytheme.libraries.yml
├── mytheme.theme
├── css/
│ └── style.css
├── js/
│ └── script.js
└── templates/
mytheme.info.yml
This file is required. Without it Drupal won’t recognise the theme.
1
2
3
4
5
6
7
8
9
10
11
12
13
name: My Theme
type: theme
description: Custom theme for My Site.
core_version_requirement: ^10 || ^11
base theme: stable9
libraries:
- mytheme/global
regions:
header: Header
primary_menu: Primary Menu
content: Content
sidebar: Sidebar
footer: Footer
base theme— inherits templates and preprocessing from the parent. Usestable9for Drupal 10/11,classyfor older.libraries— attaches your CSS/JS globally. Remove if you want to attach per-template instead.regions— defines the available block placement regions. Thecontentregion is required.
mytheme.libraries.yml
Defines asset libraries that can be attached to the theme or templates.
1
2
3
4
5
6
7
8
global:
css:
theme:
css/style.css: {}
js:
js/script.js: {}
dependencies:
- core/drupal
mytheme.theme
Optional PHP file for preprocess functions. See Drupal preprocess functions for usage.
1
2
3
4
5
6
7
8
<?php
/**
* Implements hook_preprocess_HOOK() for page templates.
*/
function mytheme_preprocess_page(&$variables) {
// Add variables to page.html.twig here.
}
Enable and Set as Default
1
2
3
4
5
6
7
8
# Enable the theme
ddev drush theme:enable mytheme
# Set as the default (front-end) theme
ddev drush cset system.theme default mytheme --yes
# Clear cache
ddev drush cr
To set the admin theme separately:
1
ddev drush cset system.theme admin claro --yes
Verify in the UI
Appearance → your theme should show as Installed with a Set as default option if not already set via Drush.
Export Config
After enabling and setting the theme, export config so it’s tracked in version control:
1
2
3
ddev drush cex --yes
git add config/sync/system.theme.yml
git commit -m "Enable mytheme as default theme"