• Home
  • Blog
  • Resources
  • About
Authoring Mode
  • Home
  • Blog
  • Resources
  • About
Get in TouchQuestions, collaborations, or just say hello.

Hard work × creativity
Journey to inspire others

Navigation

  • Home
  • Blog
  • Resources
  • About

Connect

  • GitHub
  • LinkedIn
  • Resources

Legal

  • Privacy Policy
  • Sitemap

© 2026 Alicia Snyder · Authoring Mode · All rights reserved

Made with ♥ and lots of Red Bull

  1. Home::
  2. Blog::
  3. AEM Client Library Configuration

AEM Client Library Configuration

A detailed explanation of the clientlib.config.cjs file variables and what the configuration compiles to in an AEM project.

Published:November 20, 2025
Updated:November 2, 2026
AS
Alicia Snyder
November 20, 2025
7 mins read
frontendclientlibsconfigurationwebpackbuild-process

In this configuration how-to, I will explain  clientlib.config.cjs file variables and what the configuration compiles to in an AEM (Adobe Experience Manager) project.

This is a companion guide to HMR & Y. O. U., which covers Hot Module Reloading and the basics of setting up client libraries.

If you've ever worked on the front end of an AEM project, you're probably pretty familiar with clientlibs. But have you ever wondered how your compiled JavaScript and CSS actually end up in AEM? We write our TypeScript, Sass, or whatever else we're using, Webpack compiles everything, and somehow it all ends up neatly organized under /apps. Well, there's a little more going on behind the scenes.

In this article, we're going to look at clientlib.config.js, which is part of a custom front-end build configuration using aem-clientlib-generator.

This isn't an AEM configuration file itself. It's a Node.js configuration that tells the generator where to find our compiled assets, how to organize them into client libraries, and where to put the generated files.

Let's break down what each part does and how everything eventually makes its way into AEM.

Path Variables

Before we start generating anything, we need to tell our build process where to find the compiled front-end files and where to put the generated clientlibs.

We have two important paths:

  • BUILD_DIR — The directory containing our compiled assets. In this example, Webpack outputs everything into ui.frontend/dist.

  • CLIENTLIB_DIR — The location in our Maven project's source tree where aem-clientlib-generator writes the clientlibs. Here, we're using packages/application/src/main/content/jcr_root/apps/myapp/clientlibs.

One important distinction: CLIENTLIB_DIR isn't pointing directly at AEM's JCR repository.

We're still working with files in our local project. Those files eventually get packaged and deployed to the corresponding repository path in AEM. Depending on your project structure, you might see generated clientlibs under ui.apps instead. Both approaches follow the same general idea.

Base Configuration (libsBaseConfig)

PropertyValuePurpose
allowProxytrueAllows AEM to proxy client library requests
serializationFormat'xml'Uses XML format for AEM client library metadata
cssProcessor['default:none', 'min:none']No CSS processing/minification
jsProcessor['default:none', 'min:none']No JS processing/minification

Why Are We Disabling AEM's Minification?

You might have noticed that both cssProcessor and jsProcessor are set to none.

That's intentional. We're already using Webpack to compile and optimize our front-end assets, so we don't necessarily want AEM running another minification pass on the generated files.

Depending on your build configuration, running multiple processors can be unnecessary and can occasionally introduce issues. By disabling AEM's additional processing here, we're leaving that responsibility to our front-end build. Just remember that this assumes your build is already handling optimization appropriately. If it isn't, disabling minification in AEM could mean you're serving larger files than necessary.

Client Library Configurations

clientlib-dependencies

PropertyValuePurpose
Nameclientlib-dependenciesClient library identifier
Categories['myapp.dependencies']AEM category for including this library
DependenciesNoneNo dependencies on other client libraries
EmbedNoneNo embedded libraries
Assets - JScwd: 'clientlib-dependencies'files: ['*/.js']flatten: falseCopies all JS files from dependencies folder
Assets - CSScwd: 'clientlib-dependencies'files: ['*/.css']flatten: falseCopies all CSS files from dependencies folder

Dependencies vs. Embed

Now, these two properties might look pretty similar, but they don't do the same thing.

dependencies tells AEM that another clientlib needs to be included when this one is requested.

