Get Started: CDN, npm & Vite

Bootstrap · Lesson 2 of 28 8 min read Updated

Before you can use a single Bootstrap class, the browser has to load Bootstrap's CSS and JavaScript. There are three common ways to do that, and each suits a different kind of project.

In this lesson you will use the CDN starter template, learn how to host the files yourself, and set up a real project with npm and Vite, which is how most professional teams work today.

Three ways to add Bootstrap

MethodBest forNeeds Node.js?
CDN linksLearning, quick prototypes, simple sitesNo
Download the compiled filesSites that must work offline or on an intranetNo
npm + a build tool (Vite)Real projects, customising colours with Sass, smaller filesYes

All three give you the same Bootstrap. The difference is where the files come from and how much control you have.

Option 1: the CDN starter template

A CDN (Content Delivery Network) hosts the files on fast servers around the world. You only add two lines. This is the template every example in this tutorial uses, so keep a copy of it.

HTMLTry it yourself
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Bootstrap starter</title>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
  <div class="container py-4">
    <h1>It works!</h1>
    <p id="status" class="text-body-secondary">Checking Bootstrap...</p>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js"></script>
  <script>
    // Every Bootstrap plugin has a VERSION property, so this proves the JavaScript loaded.
    document.getElementById("status").textContent = "Bootstrap " + bootstrap.Modal.VERSION + " is ready.";
  </script>
</body>
</html>

Three details matter here:

  • The version number is in both URLs (bootstrap@5.3.8). Always pin an exact version, so your site does not change when a new release appears.
  • The CSS goes in the <head>, so the page is styled before it is shown.
  • The JavaScript goes just before </body>, so the HTML exists before the script looks for it. You could also put it in the <head> with the defer attribute.

The bundle file (bootstrap.bundle.min.js) contains Bootstrap's JavaScript plus Popper, a small library that positions dropdowns, tooltips and popovers next to the element that opened them. If you use bootstrap.min.js (without "bundle"), you must load Popper yourself first.

Option 2: download the compiled files

On getbootstrap.com you can download a zip of the ready-to-use files. Unzip it into your project, and you get a structure like this:

Text
tiffin-site/
  index.html
  css/
    bootstrap.min.css
    bootstrap.min.css.map
  js/
    bootstrap.bundle.min.js
    bootstrap.bundle.min.js.map

Then link the files with relative paths instead of CDN URLs:

HTML
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- ... page content ... -->
<script src="js/bootstrap.bundle.min.js"></script>

The .map files are source maps. They are only used by browser developer tools to show readable code, so they are optional. This method works without the internet, which is useful for a college lab or an office intranet. If the page appears unstyled, the path is almost always wrong; see File Paths.

Option 3: npm and Vite

Professional projects install Bootstrap with npm, the package manager that comes with Node.js, and use a build tool that bundles your files for the browser. Vite is the most popular choice today: it gives you a fast development server that reloads as you save, and a build command that produces small, optimised files. You need Node.js installed (see npm & Tooling).

Run these commands in a terminal, one at a time:

Terminal
mkdir tiffin-site
cd tiffin-site
npm init -y
npm install bootstrap @popperjs/core
npm install --save-dev vite sass

bootstrap and @popperjs/core are the libraries your site uses. vite and sass are development tools only, so they go in devDependencies. Now create three files:

Text
tiffin-site/
  index.html
  src/
    main.js
    styles.scss
  package.json
HTML
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Sharma Tiffin Service</title>
  <script type="module" src="/src/main.js"></script>
</head>
<body>
  <div class="container py-4">
    <h1>Sharma Tiffin Service</h1>
    <button class="btn btn-primary">Order lunch</button>
  </div>
</body>
</html>
SCSS
// src/styles.scss
@import "bootstrap/scss/bootstrap";
JavaScript
// src/main.js
import "./styles.scss";
import * as bootstrap from "bootstrap";

Add scripts to package.json so you have short commands:

JSON
{
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  }
}

Now npm run dev starts the development server (Vite prints the local address, usually http://localhost:5173), and npm run build writes the finished site to a dist/ folder that you upload to your hosting.

Why go to this trouble? Because Sass lets you change Bootstrap's colours, fonts and spacing at the source, and you can import only the JavaScript you use:

JavaScript
// Smaller bundle: only the plugins this page needs
import { Modal, Tooltip } from "bootstrap";

Right-to-left languages

Bootstrap also ships bootstrap.rtl.min.css for languages written right to left, such as Urdu and Arabic. Use it instead of the normal CSS file and set dir="rtl" on the <html> element. Because Bootstrap 5 uses "start" and "end" in its class names instead of "left" and "right", the same HTML works in both directions.

Older code

In Bootstrap 4 and 3, the JavaScript needed jQuery, and the order of script tags was strict: jQuery first, then Popper (Bootstrap 4 only), then Bootstrap. You will still see this in many projects:

HTML
<!-- Bootstrap 4 style: do not use in new projects -->
<script src="jquery.slim.min.js"></script>
<script src="popper.min.js"></script>
<script src="bootstrap.min.js"></script>

Bootstrap 5 needs none of that. One bundle file, or one import, is enough.

Common mistakes

  • Loading bootstrap.min.js without Popper. Dropdowns and tooltips throw an error saying they require Popper. Use the bundle file, or install @popperjs/core.
  • Loading the JavaScript twice (the bundle plus a separate copy, or a CDN copy plus an npm import). Components then open and close at the same time and appear broken.
  • Forgetting to import the CSS in main.js. With Vite, nothing is styled until you import the stylesheet.
  • Opening index.html directly from the folder in a Vite project. Always use npm run dev; the browser cannot read .scss files or bare imports such as "bootstrap" on its own.

Key points

  • You can add Bootstrap from a CDN, from downloaded files, or with npm and a build tool such as Vite.
  • Put the CSS link in the <head> and the JavaScript bundle before </body>.
  • The bundle includes Popper, which dropdowns, tooltips and popovers need.
  • Pin an exact version such as 5.3.8 and use the integrity hashes from the official site in production.
  • npm + Vite + Sass lets you customise Bootstrap and ship only the code you use.

Exercise

Start from the CDN starter template. Change the title to "Meera's Bakery, Kochi", replace the heading with the bakery name, and add a paragraph that shows the Bootstrap version using bootstrap.Alert.VERSION. Then answer in one sentence: which tag would you change to switch to bootstrap.rtl.min.css for an Urdu version, and which attribute would you add to <html>?

Show solution
HTML
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Meera's Bakery, Kochi</title>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
  <div class="container py-4">
    <h1>Meera's Bakery</h1>
    <p id="version"></p>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js"></script>
  <script>
    document.getElementById("version").textContent = "Using Bootstrap " + bootstrap.Alert.VERSION;
  </script>
</body>
</html>

For an Urdu version you would change the <link> tag to load bootstrap.rtl.min.css and add dir="rtl" (and lang="ur") to the <html> element.

Quick Quiz

1. What is the difference between bootstrap.bundle.min.js and bootstrap.min.js?

2. In a Vite project, which command creates the optimised files you upload to your hosting?

3. Why should a CDN link contain an exact version such as bootstrap@5.3.8?

4. Where should the Bootstrap JavaScript bundle usually go?

Learn Bootstrap with a mentor

Free lessons get you started. Our Full Stack Web Development training adds real projects and code reviews from working developers.

  • Project-based learning
  • Mentor code reviews
  • Free counselling call