How to Detect if a Website Uses Bootstrap (2026 Guide)

June 15, 2026 · 10 min read

Bootstrap is still one of the most widely deployed front-end frameworks on the public web. A decade of admin dashboards, marketing sites, internal tools, and CMS themes shipped on it, and a large share of those pages are still live. Knowing whether a site uses Bootstrap — and which major version — matters for competitive research, agency design audits, framework-migration planning, and sales prospecting against companies whose front end signals "built fast, ready to modernise."

This guide covers two approaches: the manual DevTools method for checking a single page, and the DetectZeStack API for scanning thousands of domains. Every code example is copy-pasteable and uses fields that actually exist in the API response.

Why Detect Bootstrap on a Website

"Just view source" works fine for one URL. The use cases that drive Bootstrap detection are almost never about a single page:

All of them want the same two answers in code: is Bootstrap present? and which version?

Manual Ways to Detect Bootstrap

For a one-off check on a single page, the browser is the fastest tool. Bootstrap advertises itself in three independent ways, and any one of them is usually enough.

Inspect Class Names in DevTools

Bootstrap's entire value proposition is a named set of components and a grid, so the class vocabulary is a strong fingerprint. Open DevTools, inspect the markup, and look for these patterns:

Class patternWhat it signals
container / container-fluidThe top-level layout wrapper
row + col-md-6 / col-lg-4The 12-column responsive grid
navbar navbar-expand-lgThe responsive navigation component
btn btn-primaryButton component + colour variant
card / card-bodyThe card component
d-flex / mt-3 / py-2Spacing and display utility classes

The grid classes are the most reliable single tell. A page peppered with col-md-* and row on layout wrappers is almost certainly Bootstrap (or a fork of it). From the DevTools console you can count them quickly:

// Rough Bootstrap signal: count grid + component classes on the page
document.querySelectorAll('[class*="col-"], .row, .navbar, .btn-primary, .card').length

A double-digit result on a content-heavy page is a strong hint. It is not proof on its own — a few hand-rolled sites borrow Bootstrap-style names — so pair it with the stylesheet check below.

Check Loaded CSS and JS Files for bootstrap.min.css

Even without running any JavaScript, the HTML usually names the framework directly. Bootstrap is most often loaded from one of three places:

A quick grep against the raw HTML answers the question without executing anything:

curl -s https://getbootstrap.com | grep -oE 'bootstrap[.@-][^"'\'' ]*\.(css|js)' | head -5

The optional bootstrap.bundle.min.js (which packages Popper for dropdowns, tooltips, and modals) is a second signal. A page that loads both the CSS and the bundle is using Bootstrap's interactive components, not just its grid.

Read the Bootstrap Version from the Bundle

When the version is not already in the filename, the file itself usually carries it. Open bootstrap.min.css and the first line is a banner comment:

/*! Bootstrap v5.3.3 (https://getbootstrap.com/) | MIT License */

The major version matters because the class vocabulary changed across releases. Bootstrap 3 used col-md-6 with .panel and .glyphicon; Bootstrap 4 introduced flexbox utilities and dropped Glyphicons; Bootstrap 5 removed jQuery as a dependency and renamed several utilities (ml-*/mr-* became ms-*/me-*). Spotting data-bs-toggle attributes, for example, tells you the site is on Bootstrap 5, because the bs- prefix was introduced in that release.

Verify after a migration. If your plan is "remove Bootstrap from the main layout" but a CMS theme or a vendored widget reloads bootstrap.min.css, your removal is silently undone. The stylesheet grep above is the cheapest way to confirm the file is actually gone after a deploy.

Bootstrap vs Tailwind: Telling CSS Frameworks Apart

The two frameworks people most often confuse at a glance are Bootstrap and Tailwind, because both produce class-heavy markup. Under the hood they are opposites, and the difference is exactly what makes each one detectable.

SignalBootstrapTailwind
ApproachComponent frameworkUtility-first
Typical classesnavbar, card, btn-primary, col-md-4flex, pt-4, text-sm, bg-blue-500
Stylesheetbootstrap.min.css (named)hashed/purged bundle
Optional JSbootstrap.bundle.min.jsnone required

Bootstrap names componentscard, navbar, modal — and ships a single recognisable stylesheet. Tailwind names atomspt-4, flex, text-sm — and usually purges unused styles into an opaque hashed bundle with no component CSS to fingerprint. In the DetectZeStack response both land in the UI frameworks category, but the class vocabulary and the presence of a named bootstrap.min.css are what separate them. If you are chasing Tailwind specifically, see How to Detect Tailwind CSS on Any Website.

Detect Bootstrap at Scale with the DetectZeStack API

The console method does not scale to 200 domains, let alone 200,000. For programmatic detection, the DetectZeStack /analyze endpoint returns every detected technology on a page as structured JSON, including Bootstrap and its parsed version when present.

Single-Site curl Example with /analyze

Before wiring up a real key, you can confirm the response shape against the public /demo endpoint, which runs the same detector pipeline with no authentication. It is rate-limited but perfect for a smoke test:

curl -s "https://detectzestack.com/demo?url=https://getbootstrap.com" | python3 -m json.tool

The response is a single JSON object. Trimmed to the relevant fields, a Bootstrap hit looks like this:

{
  "url": "https://getbootstrap.com",
  "domain": "getbootstrap.com",
  "technologies": [
    {
      "name": "Bootstrap",
      "categories": ["UI frameworks"],
      "confidence": 100,
      "description": "Bootstrap is a free and open-source CSS framework directed at responsive, mobile-first front-end web development.",
      "website": "https://getbootstrap.com",
      "icon": "Bootstrap.svg",
      "source": "http",
      "version": "5.3.3",
      "cpe": ""
    }
  ],
  "categories": { "UI frameworks": ["Bootstrap"] },
  "meta": { "status_code": 200, "tech_count": 9, "scan_depth": "full" },
  "cached": false,
  "response_ms": 1604
}

