Skip to main content

How to Load Third-Party JavaScript Libraries in Salesforce LWC

In plain words: To use external JavaScript libraries (like Chart.js, D3.js, or Moment.js) in Salesforce LWC, you cannot just link to an external CDN or rely on standard NPM imports. Instead, you must upload the library as a Static Resource and load it securely using the lightning/platformResourceLoader module.

Importing third-party libraries greatly expands what you can build with Lightning Web Components. Instead of reinventing the wheel for complex date formatting, charts, or animations, you can leverage existing open-source libraries. In this guide, we will walk through the official, secure way to implement third-party JS libraries inside Salesforce.

Prerequisites

  • A Salesforce Developer Edition, Sandbox, or Scratch Org.
  • Basic familiarity with JavaScript promises and the LWC lifecycle.
  • The downloaded .js or .zip file of the third-party library you want to use.
Warning Trap: A common mistake for developers coming from standard web development is trying to use npm install and standard dynamic ES6 imports natively inside the Salesforce platform. Due to Lightning Web Security (LWS) and Locker Service restrictions, standard NPM dynamic imports won't work unless you are building an off-platform LWC OSS app. Always use Static Resources for on-platform components.

Step 1: Upload the Library as a Static Resource

First, you need to bring the library's source code into your Salesforce org.

Action Steps:
  • Download the production-ready script (e.g., moment.min.js) from the library's official website.
  • Log into Salesforce, navigate to Setup, and search for Static Resources.
  • Click New. Name the resource momentJS, upload the file, set Cache Control to Public, and click Save.

Step 2: Import the Loader and Static Resource in LWC

In your LWC JavaScript file, you must import the loadScript function alongside the reference to your newly uploaded Static Resource.

import { LightningElement } from 'lwc';
import { loadScript } from 'lightning/platformResourceLoader';
import MOMENT_JS from '@salesforce/resourceUrl/momentJS';

export default class ThirdPartyLibDemo extends LightningElement {
    isLibraryLoaded = false;
    currentDate = '';
}

Step 3: Load the Library in RenderedCallback

To ensure the DOM is ready and the script only loads once, we use the renderedCallback() lifecycle hook combined with a boolean tracking variable.

export default class ThirdPartyLibDemo extends LightningElement {
    isLibraryLoaded = false;
    formattedDate = '';

    renderedCallback() {
        // Prevent the script from loading multiple times
        if (this.isLibraryLoaded) {
            return;
        }
        this.isLibraryLoaded = true;

        // Load the script and handle the promise
        loadScript(this, MOMENT_JS)
            .then(() => {
                this.initializeLibrary();
            })
            .catch(error => {
                console.error('Failed to load the Moment.js library', error);
            });
    }

    initializeLibrary() {
        // The global 'moment' object is now available
        this.formattedDate = moment().format('MMMM Do YYYY, h:mm:ss a');
    }
}

In the corresponding HTML file, you can output your newly formatted date:

<template>
    <lightning-card title="Third-Party Library Demo" icon-name="custom:custom18">
        <div class="slds-p-around_medium">
            <p>Current Formatted Date: <strong>{formattedDate}</strong></p>
        </div>
    </lightning-card>
</template>
360 Architecture Summary:
  • Multiple Files: If your library requires both CSS and JS, use loadStyle alongside loadScript and wrap them in Promise.all([]).
  • Namespace Isolation: Global variables attached to the window object by the library (like moment or d3) become safely available within your component's isolated context.
  • File Size Limits: A single Static Resource can be up to 5 MB in size.

Best Practices for Third-Party Libraries

  • Keep it lightweight: Only import libraries if standard LWC/JavaScript cannot do the job. Modern JavaScript has built-in Intl.DateTimeFormat which often removes the need for heavy date libraries.
  • Check Compatibility: Ensure the library does not attempt to break out of the Shadow DOM or access restricted global objects, as Lightning Web Security (LWS) will block it.
Core Takeaway: To utilize third-party code in Salesforce securely, always upload the library as a Static Resource and initialize it asynchronously via loadScript inside the renderedCallback() hook.