A Drupal themer owns everything between the render array and the browser: Twig templates, preprocess functions, libraries, accessibility and front-end performance. It is a distinct job from front-end development in general, because most of the difficulty is not CSS — it is knowing which of Drupal's templates is producing the markup you want to change, and changing it in a place that survives the next core update.
The theme layer, in the order Drupal actually uses it
Markup in Drupal is produced by a pipeline, and effective theming means intervening at the right point in it rather than at the last one.
- A render array describes what should appear, with its cacheability attached. Nothing is HTML yet.
- Preprocess functions in your
.themefile add or reshape variables before a template sees them — this is where classes and computed values belong. - Theme suggestions decide which template file wins. Core's suggestion hooks, documented in
core/lib/Drupal/Core/Render/theme.api.php, are how you get a different template for one content type, one view mode or one region. - Twig templates print the result, with autoescaping on by default.
- Libraries attach the CSS and JavaScript that page needs, and only that page.
A themer who works at step 4 alone ends up with string manipulation, duplicated markup and CSS that fights itself. Most of the durable wins are at steps 2, 3 and 5.
Do not sub-theme the core front-end theme without reading its warning
This is the most common expensive decision on a new build, and core states the answer in its own files. The first ten lines of core/themes/olivero/olivero.info.yml mark Olivero @internal, warn that it "is not backwards compatible", and offer two options: copy it and rename it as your own theme, or sub-theme it only for minor tweaks, accepting that Olivero may break those tweaks as it changes. core/themes/claro/claro.info.yml carries the same warning for the administration theme.
The supported route is the generator. Core ships a command — registered as generate-theme in core/lib/Drupal/Core/Command/GenerateTheme.php — that copies Starterkit into a theme of your own with your name baked in. Starterkit itself is hidden: true in its .info.yml: it is a source to be copied, not a base theme to inherit from. Drupal 11.4.6 ships Olivero, Claro, Default Admin, Stark, Starterkit and Stable 9, and only two of those are meant to be looked at by visitors.
Single-directory components are in core now — the module is not
Component-based theming is part of core's theme system: the plugin manager lives at core/lib/Drupal/Core/Theme/ComponentPluginManager.php, with validation classes under core/lib/Drupal/Core/Theme/Component/. The old standalone sdc module is still in the tree but its .info.yml now reads lifecycle: obsolete and hidden: true. Any tutorial that tells you to enable the SDC module is describing a Drupal that no longer exists.
What a production theme has that a demo theme does not
- Libraries scoped to where they are used. One global stylesheet is easy and it is why so many Drupal sites ship CSS nobody's page uses.
- Template overrides that are named for a reason. If your templates directory has forty files and nobody can say which page each one serves, the suggestion system is being fought rather than used.
- Real content in testing. Long titles, missing images, two-word headings and a node with fourteen tags break more themes than any browser does.
- Keyboard and screen-reader passes. Not a Lighthouse score — an actual tab through the menu and a listen to the page.
- A documented build. If the CSS is compiled, the next person needs the command, not archaeology.
Two front-end habits show up in reviews constantly and both have their own write-ups: CSS organised by no system at all, covered in SMACSS-based CSS categorisation for Drupal 11 theming, and specificity wars inside a sub-theme, covered in troubleshooting CSS issues in a Drupal sub-theme.
Accessibility is a theming responsibility, not a review stage
Almost every accessibility defect that reaches an audit was created in the theme layer: a heading level skipped for visual reasons, a link whose text is "read more" fourteen times on one page, a colour pair chosen in a design tool that never had contrast checked, a dropdown that works on hover and nowhere else.
One Drupal-specific trap is worth naming because it looks like the safe option: hiding a block title with CSS or with the "display title" checkbox has different consequences for search engines and screen readers, and the two are easy to confuse — that is the subject of why hidden block titles still affect SEO and accessibility.
If accessibility is a contractual requirement on your project rather than a preference, it is worth scoping deliberately; the Drupal services page explains how that is handled as a defined piece of work.
A worked example: how much a theme can expose without custom code
Solo, one of the contributed themes on this site's portfolio, is a useful demonstration of how far the theme settings layer can be pushed, because every number below was counted in its source rather than repeated from its documentation:
- 24 regions plus a hidden region, declared in
solo.info.yml. - 15 colour inputs per region — background, text, headings, links and hover, borders, form fields, menu link colours and four button colours — defined in
_get_region_attributes(). - Five site breakpoints and five menu breakpoints, 576px through 1400px.
- Seven two-column, three three-column and four four-column layout ratios per grouped region.
- Core support declared as
^10.1 || ^11 || ^12in its.info.yml, withphp: ^8.1.
The point is not the count. It is that a theme which exposes settings properly moves work from developers to site builders permanently, and that is the highest-value thing a themer can build. The full breakdown is on the Solo theme page, and per-content-type form theming is covered in customising node edit forms per content type.
Hiring a Drupal themer
Ask to see a theme's templates directory and its libraries.yml before you look at a single screenshot. Then ask three questions:
- "How did you decide which templates to override?" You want to hear about Twig debug output and suggestions, not about copying every template from core.
- "Where do you put a class that depends on a field value?" A preprocess function. If the answer is "in the Twig file" every time, logic and presentation are already mixed.
- "What did you do about the design that could not be built accessibly?" Everyone has met one. The answer tells you whether they push back or quietly ship it.
Common questions
Is a Drupal themer just a front-end developer?
The CSS and JavaScript skills are the same. The difference is the middle layer: render arrays, preprocess, suggestions and libraries. A strong front-end developer with no Drupal experience will produce something that works and is hard to maintain, usually by generating markup outside the theme system.
Should we build a custom theme or configure a contributed one?
If your design is a brand expression with specific layouts, build. If you need a competent, accessible, configurable site and your budget is better spent on content, a well-maintained contributed theme with a sub-theme for your overrides is the cheaper answer and stays upgradeable.
Do we still need a themer if we use Layout Builder?
Yes, and arguably more. Layout Builder moves composition to editors, which increases the number of possible combinations your CSS has to survive. Somebody has to make the components behave in every arrangement an editor can produce.
How long does a custom Drupal theme take?
It depends almost entirely on how many distinct components the design contains and how much of the site's content is already modelled. A theme for a site whose content types are settled is a fraction of the cost of one being built while the content model is still moving.
Next steps
If you already have a theme, the fastest diagnostic is to open Twig debugging and read which templates are rendering on your three most important pages. If the answer is mostly core defaults with a large stylesheet on top, there is real performance and maintainability to recover.
To have that looked at properly, request a quote with your site URL, or get in touch to describe the design problem first. If the work turns out to be back-end rather than presentation, the Drupal developer page covers that side.