For production usage, sign up on RapidAPI and call /analyze with your key. The endpoint returns the same shape as /demo but without the demo rate limit, and each call is counted against your monthly quota:

curl -s "https://detectzestack.p.rapidapi.com/analyze?url=https://getbootstrap.com" \
  -H "x-rapidapi-key: $RAPIDAPI_KEY" \
  -H "x-rapidapi-host: detectzestack.p.rapidapi.com" \
  | jq '.technologies[] | select(.name == "Bootstrap")'

If Bootstrap is detected, that pipe prints exactly the matching object. If it is not present, jq outputs nothing and the script exits cleanly — easy to wire into a shell pipeline that filters a list of domains.

Confirm a Single Technology with /check

When you only care about one technology, the /check endpoint is more direct than /analyze. It runs the same detection but answers a yes/no question with a ?tech= parameter, so you do not have to filter the array yourself:

curl -s "https://detectzestack.p.rapidapi.com/check?url=https://getbootstrap.com&tech=Bootstrap" \
  -H "x-rapidapi-key: $RAPIDAPI_KEY" \
  -H "x-rapidapi-host: detectzestack.p.rapidapi.com"

The response is a compact object built for exactly this question:

{
  "domain": "getbootstrap.com",
  "technology": "Bootstrap",
  "detected": true,
  "confidence": 100,
  "version": "5.3.3",
  "categories": ["UI frameworks"],
  "response_ms": 1180,
  "cached": false
}

The tech match is case-insensitive, and the returned technology field is the canonical name from the detector, so you can pass bootstrap and still get back Bootstrap. When the technology is absent, detected is false and version is an empty string.

Reading the API Response (Version and Confidence)

Two fields on the Bootstrap entry carry the information you actually act on: version and confidence.

The version field is a plain string ("5.3.3", "4.6.2", "3.4.1") when the detector found one, and empty when it did not. It comes back empty in two common situations: the site purges and hashes its CSS into a single bundle so neither the filename nor a banner comment is visible, or Bootstrap is loaded from a path the detector did not have a version fingerprint for. In both cases name still reports Bootstrap — treat an empty version as "present, version not detectable from this signal," not as "absent."

The confidence field is an integer from 0 to 100. A strong, unambiguous match such as a named bootstrap.min.css reports 100; weaker signals report lower. For a portfolio audit, a one-liner that lists every site running a major version older than 5 looks like this:

jq -r '
  .technologies[]
  | select(.name == "Bootstrap")
  | select(.version != "")
  | select(.version | split(".") | .[0] | tonumber < 5)
  | "\(input_filename): Bootstrap \(.version)"
' analyses/*.json

That flags the saved /analyze responses on Bootstrap 3 or 4 — the strongest signal that a redesign or framework upgrade is overdue. The same shape works for any version cutoff you care about.

Common Detection Gotchas

Three situations regularly trip up Bootstrap detection. Recognising them keeps your inventory honest.

Forks and Bootstrap-Based Themes

Plenty of admin templates and CMS themes are built on top of Bootstrap and rename or extend its classes. These still load a recognisable bootstrap.min.css in most cases, so the detector reports Bootstrap correctly — but be aware that the design you see may be a commercial theme rather than vanilla Bootstrap. The class names will give it away when you inspect.

Purged and Bundled CSS

Modern build tools tree-shake unused Bootstrap CSS and concatenate the rest into a single hashed file like app.4f2c1a.css. The stylesheet no longer mentions Bootstrap and there is no banner comment, so the HTTP-layer detector cannot read the version — version comes back empty. The name still reports Bootstrap when a class-pattern or signature match fires, but do not rely on the version field for purged builds.

Bootstrap Icons Without the Framework

The bootstrap-icons font is a separate package and is sometimes used on sites that do not use the Bootstrap CSS framework at all. Seeing bi bi-* icon classes is not, by itself, proof the layout is built on Bootstrap. Check for the grid and component classes (row, col-*, navbar) before you count a site as a Bootstrap site.

Get Your Free API Key

The flow is short:

  1. Smoke test the response shape with curl "https://detectzestack.com/demo?url=https://example.com" — no key required.
  2. Sign up at rapidapi.com/mlugoapx/api/detectzestack and copy your x-rapidapi-key. The free tier is 100 requests per month with no credit card.
  3. Run the /analyze or /check example above against a domain you control.
  4. Read technologies[].version on the Bootstrap entry — that's your answer.

From there, the same call gives you every other piece of the stack: CDN, analytics, CMS, JavaScript frameworks, and more. One quota, one response shape, every technology in one shot. For higher-throughput patterns, see Batch Scan 1,000 Websites for Tech Stack.

Conclusion

Detecting Bootstrap on a single page takes a quick DevTools inspection: count the grid and component classes, then confirm a named bootstrap.min.css in the loaded stylesheets. Detecting it across a portfolio takes one HTTP call per domain to /analyze or /check. The version field is the part that turns a yes/no answer into a migration or sales decision — pay attention to whether it is populated, and remember that an empty string on a purged build means "present, version hidden," not "absent."

Related Reading

Detect Bootstrap and Every Other Technology in One API Call

One HTTP request returns every framework, library, CDN, CMS, and analytics tag on a page — with version strings where available. 100 requests per month free. No credit card.

Get your free API key

Get API updates and tech detection tips

Join the mailing list. No spam, unsubscribe anytime.