Picture a delivery truck that drops off every package on its route to every house, whether that house ordered anything or not. That's what a bloated Drupal library does to every page load: it ships jQuery, three unrelated widgets, and a stylesheet nobody asked for, just because they all live in the same file. A well-defined .libraries.yml library is the opposite — a precisely addressed parcel, sent only to the page that actually needs it.
What you'll learn in this lesson
- How Drupal's
.libraries.ymlfile groups CSS/JS into named, independently-loadable bundles - Why splitting one big library into several small ones reduces wasted bytes on every page
- How
dependencieslet one library pull in exactly what it needs — nothing more - How
versionfeeds into asset-hash generation, and why forgetting to bump it causes stale-cache bugs
A real library definition, line by line
Here's a genuine .libraries.yml file from Drupal's own Examples module, defining two separate libraries:
accordion:
# Starting from Drupal 10.1.2, the version information plays a critical role
# in generating a unique hash for aggregated files. It is important to update
# the version value whenever a referenced file undergoes changes.
version: 4.0.0
js:
js/accordion.js: {}
css:
component:
css/accordion.css: {}
colors:
version: 4.0.0
css:
component:
css/weights.css: {}
js:
# We use weight as example attribute. Its usage is discouraged, though;
# dependencies should instead be used.
js/colors.rgb.js: { weight: -2 }
js/colors.base.js: { weight: -8 }
js/colors.cmy.js: { weight: -4 }
dependencies:
- core/jquery
- core/drupalSettings
Two libraries, not one
Notice this file defines accordion and colors as two completely separate top-level keys — two independent libraries a page can attach individually. A page that only needs the accordion widget never loads the color-picker JavaScript, and vice versa. This is the single biggest lever in "minimal libraries": don't bundle unrelated functionality into one library just because it's convenient to write once. Every unattached-but-still-loaded byte is pure waste.
css.component vs. a bare css key
CSS assets are grouped by SMACSS category — base, layout, component, state, or theme. Using component here tells Drupal's aggregator this stylesheet styles a specific, self-contained widget (the accordion), which affects load order relative to other categories. Getting the category right isn't cosmetic — it's part of how Drupal decides what can safely be aggregated together.
dependencies: pull in only what you need
dependencies:
- core/jquery
- core/drupalSettings
The colors library declares its own dependencies explicitly rather than assuming jQuery is "probably already loaded somewhere." This is the correct pattern: Drupal resolves the dependency graph and loads core/jquery exactly once, however many libraries depend on it — you never need to (and shouldn't) list a dependency's own dependencies again.
weight to force load order (as `colors` does for its three JS files) is fragile and discouraged for anything beyond same-library file ordering. If library B genuinely needs library A to load first, express that with dependencies, not a weight number you have to keep synchronized by hand.Why version isn't optional
Since Drupal 10.1.2, version feeds directly into the hash Drupal generates for aggregated file URLs. Change a file's contents but forget to bump version, and visitors with a cached copy of the old aggregate may keep serving stale CSS/JS indefinitely — a genuinely confusing bug to track down, since the deployed code is correct and the browser cache is "wrong" for a reason nobody can see. Bump the version number every time you meaningfully change a library's files.
Quick check: you have a library used by exactly one page on a low-traffic admin screen, bundled together with a library used on every single front-end page. What's the actual performance cost of leaving them combined? (If you said "every front-end visitor downloads code for a screen they'll never see," you've got the core idea — the fix is splitting them into two separate library keys, exactly like
accordionandcolorsabove.)
Key takeaways
- Each top-level key in a
.libraries.ymlfile is an independently attachable library — split unrelated functionality into separate libraries rather than bundling it into one. - Use
dependenciesto pull in another library's assets; never hand-list a dependency's own dependencies. - CSS files are grouped by SMACSS category (
base/layout/component/state/theme) — pick the category that matches what the CSS actually does. - Avoid
weightfor ordering between libraries; reach fordependenciesinstead. Weight is only reasonable for ordering files within the same library. - Bump
versionwhenever a library's files change — Drupal 10.1.2+ uses it to generate the aggregation hash, and forgetting causes silent stale-cache bugs.
Coming up next
Defining a lean library is only half the job — the next lesson covers the other half: attaching it conditionally, so even a perfectly minimal library only loads on the pages that actually need it.