Managing Library Dependencies in Drupal Without Bloatfor Drupal 11 , 10 , 9 , and 8

Last updated :  

Think of library dependencies like a chain of favors: your library asks for a favor from another, which asks for a favor from a third, and so on. Each favor is reasonable on its own, but a long enough chain means loading one small widget silently drags in a dozen libraries nobody remembers agreeing to. Managing dependencies well means keeping that chain short, explicit, and genuinely necessary — not accumulated by accident.

What you'll learn in this lesson

  • How Drupal resolves a library's full dependency chain, and why you never need to list a dependency's own dependencies
  • The real cost of an unnecessary dependency, even one that "might come in handy"
  • How to check what a library actually depends on before you add it
  • Why core/jquery-style dependencies should be declared explicitly, never assumed to already be loaded

A real dependency declaration

From the Examples module's own js_example.libraries.yml:

colors:
  version: 4.0.0
  css:
    component:
      css/weights.css: {}
  js:
    js/colors.rgb.js: { weight: -2 }
    js/colors.base.js: { weight: -8 }
    js/colors.cmy.js: { weight: -4 }
  dependencies:
    - core/jquery
    - core/drupalSettings

Drupal resolves the chain for you — once

Notice colors lists only core/jquery and core/drupalSettings directly — it doesn't also list whatever those two libraries depend on internally. Drupal's asset resolver walks the full dependency graph automatically and de-duplicates: if five different libraries on a page all depend on core/jquery, jQuery still loads exactly once, in the correct position relative to everything that needs it. Your only job is declaring your library's own direct dependencies, honestly and completely — the transitive resolution is Drupal's problem, not yours.

The real cost of "just in case" dependencies

A dependency you don't actually use isn't free just because Drupal de-duplicates. Every dependency in the chain still has to be resolved, still adds its own file(s) to the aggregate, and still ships bytes to every visitor who loads any library that pulls it in — even if none of your code ever calls into it. A library that depends on core/jquery "in case we need it later" is committing every future page that loads this library to shipping jQuery, whether that future need ever materializes or not.

Before adding a dependency, check what it already pulls in. Open the dependency's own .libraries.yml and read its dependencies key. A library that looks small in isolation might already be the head of a much longer chain — you're not just adding one dependency, you're inheriting everything beneath it too.

Never assume a library is "probably already loaded"

It's tempting to skip declaring core/jquery as a dependency because "some other module on this site definitely loads it already." Don't. That assumption breaks the moment someone disables that other module, or your library gets reused on a site that doesn't have it — and the failure mode is a silent JavaScript error in production, not a helpful message telling you what's missing. Declare every dependency your code genuinely uses, every time, regardless of what else might coincidentally already be on the page.

Quick check: your library's JS file calls jQuery() but doesn't list core/jquery in dependencies. It happens to work today because another library on every page you've tested already loads jQuery first. What happens when a site administrator disables that other module? (If you said "your library's JS breaks with no clear error pointing back to the missing dependency," you've understood exactly why declaring dependencies explicitly — never relying on load-order coincidence — is non-negotiable.)

Key takeaways

  • List only your library's direct dependencies — Drupal resolves the full transitive chain and de-duplicates automatically.
  • An unused "just in case" dependency still costs every page that loads your library extra bytes and resolution overhead — there's no free version of "maybe we'll need it."
  • Check a dependency's own dependencies key before adding it — you inherit its whole chain, not just the one library you named.
  • Never rely on another library "probably" having already loaded a shared dependency like jQuery — declare it explicitly every time your code actually uses it.

Coming up next

With libraries defined, attached, and their dependencies kept lean, the next lesson moves from JavaScript/CSS logic to the raw files themselves — compressing static assets so even a correctly-scoped library ships as few bytes as possible.