PHPackages                             emulsify-ds/emulsify-drupal - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. emulsify-ds/emulsify-drupal

ActiveDrupal-theme[Utility &amp; Helpers](/categories/utility)

emulsify-ds/emulsify-drupal
===========================

The official Drupal theme for Emulsify, with Storybook and a Vite-based build workflow for generated child themes

7.2.0(2w ago)96561.6k↓42.9%44[5 issues](https://github.com/emulsify-ds/emulsify-drupal/issues)[2 PRs](https://github.com/emulsify-ds/emulsify-drupal/pulls)2GPL-2.0-or-laterTwigCI passing

Since Nov 14Pushed 1mo ago19 watchersCompare

[ Source](https://github.com/emulsify-ds/emulsify-drupal)[ Packagist](https://packagist.org/packages/emulsify-ds/emulsify-drupal)[ Docs](https://www.emulsify.info)[ RSS](/packages/emulsify-ds-emulsify-drupal/feed)WikiDiscussions main Synced 2w ago

READMEChangelog (10)Dependencies (10)Versions (77)Used By (2)

[![Emulsify Design System](https://github.com/emulsify-ds/.github/raw/6bd435be881bd820bddfa05d88905efe29176a0a/assets/images/header.png)](https://github.com/emulsify-ds/.github/blob/6bd435be881bd820bddfa05d88905efe29176a0a/assets/images/header.png)

Emulsify Drupal
===============

[](#emulsify-drupal)

Emulsify is an open-source toolset for creating and implementing design systems on your website
-----------------------------------------------------------------------------------------------

[](#emulsify-is-an-open-source-toolset-for-creating-and-implementing-design-systems-on-your-website)

### Storybook, Emulsify Core 4, and a Vite-based build workflow for Drupal 11.3+

[](#storybook-emulsify-core-4-and-a-vite-based-build-workflow-for-drupal-113)

**Emulsify Drupal** is the official Drupal parent theme for Emulsify. It provides a [Storybook](https://storybook.js.org/) component library, Emulsify Core 4 tooling, and a [Vite](https://vite.dev/)-based build workflow for Drupal 11.3+ with Drupal 12 forward compatibility. Until Drupal 12 beta or stable recommended-project releases are available, Drupal core development branch coverage is experimental.

The current 7.x series no longer depends on `stable9`; Emulsify now ships its own complete template layer instead of inheriting one from a Drupal parent theme.

Documentation
-------------

[](#documentation)

[docs.emulsify.info](https://emulsify.info/docs)

### Quick Links

[](#quick-links)

1. [Installation](https://www.emulsify.info/docs/emulsify-drupal)
2. [Usage](https://www.emulsify.info/docs/emulsify-drupal/basic-usage/commands)
3. [Upgrade guide](./UPGRADE.md)
4. [Twig component includes](./docs/twig-component-includes.md)
5. [Sister-project parity contract](./docs/sister-project-parity.md)
6. [Template override map](./docs/template-map.md)
7. [Favicon generation lifecycle](./docs/favicon-generation.md)
8. [Optional design-token integration](./docs/design-token-integration.md)
9. [Release readiness checklist](./docs/release-readiness.md)

Demo
----

[](#demo)

1. [Storybook](http://storybook.emulsify.info/)

License
-------

[](#license)

Emulsify Drupal is licensed under `GPL-2.0-or-later`, matching Drupal.org Composer metadata guidance for hosted Drupal projects.

How To
------

[](#how-to)

### Generate a child theme

[](#generate-a-child-theme)

Emulsify Tools is required by the Emulsify Drupal parent theme. Use its Drush helper command to generate a child theme:

```
drush emulsify my_theme
```

The helper module also exposes the fully qualified command name:

```
drush emulsify_tools:bake my_theme
```

The `whisk` directory is the Whisk starter source used by both generation methods. Do not enable `whisk` directly; generated child themes keep `emulsify` as their runtime parent theme.

You can also generate the same child theme with Drupal core's standard Starterkit command from the root of your Drupal site:

```
php web/core/scripts/drupal generate-theme my_theme --starterkit whisk --path themes/custom
```

These generation methods should be treated as equivalent:

1. They generate the theme into `web/themes/custom/my_theme`.
2. They use the Whisk starter source.
3. They keep `emulsify` as the runtime parent theme for the generated child theme.
4. They preserve `project.emulsify.json` so Emulsify Core can identify the generated Drupal project structure.
5. They retain `generatedFrom` and `generatedFromVersion` metadata so support tooling can identify the Emulsify Drupal source and version used to create the child theme.

After generation:

1. Enable the theme:

```
drush theme:enable my_theme -y
drush config:set system.theme default my_theme -y
drush cr -y
```

2. Install the generated child theme's frontend dependencies:

```
cd web/themes/custom/my_theme
npm install
```

3. Select and install the project's component library. Whisk does not provide a project source tree or build entrypoints. Its generated Drupal library file contains only commented CSS and JavaScript examples. Follow the component library's setup instructions; once it provides build inputs, update those examples and start the local tooling:

```
npm run develop
```

Generated child themes include the Vite and Storybook tooling from Emulsify Core 4. The selected component library owns the source structure and asset integration those tools consume.

### Write Twig component includes

[](#write-twig-component-includes)

For new project Twig, prefer Drupal Single Directory Component names:

```
{% include "my_theme:list" with {
  items: items,
} only %}
```

The Twig function form is also supported:

```
{{ include("my_theme:list", {
  items: items,
}, with_context = false) }}
```

Replace `my_theme` with the generated child theme machine name. Legacy namespace includes such as `{% include "@components/button/button.twig" %}` are still valid for existing projects and migrations, but they are not the recommended default for new project components. See [docs/twig-component-includes.md](./docs/twig-component-includes.md) for the component include guidance.

### Verify your generated child theme

[](#verify-your-generated-child-theme)

Run the install and test commands from the generated child theme directory, not from `whisk`:

```
cd web/themes/custom/my_theme
node --version
npm install
npm run test
npm run inspect:components
```

The component inspector discovers the project component inventory and reports component metadata, dependencies, configuration issues, and orphaned files. It does not require components to exist, so a newly generated component-neutral theme returns a valid empty report. Use JSON output for automation or view the command help:

```
npm run inspect:components -- --json
npm run inspect:components -- --help
```

After the selected component library supplies project sources, also run its asset-dependent checks:

```
npm run build
npm run storybook-build
```

Generated child themes require Node.js 24 or newer. Use `npm install` for the first local install, or `npm ci` when the generated child theme already has a committed `package-lock.json`.

These checks verify the expected local workflow:

1. `node --version` confirms the Node.js runtime satisfies the generated child theme requirement.
2. `npm install` installs Emulsify Core 4 and the generated child theme tooling.
3. `npm run test` verifies the generated Jest setup. It passes when no project tests exist yet.
4. `npm run inspect:components` reports the component inventory and related project health information.
5. After component-library installation, `npm run build` compiles its Drupal-facing assets with the Vite build workflow.
6. `npm run storybook-build` verifies the component library's static Storybook build.

Optional browser-based accessibility check:

```
npm run a11y
```

`npm run a11y` builds Storybook and runs the Emulsify Core accessibility check. Run it after component-library installation in local or CI environments that can use the required browser-based tooling.

### Manage generated favicon packages

[](#manage-generated-favicon-packages)

The generated favicon workflow is built around one portable SVG source stored in theme settings.

Emulsify Drupal owns the theme-facing parts of that workflow: the theme settings form, config defaults and schema, admin previews, frontend head tags, generated asset references in `.settings`, and sanitized SVG storage for config portability.

1. Configure the package in the theme settings form for `emulsify` or a generated child theme.
2. Save the theme settings form to generate or update the package during normal admin changes.
3. Review package and portable-source diagnostics in the theme settings UI.

Emulsify Tools owns deployment-oriented Drush operations for those same settings. After configuration import or deploy, use the Emulsify Tools favicon commands to generate, inspect, or reset environment-local package files before public traffic reaches the environment. See the Emulsify Tools README for the full command documentation.

Runtime page requests never generate favicon files. If the configured package is missing, Emulsify skips favicon head tags until the theme settings form or the Emulsify Tools generate command creates the package.

Generated favicon packages require the PHP `gd` extension and the `Imagick` extension for SVG rasterization. If either extension is unavailable, the uploaded SVG can still be stored in configuration, but PNG and ICO package generation will fail until those extensions are installed.

The theme settings UI surfaces the current portable-source and package status. Portable SVG copies larger than 256 KB are flagged because very large config payloads are awkward to review and deploy.

See [docs/favicon-generation.md](./docs/favicon-generation.md) for generated files, package location, generator limits, and deployment expectations.

Contributing
------------

[](#contributing)

### [Code of Conduct](https://github.com/emulsify-ds/emulsify-drupal/blob/main/CODE_OF_CONDUCT.md)

[](#code-of-conduct)

The project maintainers have adopted a Code of Conduct that we expect project participants to adhere to. Please read the full text so that you can understand what actions will and will not be tolerated.

### Contribution Guide

[](#contribution-guide)

Please also follow the issue template and pull request templates provided. See below for the correct places to post issues:

1. [Emulsify Drupal](https://www.drupal.org/project/issues/emulsify?categories=All)
2. [Emulsify Tools Drupal Module](https://www.drupal.org/project/issues/emulsify_tools?categories=All)
3. [Emulsify Twig Extensions](https://github.com/emulsify-ds/emulsify-twig-extensions/issues)

### Committing Changes

[](#committing-changes)

To facilitate automatic semantic release versioning, we utilize the [Conventional Changelog](https://github.com/conventional-changelog/conventional-changelog) standard through Commitizen. Follow these steps when committing your work to ensure semantic release can version correctly.

1. Stage your changes, ensuring they encompass exactly what you wish to change, no more.
2. Create a [Conventional Commit](https://www.conventionalcommits.org/en/v1.0.0/) message, either manually or with your preferred commit helper.
3. Your commit message will be used to create the changelog for the next version that includes that commit.

### Release Readiness

[](#release-readiness)

Run the release guard before merging packaging, Whisk starter, favicon settings, or release metadata changes, and before preparing a 7.x release:

```
npm run release:check
```

Use Node.js 24.15 or newer for local release tooling.

Release automation publishes from `main` with non-prefixed SemVer tags.

Use `npm run release:check -- --skip-smoke` when you only want the static metadata, README, duplicate-script, and schema checks. The static checks verify that favicon settings stay aligned across `FaviconSettings::DEFAULTS`, `config/install/emulsify.settings.yml`, and `config/schema/emulsify.schema.yml`.

Author
------

[](#author)

Emulsify® is a product of [Four Kitchens — We make BIG websites](https://fourkitchens.com).

Contributors
------------

[](#contributors)

   [![Brian Lewis](https://avatars.githubusercontent.com/u/1663810?v=4?s=100)
**Brian Lewis**](https://github.com/ModulesUnraveled)
[💻](https://github.com/fourkitchens/emulsify-drupal/commits?author=ModulesUnraveled "Code") [📖](https://github.com/fourkitchens/emulsify-drupal/commits?author=ModulesUnraveled "Documentation") [![Randy Oest](https://avatars.githubusercontent.com/u/409903?v=4?s=100)
**Randy Oest**](https://github.com/amazingrando)
[💻](https://github.com/fourkitchens/emulsify-drupal/commits?author=amazingrando "Code") [📖](https://github.com/fourkitchens/emulsify-drupal/commits?author=amazingrando "Documentation") [![Callin Mullaney](https://avatars.githubusercontent.com/u/369018?v=4?s=100)
**Callin Mullaney**](https://github.com/callinmullaney)
[💻](https://github.com/fourkitchens/emulsify-drupal/commits?author=callinmullaney "Code") [📖](https://github.com/fourkitchens/emulsify-drupal/commits?author=callinmullaney "Documentation") [![Patrick Coffey](https://avatars.githubusercontent.com/u/1107871?v=4?s=100)
**Patrick Coffey**](https://github.com/patrickocoffeyo)
[💻](https://github.com/fourkitchens/emulsify-drupal/commits?author=patrickocoffeyo "Code") [📖](https://github.com/fourkitchens/emulsify-drupal/commits?author=patrickocoffeyo "Documentation") [![Luke Herrington](https://avatars.githubusercontent.com/u/1127238?v=4?s=100)
**Luke Herrington**](https://github.com/infiniteluke)
[💻](https://github.com/fourkitchens/emulsify-drupal/commits?author=infiniteluke "Code") [📖](https://github.com/fourkitchens/emulsify-drupal/commits?author=infiniteluke "Documentation") [![Aaron Couch](https://avatars.githubusercontent.com/u/512243?v=4?s=100)
**Aaron Couch**](https://github.com/acouch)
[💻](https://github.com/fourkitchens/emulsify-drupal/commits?author=acouch "Code") [📖](https://github.com/fourkitchens/emulsify-drupal/commits?author=acouch "Documentation")   [![Marc Berger](https://avatars.githubusercontent.com/u/107938318?v=4?s=100)
**Marc Berger**](https://github.com/codechefmarc)
[💻](https://github.com/fourkitchens/emulsify-drupal/commits?author=codechefmarc "Code") [📖](https://github.com/fourkitchens/emulsify-drupal/commits?author=codechefmarc "Documentation") [![James Todd](https://avatars.githubusercontent.com/u/320747?v=4?s=100)
**James Todd**](https://github.com/techninja)
[💻](https://github.com/fourkitchens/emulsify-drupal/commits?author=techninja "Code") [📖](https://github.com/fourkitchens/emulsify-drupal/commits?author=techninja "Documentation") [![Kurt Trowbridge](https://avatars.githubusercontent.com/u/848721?v=4?s=100)
**Kurt Trowbridge**](https://github.com/KurtTrowbridge)
[💻](https://github.com/fourkitchens/emulsify-drupal/commits?author=KurtTrowbridge "Code") [📖](https://github.com/fourkitchens/emulsify-drupal/commits?author=KurtTrowbridge "Documentation") [![Chris Martin](https://avatars.githubusercontent.com/u/12279982?v=4?s=100)
**Chris Martin**](https://github.com/ccjjmartin)
[💻](https://github.com/fourkitchens/emulsify-drupal/commits?author=ccjjmartin "Code") [📖](https://github.com/fourkitchens/emulsify-drupal/commits?author=ccjjmartin "Documentation") [![Adam Erickson](https://avatars.githubusercontent.com/u/545638?v=4?s=100)
**Adam Erickson**](https://github.com/americkson)
[💻](https://github.com/fourkitchens/emulsify-drupal/commits?author=americkson "Code") [📖](https://github.com/fourkitchens/emulsify-drupal/commits?author=americkson "Documentation") [![Chris Runo](https://avatars.githubusercontent.com/u/1760366?v=4?s=100)
**Chris Runo**](https://github.com/cruno91)
[💻](https://github.com/fourkitchens/emulsify-drupal/commits?author=cruno91 "Code") [📖](https://github.com/fourkitchens/emulsify-drupal/commits?author=cruno91 "Documentation")   [![Andy Carlberg](https://avatars.githubusercontent.com/u/7405933?v=4?s=100)
**Andy Carlberg**](https://github.com/andycarlberg)
[💻](https://github.com/fourkitchens/emulsify-drupal/commits?author=andycarlberg "Code") [📖](https://github.com/fourkitchens/emulsify-drupal/commits?author=andycarlberg "Documentation") [![eatsmarter-benny](https://avatars.githubusercontent.com/u/78405000?v=4?s=100)
**eatsmarter-benny**](https://github.com/eatsmarter-benny)
[💻](https://github.com/fourkitchens/emulsify-drupal/commits?author=eatsmarter-benny "Code") [📖](https://github.com/fourkitchens/emulsify-drupal/commits?author=eatsmarter-benny "Documentation") [![Brian Perry](https://avatars.githubusercontent.com/u/889478?v=4?s=100)
**Brian Perry**](https://github.com/backlineint)
[💻](https://github.com/fourkitchens/emulsify-drupal/commits?author=backlineint "Code") [📖](https://github.com/fourkitchens/emulsify-drupal/commits?author=backlineint "Documentation") [![Israel Shmueli](https://avatars.githubusercontent.com/u/315597?v=4?s=100)
**Israel Shmueli**](https://github.com/israelshmueli)
[💻](https://github.com/fourkitchens/emulsify-drupal/commits?author=israelshmueli "Code") [📖](https://github.com/fourkitchens/emulsify-drupal/commits?author=israelshmueli "Documentation") [![John Karahalis](https://avatars.githubusercontent.com/u/933396?v=4?s=100)
**John Karahalis**](https://github.com/openjck)
[💻](https://github.com/fourkitchens/emulsify-drupal/commits?author=openjck "Code") [📖](https://github.com/fourkitchens/emulsify-drupal/commits?author=openjck "Documentation") [![Mihaic100](https://avatars.githubusercontent.com/u/14100169?v=4?s=100)
**Mihaic100**](https://github.com/Mihaic100)
[💻](https://github.com/fourkitchens/emulsify-drupal/commits?author=Mihaic100 "Code") [📖](https://github.com/fourkitchens/emulsify-drupal/commits?author=Mihaic100 "Documentation")   [![Paul Sebborn](https://avatars.githubusercontent.com/u/147779?v=4?s=100)
**Paul Sebborn**](https://github.com/psebborn)
[💻](https://github.com/fourkitchens/emulsify-drupal/commits?author=psebborn "Code") [📖](https://github.com/fourkitchens/emulsify-drupal/commits?author=psebborn "Documentation")  This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!

###  Health Score

66

—

FairBetter than 99% of packages

Maintenance91

Actively maintained with recent releases

Popularity53

Moderate usage in the ecosystem

Community35

Small or concentrated contributor base

Maturity74

Established project with proven stability

 Bus Factor2

2 contributors hold 50%+ of commits

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~44 days

Recently: every ~15 days

Total

56

Last Release

20d ago

Major Versions

2.x-dev → 3.0.02021-07-01

3.0.2 → 4.0.02021-12-23

4.9.1 → 5.0.02024-06-08

5.4.1 → 6.0.02025-06-03

6.2.0 → 7.x-dev2026-05-30

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/1663810?v=4)[Brian Lewis](/maintainers/ModulesUnraveled)[@ModulesUnraveled](https://github.com/ModulesUnraveled)

![](https://www.gravatar.com/avatar/c0e61c319d853fdc35670358f4d441cfc1167a8e0fbce4f075ca707c916a3fe8?d=identicon)[fourkitchens](/maintainers/fourkitchens)

![](https://www.gravatar.com/avatar/b3097fac15f816b756310b8660da0b23313f50a9c5dd0ad712b06234093cf747?d=identicon)[evanmwillhite](/maintainers/evanmwillhite)

---

Top Contributors

[![ModulesUnraveled](https://avatars.githubusercontent.com/u/1663810?v=4)](https://github.com/ModulesUnraveled "ModulesUnraveled (190 commits)")[![callinmullaney](https://avatars.githubusercontent.com/u/369018?v=4)](https://github.com/callinmullaney "callinmullaney (61 commits)")[![amazingrando](https://avatars.githubusercontent.com/u/409903?v=4)](https://github.com/amazingrando "amazingrando (43 commits)")[![patrickocoffeyo](https://avatars.githubusercontent.com/u/1107871?v=4)](https://github.com/patrickocoffeyo "patrickocoffeyo (36 commits)")[![infiniteluke](https://avatars.githubusercontent.com/u/1127238?v=4)](https://github.com/infiniteluke "infiniteluke (12 commits)")[![acouch](https://avatars.githubusercontent.com/u/512243?v=4)](https://github.com/acouch "acouch (8 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (8 commits)")[![techninja](https://avatars.githubusercontent.com/u/320747?v=4)](https://github.com/techninja "techninja (7 commits)")[![ccjjmartin](https://avatars.githubusercontent.com/u/12279982?v=4)](https://github.com/ccjjmartin "ccjjmartin (6 commits)")[![KurtTrowbridge](https://avatars.githubusercontent.com/u/848721?v=4)](https://github.com/KurtTrowbridge "KurtTrowbridge (6 commits)")[![americkson](https://avatars.githubusercontent.com/u/545638?v=4)](https://github.com/americkson "americkson (5 commits)")[![cruno91](https://avatars.githubusercontent.com/u/1760366?v=4)](https://github.com/cruno91 "cruno91 (3 commits)")[![joetower](https://avatars.githubusercontent.com/u/366413?v=4)](https://github.com/joetower "joetower (1 commits)")[![josue2591](https://avatars.githubusercontent.com/u/9342250?v=4)](https://github.com/josue2591 "josue2591 (1 commits)")[![codechefmarc](https://avatars.githubusercontent.com/u/107938318?v=4)](https://github.com/codechefmarc "codechefmarc (1 commits)")[![backlineint](https://avatars.githubusercontent.com/u/889478?v=4)](https://github.com/backlineint "backlineint (1 commits)")[![andycarlbergbounteous](https://avatars.githubusercontent.com/u/191636412?v=4)](https://github.com/andycarlbergbounteous "andycarlbergbounteous (1 commits)")[![openjck](https://avatars.githubusercontent.com/u/933396?v=4)](https://github.com/openjck "openjck (1 commits)")[![psebborn](https://avatars.githubusercontent.com/u/147779?v=4)](https://github.com/psebborn "psebborn (1 commits)")[![Mihaic100](https://avatars.githubusercontent.com/u/14100169?v=4)](https://github.com/Mihaic100 "Mihaic100 (1 commits)")

### Embed Badge

![Health badge](/badges/emulsify-ds-emulsify-drupal/health.svg)

```
[![Health](https://phpackages.com/badges/emulsify-ds-emulsify-drupal/health.svg)](https://phpackages.com/packages/emulsify-ds-emulsify-drupal)
```

###  Alternatives

[farmos/farmos

A web-based farm record keeping application.

1.3k7.3k1](/packages/farmos-farmos)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
