Theming Concepts – Libraries System (CSS & JS Management)

In Drupal 10 and Drupal 11, all CSS and JavaScript must be defined and loaded using the Libraries system. This system replaces the old Drupal 7 approach of adding assets directly via PHP or inline markup.

For the Acquia Front End Specialist exam, you must understand:

  • How libraries are defined
  • How they are attached
  • How dependencies work
  • How ordering works
  • How conditional loading works
  • How asset aggregation works
  • Why Drupal enforces this architecture

This is one of the most important frontend architecture topics.


1. Why Drupal Uses a Libraries System

Drupal does NOT allow:

❌ Inline inside Twig
❌ Direct tags inside templates
❌ Random JS injection via PHP

Instead, Drupal uses structured libraries because:

• Enables dependency resolution
• Prevents duplication
• Supports aggregation
• Supports cacheability metadata
• Enables performance optimization
• Improves security

Core classes involved:

  • Drupal\Core\Asset\AssetResolver
  • Drupal\Core\Asset\LibraryDiscoveryParser
  • Drupal\Core\Asset\AttachedAssets

Location:

core/lib/Drupal/Core/Asset/

Drupal 11 continues using the same system.


2. Defining a Library (REQUIRED FILE)

Libraries are defined inside:

theme_name.libraries.yml

Example:

global:
  css:
    theme:
      css/style.css: {}
      css/layout.css: {}
  js:
    js/script.js: {}
  dependencies:
    - core/drupal
    - core/once

Structure:

library_name:
css:
category:
file: {}
js:
file: {}
dependencies:
- other/library

Categories under css:

  • base
  • layout
  • component
  • theme

These affect ordering.


3. Attaching Libraries

There are three primary ways to attach a library.


3.1 Globally (via .info.yml)

libraries:
  - my_theme/global

Use when:

  • CSS/JS is needed site-wide

Be careful — this loads on every page.


3.2 Inside Twig

{{ attach_library('my_theme/global') }}

Use when:

  • Library is needed only for a specific template

Best for component-level JS.


3.3 Inside Preprocess

$variables['#attached']['library'][] = 'my_theme/global';

Use when:

  • Conditional loading based on logic
  • Data-driven decision

4. Dependency Management

Example:

dependencies:
  - core/jquery
  - core/drupal

Drupal ensures:

  1. Dependencies load first
  2. No duplication
  3. Correct execution order

Exam trap:

If your JS uses Drupal behaviors but you forget core/drupal, it may break.


5. Drupal Behaviors Integration

Modern Drupal JS must use behaviors:

(function (Drupal, once) {
  Drupal.behaviors.myBehavior = {
    attach: function (context) {
      once('myBehavior', context.querySelectorAll('.example')).forEach(function (element) {
        console.log('Attached');
      });
    }
  };
})(Drupal, once);

Why?

Because Drupal may re-render content via AJAX.
Behaviors ensure JS reattaches correctly.

Core files:

  • core/misc/drupal.js
  • core/misc/once.js

Drupal 11 still uses this system.


6. Conditional Asset Loading (Performance Critical)

Wrong approach:
Load all JS globally.

Correct approach:
Attach only where needed.

Example scenario:
Only attach carousel.js on homepage.

In preprocess:

if ($variables['is_front']) {
  $variables['#attached']['library'][] = 'my_theme/carousel';
}

This improves:

• Performance
• LCP score
• Reduced JS parsing time


7. Asset Aggregation & Ordering

Drupal can aggregate CSS/JS in:

Admin → Performance → Aggregate CSS/JS

Aggregation works only when assets are defined via libraries.

Ordering rules:

  1. Dependencies first
  2. base → layout → component → theme
  3. Weight if defined

8. Required vs Optional Summary

FileRequiredPurpose
libraries.ymlYESDefine assets
info.yml librariesOptionalGlobal attach
attach_library()OptionalTemplate attach
#attachedOptionalConditional attach

9. Common Mistakes

❌ Inline in Twig
❌ Forgetting dependencies
❌ Loading heavy JS globally
❌ Duplicating library names
❌ Not using behaviors


10. Real Project Scenario

Scenario:
Client requests accordion component only on FAQ page.

Correct approach:

  1. Define faq library
  2. Attach via Twig in node--faq.html.twig
  3. Use behaviors

Wrong approach:
Add JS globally in info.yml.


11. Interview Questions

  1. Why does Drupal use libraries instead of inline scripts?
  2. Explain how dependency resolution works in Drupal libraries.
  3. When should you attach a library in Twig vs preprocess?
  4. What happens if you forget to include core/drupal dependency?
  5. How does aggregation improve performance?

12. Exam-Style Questions

Q1: Where are Drupal theme libraries defined?
A. theme.info.yml
B. theme.theme
C. theme.libraries.yml
D. page.html.twig

Correct: C


Q2: Which is the correct way to attach a library in Twig?
A.
B. {{ attach_library('theme/library') }}
C. drupal_add_js()
D. include_js()

Correct: B


Q3: What ensures JS works after AJAX content replacement?
A. jQuery ready
B. Inline script
C. Drupal behaviors
D. HTML5 defer

Correct: C


13. Quick Cheat Sheet

• Define → libraries.yml
• Global load → info.yml
• Template load → attach_library()
• Conditional load → #attached
• JS must use behaviors
• Dependencies prevent duplication
• Drupal 10 & 11 use same asset system


Final Thoughts

The Libraries system is the backbone of frontend performance and maintainability in Drupal. Mastering it ensures clean architecture, exam success, and production-ready themes.