A library is someone else’s code that you use rather than write. In JavaScript there are three ways to bring one in: a script tag from a CDN, an npm install, or a module import through a bundler. Each suits a different kind of project, and picking the wrong one is why “add a date library” sometimes takes an afternoon.
Method 1: a script tag#
The fastest route, and correct for a single HTML page with no build step:
<script src="https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.11.10/dayjs.min.js"></script>
<script>
console.log(dayjs().format("DD MMMM YYYY"));
</script>
Two rules. Put the library tag before the code that uses it, or the global will not exist yet. And pin an exact version in the URL — a URL ending in “latest” means your page can break because someone else released something.
Method 2: npm#
For anything with a build step or a server:
npm init -y
npm install dayjs
import dayjs from "dayjs";
console.log(dayjs().format("DD MMMM YYYY"));
What the files mean:
package.json— the list of what your project depends on. Commit it.package-lock.json— the exact versions installed, including sub-dependencies. Commit this too; it is what makes installs reproducible.node_modules/— the downloaded code. Never commit it; add it to.gitignore.
npm install --save-dev vitest # tools, not shipped to users
npm ci # exact install from the lock file
npm outdated # what has newer versions
npm audit # known vulnerabilities
Method 3: ES modules from a CDN#
Modern browsers can import directly, with no build step:
<script type="module">
import dayjs from "https://cdn.jsdelivr.net/npm/dayjs@1.11.10/+esm";
console.log(dayjs().format("YYYY-MM-DD"));
</script>
Convenient for prototypes. For production it means an extra connection to someone else’s server on every page load, and your site stops working if theirs does.
Choosing between them#
| Project | Use |
|---|---|
| One HTML file, learning | Script tag from a CDN |
| Anything with a build step | npm |
| Node script or server | npm |
| Quick experiment in the console | ES module from a CDN |
Judging a library before you depend on it#
Adding a dependency is a commitment. Five checks, none of which takes long:
- When was the last release? Years of silence on a browser library usually means trouble ahead.
- How many open issues, and are any answered? A maintainer who replies matters more than a low number.
- How big is it? A 300 kB library to format a date is a bad trade.
- How many dependencies does it drag in? Each one is code you are also trusting.
- What is the licence? MIT and Apache 2.0 are permissive. Anything unusual deserves a read.
Reading documentation efficiently#
In this order:
- The first example on the readme. Get that running unchanged before anything else. It confirms your setup works.
- The installation section. Check whether it needs a peer dependency or a plugin for the feature you want.
- The API list. Skim the function names to learn the shape of the library, not the details.
- The specific page for your task. Only now.
If an example does not work, check the version first. Documentation on a website is usually for the latest release; the version you installed may be older. npm list dayjs tells you what you actually have.
When you do not need a library#
JavaScript has absorbed a lot of what libraries used to provide:
// Instead of jQuery
document.querySelector(".button").addEventListener("click", handler);
element.classList.toggle("active");
// Instead of a request library
const data = await fetch("/api/items").then(r => r.json());
// Instead of a date formatting library
new Intl.DateTimeFormat("en-GB", { dateStyle: "long" }).format(new Date());
// Instead of a number formatting library
new Intl.NumberFormat("en-GB", { style: "currency", currency: "GBP" }).format(42.5);
// Instead of much of lodash
const unique = [...new Set(items)];
const sorted = [...items].sort((a, b) => a.price - b.price);
A useful test: if the library would replace fewer than about twenty lines of code you understand, write the twenty lines.
When a library will not load#
Work through these in order:
- Open the console. A “not defined” error means the script did not load, or ran too late.
- Open the Network tab. A 404 on the library URL is the most common cause and takes two seconds to spot.
- Check the order of your script tags. The library must come first.
- Check the global name. It is not always the package name — the documentation will say what it is.
- For imports, check the module type. “Cannot use import statement outside a module” means you need
type="module"on the tag, or"type": "module"in package.json.
Questions people ask#
What is the difference between a library and a framework?
You call a library; a framework calls you. You decide when to invoke a date library. A framework owns the structure of your application and invokes your code at the points it defines.
Should I commit node_modules?
No. It is large, platform-specific, and fully reproducible from package-lock.json. Commit the lock file instead and run npm ci.
What do the version symbols mean?
A caret allows any release within the same major version at or above the one given. A tilde allows patch releases only. A bare version pins it exactly. The lock file records what was actually installed regardless.
How do I remove a library?
npm uninstall name, then search your code for any remaining imports. Removing the package without removing the imports gives a confusing “cannot resolve” error at build time.
Where to go next#
- Exporting functions in JavaScript — the module syntax libraries use.
- The JavaScript fetch API — the built-in that replaced request libraries.
- Why is my JavaScript not working? — the debugging order above, in full.