Defining a Libraryfor Drupal 8 , 9 , 10 , and 11

Last updated :  

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 required version key
  • 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.

One file, multiple libraries is fine: nothing stops two different library entries in the same .libraries.yml from referencing overlapping files. Libraries are just named bundles — they don't "own" a file exclusively.

Quick check: you change js/accordion.js but forget to bump version. 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.yml at the module root.
  • Referenced elsewhere as module_name/library_name — always the two parts together, never the library name alone.
  • Always bump version when 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.