Use Third-Party JavaScript Libraries

Before you use a third-party JavaScript library, we recommend that you check AppExchange for third-party apps that match your requirements. Alternatively, check if a base component provides your desired functionality.

Tip

You can use third-party JavaScript libraries with Lightning web components. For example, use a library with interactive charts and graphs or a library that reduces code complexity.

  1. Download the library from the third-party library's site.

  2. Upload the library to your Salesforce organization as a static resource, which is a Lightning Web Components content security policy requirement.

  3. In a JavaScript class that extends LightningElement:

    • Import the library by its static resource name.

      import RESOURCE_NAME from "@salesforce/resourceUrl/RESOURCE_NAME";

      For example, if you named the static resource myLib:

      import myLib from "@salesforce/resourceUrl/myLib";
    • Import methods from the platformResourceLoader module.

      import { loadStyle, loadScript } from "lightning/platformResourceLoader";

      See the lightning/platformResourceLoader reference docs.

  4. Load the library and call its functions in a then() method.

    loadScript(this, myLib + "/myLib.js").then(() => { let result = myLib.myFunction(2, 2); });

If your component runs in an org where Lightning Web Security (LWS) isn’t enabled, libraries that are used by your component must meet Lightning Locker requirements. See Determine Whether a JavaScript Library Is Locker Compliant. If the org is using Lightning Web Security (LWS), most third-party libraries work as expected without changes. However, some libraries require changes to work with LWS. See Third-Party Library Considerations for LWS.

Important

DOM Manipulation with JavaScript 

Using JavaScript to manipulate the DOM isn’t recommended because the Lightning Web Components engine does it more efficiently. However, there are some third-party JavaScript libraries that take over the DOM.

Salesforce doesn't provide support for third-party JavaScript libraries. Documentation and examples that demonstrate using a third-party JavaScript library don't constitute an endorsement of the third-party JavaScript library. We recommend that you check the third-party JavaScript library documentation for usage information.

Note

If a call to appendChild() manipulates the DOM, styling isn’t applied to the appended element.

When using these libraries in a Lightning web component, add lwc:dom="manual" to any HTML element that you want to manipulate with JavaScript. When the engine sees the directive, it preserves encapsulation.

Add the lwc:dom="manual" directive to an empty native HTML element. The owner of the component calls appendChild() on that element to manually insert the DOM.

<template> <div lwc:dom="manual"></div> </template>

Example: D3 JavaScript Library 

This example uses the D3 JavaScript library to create an interactive data visualization.

You can follow the example using the libsD3 component from the lwc-recipes repo. If you had deployed lwc-recipes in your org previously, you can skip the first 2 steps. Verify that the d3 JavaScript library is available in the Static Resources page of your Salesforce org.

Tip

A component displaying a graph of colored dots connected by lines. You can click and drag the dots to change the shape of the graph.

To use the library:

  1. Download the D3 JavaScript library at the lwc-recipes repo. At the time of writing, the example uses v5.16.0 of the D3 JavaScript Library.

  2. Compress the JavaScript and CSS files into a zip file. Name the file d3.zip. Upload d3.zip to your org as a static resource.

  3. Create a component to contain the graph. Here, the container is an empty <svg>. The lwc:dom="manual" directive tells LWC that the DOM in the <svg> element has been inserted manually.

<!-- libsD3.html --> <template> <div class="slds-m-around_medium"> <svg class="d3" width={svgWidth} height={svgHeight} lwc:dom="manual"></svg> </div> </template>

In the component’s JavaScript class, import loadStyle and loadScript from lightning/platformResourceLoader. Import the d3 static resource as well. Notice that D3 is the static resource reference for loading the resources, and d3 is the name of the static resource uploaded to Salesforce.

To create the graph, invoke loadStyle and loadScript in renderedCallback() on the first render. Using renderedCallback() ensures that the page loads and renders the container before the graph is created.

Calls to loadStyle and loadScript return promises. Use Promise.all() to aggregate the results and ensure that both files are resolved before invoking the callback. The then() callback is invoked only after the load completes and only if no error occurs. To handle any potential error occurring during the load process, you can provide a catch() callback.

To initialize the graph in the promise callback, call initializeD3(), which reaches into the DOM and gets a reference to the container that displays the graph, here an <svg> element.

// libsD3.js /* global d3 */ import { LightningElement } from "lwc"; import { ShowToastEvent } from "lightning/platformShowToastEvent"; import { loadScript, loadStyle } from "lightning/platformResourceLoader"; import D3 from "@salesforce/resourceUrl/d3"; import DATA from "./data"; export default class LibsD3 extends LightningElement { svgWidth = 400; svgHeight = 400; d3Initialized = false; async renderedCallback() { if (this.d3Initialized) { return; } this.d3Initialized = true; try { await Promise.all([ loadScript(this, D3 + "/d3.v5.min.js"), loadStyle(this, D3 + "/style.css"), ]); this.initializeD3(); } catch (error) { this.dispatchEvent( new ShowToastEvent({ title: "Error loading D3", message: error.message, variant: "error", }), ); } } initializeD3() { // Example adopted from https://bl.ocks.org/mbostock/2675ff61ea5e063ede2b5d63c08020c7 const svg = d3.select(this.template.querySelector("svg.d3")); const width = this.svgWidth; const height = this.svgHeight; const color = d3.scaleOrdinal(d3.schemeDark2); const simulation = d3 .forceSimulation() .force( "link", d3.forceLink().id((d) => { return d.id; }), ) .force("charge", d3.forceManyBody()) .force("center", d3.forceCenter(width / 2, height / 2)); const link = svg .append("g") .attr("class", "links") .selectAll("line") .data(DATA.links) .enter() .append("line") .attr("stroke-width", (d) => { return Math.sqrt(d.value); }); const node = svg .append("g") .attr("class", "nodes") .selectAll("circle") .data(DATA.nodes) .enter() .append("circle") .attr("r", 5) .attr("fill", (d) => { return color(d.group); }) .call(d3.drag().on("start", dragstarted).on("drag", dragged).on("end", dragended)); node.append("title").text((d) => { return d.id; }); simulation.nodes(DATA.nodes).on("tick", ticked); simulation.force("link").links(DATA.links); function ticked() { link .attr("x1", (d) => d.source.x) .attr("y1", (d) => d.source.y) .attr("x2", (d) => d.target.x) .attr("y2", (d) => d.target.y); node.attr("cx", (d) => d.x).attr("cy", (d) => d.y); } function dragstarted(d) { if (!d3.event.active) { simulation.alphaTarget(0.3).restart(); } d.fx = d.x; d.fy = d.y; } function dragged(d) { d.fx = d3.event.x; d.fy = d3.event.y; } function dragended(d) { if (!d3.event.active) { simulation.alphaTarget(0); } d.fx = null; d.fy = null; } } }

In a Lightning web component, you can’t use document to query for DOM elements. Instead, use this.template. For example, this D3 code sample uses this.template.querySelector('svg.d3'). See DOM Access Containment.

Note

Useful Patterns 

Here are some useful patterns for loading your code. This code loads a JavaScript library without a CSS file.

loadScript(this, RESOURCE_NAME + "/lib.js").then(() => { /* callback */ });

This code loads multiple JavaScript files in parallel.

Promise.all([ loadScript(this, RESOURCE_NAME + "/lib1.js"), loadScript(this, RESOURCE_NAME + "/lib2.js"), loadScript(this, RESOURCE_NAME + "/lib3.js"), ]).then(() => { /* callback */ });

See Also

The Summer '25 guide is now live

Looking for the Component Reference? Go to https://developer.salesforce.com/docs/component-library/.