clientlib Articles / Blogs / Perficient https://blogs.perficient.com/tag/clientlib/ Expert Digital Insights Wed, 22 Oct 2025 14:09:01 +0000 en-US hourly 1 https://blogs.perficient.com/files/favicon-194x194-1-150x150.png clientlib Articles / Blogs / Perficient https://blogs.perficient.com/tag/clientlib/ 32 32 30508587 Mastering Modular Front-End Development with Individual AEM ClientLibs https://blogs.perficient.com/2025/10/22/quit-bundling-all-your-code-together/ https://blogs.perficient.com/2025/10/22/quit-bundling-all-your-code-together/#respond Wed, 22 Oct 2025 11:37:35 +0000 https://blogs.perficient.com/?p=387954

Are you still combining everything into a single clientlib-all for your entire AEM project? If that sounds like you, then you are probably dealing with heavy page loads, sluggish deployments, and tangled code that’s hard to manage.

Here is the fix: break up those ClientLibs!

By tapping into modern build tools like Webpack through the ui.frontend module, you can build individual, focused Client Libraries that really boost performance, make things more straightforward, and keep your code much easier to maintain.

Why You Really Need Individual ClientLibs

Ditching that one huge ClientLib is not just about keeping things neat, and it gives you some solid technical wins.

1) Better Performance Through Smart Loading

When you use just one ClientLib, every bit of CSS and JavaScript gets loaded on every single page. But when you split things up into libraries that focuses on specific needs (like clientlib-form or clientlib-carousel) you are only pulling in the code you need for each template or component. This significantly reduces the initial page load time for your visitors.

2) Adaptive Cache Management

When you tweak the CSS for just one component, only that small, specific ClientLibs cache gets cleared out. Your large Vendor ClientLib, which rarely changes, remains in the user’s browser cache, resulting in better caching for repeat visitors and reduced server workload.

3) Cleaner Code That’s Easier To Work With

When you use separate ClientLibs, you are basically forcing yourself to keep different parts of your code separate, which makes it way easier for new developers to figure out what’s going on:

  • Vendor and Third-Party Information: Gets its own dedicated library
  • Main Project Styles: Goes in another library
  • Component-Specific Features: Each gets its own detailed library

 

The Current Way of Doing Things: Webpack Plus Individual ClientLibs

Today’s AEM projects use the typical AEM Project Archetype setup, which keeps the source code separate from how things get deployed:

ModuleRoleKey Function
ui.frontendSource & BuildContains all source files (JS/CSS/Less/Sass) and the Webpack configuration to bundle and optimize them.
ui.appsDeploymentReceives the final bundled assets from ui.frontend and deploys them into the JCR as ClientLibs.

Step 1: Organize Your Source Code (in the ui.frontend)

You’ll want to structure your source code in a way that makes sense, keeping it separate from your Webpack setup files.

/ui.frontend
    /src
        /components
            /common
                /card.css
                /card.js
                /index.js       <-- The Webpack Entry Point
            /vendor            
                /select2.css
                /select2.js

 

Why index.js is So Useful: Rather than letting AEM manually piece together files, we use one main index.js file as our single Webpack starting point. This file brings in all the component files you need: – Webpack handles the bundling from here

// ui.frontend/src/components/common/index.js

Main Index Include All Css Js

Step 2: Configure Webpack Output & ClientLib Generation

Your Webpack setup points to this main index.js file. Once it’s done compiling, Webpack creates the final, compressed bundle files (like clientlib-common.css, clientlib-common.js) and puts them in a target folder usually called dist.

Common Component Bundle

Step 3: Deploy the Bundle (The ui.apps ClientLib)

The last crucial step involves putting these bundles into the AEM ClientLib structure inside your ui.apps module.

This usually happens automatically through a Maven plugin.

Your ClientLib needs to have a unique category property, that is how you’ll reference it in your components.

Path in JCR (deployed through ui.apps)

Aem Module 1

/apps/my-project/clientlibs/clientlib-common
    /css
        clientlib-common.css     //The bundled Webpack output
    /js
        clientlib-common.js      //The bundled Webpack output
    /.content.xml           // <jcr:root jcr:primaryType="cq:ClientLibraryFolder" categories="[my-project.common]"/>
    /css.txt                //Lists the files in CSS folder
    /js.txt                 // Lists the files in JS folder

Step 4: Bundle Things Together with the Embed Property

While you can load a single clientlib-common, a better practice is to have a master ClientLib that loads everything the site needs. This library utilizes the powerful embed property to incorporate the contents of smaller, targeted libraries.

The Main Aggregator ClientLib ( In clientlib-site-all )

Siteall

The embed feature is essential here. It combines all your JS and CSS files into one request when the site runs, but your original ClientLibs stay organized separately in the JCR, which keeps things tidy.

Step 5: Add the Libraries to Your HTL

When it comes to your page component or template, you just need to reference that main, bundled ClientLib category using the regular Granite ClientLib template:

Htl

By setting up separate, Webpack-built ClientLibs, you are building a solid, modular, and fast front-end setup. Your ui.frontend takes care of organizing and bundling everything, while your ui.apps module handles getting it all into the AEM JCR.

Do not keep wrestling with those big, unwieldy systems; start using categories and embedding to break up your code correctly.

 

]]>
https://blogs.perficient.com/2025/10/22/quit-bundling-all-your-code-together/feed/ 0 387954