Think of your module's CSS and JavaScript files as ingredients sitting loose in a kitchen drawer — flour here, sugar there, no recipe card telling anyone which goes with what. Drupal's .libraries.yml file is that recipe card: it bundles related CSS and JS files into a single named "library," so the rest of Drupal can say "load the accordion library" instead of listing five separate file paths by hand.
What you'll learn in this lesson
- Why Drupal groups assets into named libraries instead of just linking files directly
- The exact YAML shape a library definition takes —
js,css, and the requiredversionkey - How to organize multiple CSS/JS files under one library name
The .libraries.yml file, for real
Every module that ships front-end assets defines them in a file named <module_name>.libraries.yml, sitting at the module's root. Here's a real one, from the Drupal Examples project's js_example module:
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: {}
The top-level key — accordion — is the library's machine name. Referenced elsewhere in code, it's always written as module_name/library_name, so this one is js_example/accordion. Everything indented beneath it describes what the library actually contains.
version — not optional busywork
version: 4.0.0
Drupal aggregates CSS/JS files for performance and generates a unique hash for that aggregated bundle partly from this value. Bump it whenever the underlying file's contents change, and visitors with a cached copy of the old aggregate will correctly fetch the new one instead of silently running stale JavaScript.
js and css — the actual files
js:
js/accordion.js: {}
css:
component:
css/accordion.css: {}
Each file path is relative to the module's root, and the empty {} is where you'd add file-specific options (like a weight — you'll meet that in the next lesson). Under css, the file additionally sits under a category key — component here — which controls where in the page's cascade this stylesheet loads relative to Drupal core's own base/theme/state styles. Getting the category right is what keeps your component's CSS from being unpredictably overridden by a theme's own rules.
.libraries.yml from referencing overlapping files. Libraries are just named bundles — they don't "own" a file exclusively.Quick check: you change
js/accordion.jsbut forget to bumpversion. What actually goes wrong for a visitor who already has the old aggregated bundle cached? (Answer: they keep running the old JavaScript until their cache naturally expires or is cleared — Drupal has no other signal that the file changed, since the aggregate's cache key is derived from this version number, not the file's own modification time.)
Key takeaways
- A library is a named bundle of CSS/JS files, defined in
<module_name>.libraries.ymlat the module root. - Referenced elsewhere as
module_name/library_name— always the two parts together, never the library name alone. - Always bump
versionwhen a referenced file's contents change — it's what busts Drupal's aggregation cache for that library. - CSS files declare a category (like
component) that controls cascade ordering against Drupal core and theme styles.
Coming up next
A library rarely stands alone — your custom JavaScript might need jQuery, or one of your own libraries might need another. Next, you'll add a dependencies key to a library definition and see exactly what breaks if you leave it out.