For example, if our clientlib-site depends on myapp.dependencies, AEM includes that dependency before our site library. embed, on the other hand, combines the referenced clientlib's contents into the generated output of the embedding clientlib.

So why would we use one over the other?

It depends on how we want those assets delivered. Sometimes we want separate clientlibs, and sometimes we want their contents combined. One thing to keep in mind, especially with AEM as a Cloud Service, is that modern bundlers like Webpack can already handle a lot of our dependency management and asset bundling.

Adobe's current Cloud Service guidance actually discourages relying on clientlib dependencies and embed when they aren't needed. That doesn't mean you'll never see them in an existing project. You absolutely will. But it's worth understanding how they work before deciding whether they're necessary.

clientlib-site

PropertyValuePurpose
Nameclientlib-siteClient library identifier
Categories['myapp.site']AEM category for including this library
Dependencies['myapp.dependencies']Depends on dependencies library
Embed['myapp.grid']Embeds grid system library
Assets - JScwd: 'clientlib-site'files: ['*/.js']flatten: falseCopies all JS files from site folder
Assets - CSScwd: 'clientlib-site'files: ['*/.css']flatten: falseCopies all CSS files from site folder
Assets - Resourcescwd: 'clientlib-site'files: ['*/.']flatten: falseignore: ['/.js', '*/.css']Copies all other files (fonts, images) excluding JS/CSS

Build Process Flow

Mermaid

Preparing diagram…

Final Directory Structure

/apps/myapp/clientlibs/
├── clientlib-dependencies/
│   ├── css.txt              # Lists CSS files for AEM
│   ├── js.txt               # Lists JS files for AEM
│   ├── css/
│   │   └── dependencies.css
│   └── js/
│       └── dependencies.js
└── clientlib-site/
    ├── css.txt              # Lists CSS files for AEM
    ├── js.txt               # Lists JS files for AEM
    ├── css/
    │   └── site.css
    ├── js/
    │   └── site.js
    └── resources/           # Fonts, images, etc.
        ├── fonts/
        │   ├── google/
        │   └── font-awesome/
        └── images/
            ├── png/
            └── svg/

AEM Integration Usage

ContextCode ExamplePurpose
CSS Inclusion<div data-sly-call="{clientLib.css @ categories='myapp.site'}"></div>Includes site CSS in page head
JS Inclusion<div data-sly-call="{clientLib.js @ categories='myapp.site'}"></div>Includes site JavaScript before closing body
Dependenciesclientlib-site automatically loads clientlib-dependencies firstEnsures proper loading order
DevelopmentHot Module Reloading available during developmentLive updates without page refresh

Key Benefits

BenefitDescription
Dependency ManagementAutomatic loading order with dependencies and embed properties
CachingAEM handles client library caching and versioning
MinificationOptional CSS/JS minification through AEM processors
CDN SupportClient libraries can be served from CDN
Development WorkflowHot reloading and live sync during development

Tying It All Together

Let’s chat about how this all fits together and why it’s important for a modern, well-architected project.

Once you understand what clientlib.config.cjs is doing, the process becomes pretty straightforward. Webpack handles compiling our front-end code. aem-clientlib-generator takes that output and organizes it into clientlibs. Maven packages those clientlibs, and our deployment process makes them available to AEM.

The next time your JavaScript or CSS isn't showing up where you expect it, you'll have a much better idea of where to look. Start with the compiled assets. Then check the generator's output, the clientlib configuration, and finally what actually made it into AEM. Because sometimes the problem isn't your JavaScript at all.

Sometimes it just never made it into the package. ;)

Related Posts

How To Render Browser-Stored Content in the Authoring View

How To Render Browser-Stored Content in the Authoring View

11/1/2026
Relationship of Template Types & Templates to Page Components

Relationship of Template Types & Templates to Page Components

11/20/2025
How to Load AEM Dialog Clientlibs in the Create Page Wizard

How to Load AEM Dialog Clientlibs in the Create Page Wizard

11/20/2025
AS

About Alicia Snyder

AEM developer and frontend specialist with expertise in Adobe Experience Manager, React, and modern web development. Passionate about creating accessible, performant web experiences.

Comments

Comments are not yet implemented. This is a placeholder for future comment functionality.