Find Companies Using Unpkg: Technographic API Guide
Unpkg is the CDN that sits in the README of a large share of npm packages. If a package author wants to show a one-line “just drop this in a script tag” install path, the URL they paste is almost always https://unpkg.com/package@version/file. That habit has spread unpkg across a very specific slice of the web: docs sites, package demos, CodePen-style prototypes that graduated to a real domain, and internal tools built without a bundler. Finding the companies behind those sites is a narrow but useful technographic query.
This guide covers what unpkg actually is, how DetectZeStack fingerprints it from the page HTML, why it never surfaces in DNS or headers, how it compares to jsDelivr, cdnjs, and Google Hosted Libraries, and how to go from one curl command to a batch-built list of companies using unpkg. Every example uses the real API response shape.
What Unpkg Is and Why Companies Load Scripts From It
Unpkg is a free, public content delivery network for everything published to the npm registry. Any file inside any npm package is reachable at a predictable URL: unpkg.com/[email protected]/umd/react.production.min.js serves that exact file from that exact version. Leave off the version and unpkg redirects to the latest release. Leave off the file path and it picks the package's declared browser entry point. There is no account, no configuration, and nothing to deploy.
Companies end up loading from unpkg for a handful of recurring reasons:
- The package README told them to. Many libraries document a script-tag install with an unpkg URL, and that snippet gets pasted straight into templates.
- No build step. Server-rendered apps, static marketing pages, and internal dashboards frequently pull a UI library or a chart library from unpkg rather than standing up a bundler for one dependency.
- Docs and demo sites. A project's documentation site is the natural home for live examples that import the project itself from unpkg, often at a pinned version.
Unpkg usage is a habit, not an infrastructure decision. It tells you how a team ships front-end code, not which CDN proxies their traffic.
How Unpkg Detection Works: the unpkg.com Fingerprint
Unpkg is a library-delivery CDN, so detection is a body-fingerprint match. When DetectZeStack fetches a page, it scans the served HTML for references to the unpkg host and reports a match as Unpkg under the CDN category, at confidence 100, with source: "http". The http source value means the evidence came from the HTTP response body rather than from DNS or the TLS certificate.
Script src and link href patterns the detector matches
The Unpkg fingerprint in the detection database has two parts, and either one is enough for a match:
| Pattern | Matches | Example in the page |
|---|---|---|
| Script source | unpkg.com/ | <script src="https://unpkg.com/vue@3/dist/vue.global.js"> |
| Link href | link[href*='unpkg.com'] | <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css"> |
The script pattern is a regular expression applied to every src attribute in the page; the trailing slash keeps it from matching unrelated hosts that merely contain the string. The link pattern is a DOM selector, so it catches stylesheets, preloads, and modulepreload hints that point at unpkg even when no script tag does. Both are evaluated against the HTML exactly as the server returned it.
You can reproduce the raw signal yourself in one line:
$ curl -s https://example.com | grep -o "unpkg\.com/[^\"']*" | head -3
unpkg.com/[email protected]/dist/vue.global.prod.js
unpkg.com/[email protected]/dist/leaflet.css
Why Unpkg Never Shows Up in DNS, Headers, or TLS
DetectZeStack runs four detection layers on every scan: HTTP body and headers, DNS records, and the TLS certificate. Infrastructure CDNs light up the last three. Cloudflare leaves a CNAME, a cf-ray header, and often a Cloudflare-issued certificate. Fastly and CloudFront leave equivalent marks. Those layers are covered in the guide on detecting the CDN and hosting provider of any website.
Unpkg touches none of them. A company does not put its own domain behind unpkg. The site's DNS still points at its real host, the site's response headers still come from its real server, and the certificate is still the site's own. The only trace of unpkg is inside the HTML, where a tag tells the browser to go fetch a file from unpkg.com. That is why an unpkg-only scan run against DNS and TLS alone would return nothing, and why meta.scan_depth matters when you read the results, which the batch section below comes back to.
The live scan of unpkg.com itself makes the layering visible. The demo response lists two entries under CDN: Cloudflare, which proxies the unpkg.com domain and is detected from headers, and Unpkg, which is detected because unpkg's own homepage loads assets from unpkg. Two CDN entries, two different layers, one page.
Unpkg vs jsDelivr vs cdnjs vs Google Hosted Libraries
All four are library-delivery CDNs, all four are detected from the page body, and all four land under the same CDN category. What differs is the catalog each one serves and the URL shape a page uses to reach it:
| CDN | Host in the page | What it serves |
|---|---|---|
| Unpkg | unpkg.com | Every file in every npm package, at package@version/path |
| jsDelivr | cdn.jsdelivr.net | npm, GitHub repositories, and WordPress plugins, with version aliasing and combined files |
| cdnjs | cdnjs.cloudflare.com | A curated catalog of popular libraries, versioned in the path |
| Google Hosted Libraries | ajax.googleapis.com | A short list of long-lived libraries such as jQuery and Dojo |
cdnjs and Google Hosted Libraries reflect a curated, older set of libraries, and a page loading jQuery from ajax.googleapis.com is usually a page built some years ago. Unpkg and jsDelivr both mirror npm directly, so they show up wherever a team pulls a modern package without bundling it, and a site that references one often references the other. Companion guides cover finding companies using jsDelivr, detecting cdnjs, and finding companies using Google Hosted Libraries; the pipeline below works for any of them by changing one string.
Who Uses Unpkg: Frontend Prototypes, Docs Sites, and Package Demos
Because unpkg is the CDN of the npm README, its footprint clusters around a few kinds of sites:
- Documentation and demo sites for npm packages. A library's own docs commonly load the library from unpkg so that every example runs against the published build. These sites belong to the maintainers or the company that sponsors the package.
- Prototypes that shipped. A page that started as a single HTML file with a Vue or Preact script tag from unpkg, and then acquired a domain and customers, keeps the unpkg reference until someone introduces a build step.
- Internal tools and admin panels. Server-rendered dashboards built by backend-leaning teams often pull a date picker, a chart library, or a CSS framework from unpkg rather than adding a JavaScript toolchain to the project.
- Marketing pages on static hosts. A static site on Netlify or a similar host, with an interactive widget pulled from unpkg, is a common combination. The infrastructure layer shows the static host; the body shows unpkg.
API Example: Confirming Unpkg on One Domain with /analyze
The public demo endpoint needs no API key and is the quickest way to confirm a single domain. It is IP-rate-limited, so use it for spot checks rather than list building:
$ curl -s "https://detectzestack.com/demo?url=unpkg.com" \
| jq '.technologies[] | select(.name == "Unpkg")'
{
"name": "Unpkg",
"categories": ["CDN"],
"confidence": 100,
"description": "Unpkg is a content delivery network for everything on npm.",
"website": "https://unpkg.com",
"icon": "Unpkg.png",
"source": "http",
"version": "",
"cpe": ""
}
Note the capitalization: the technology name in the response is Unpkg with a capital U. Filters that compare against a lowercase unpkg return nothing, which is an easy mistake to make in a jq or Python pipeline. The version field is empty because unpkg is a delivery network, not a versioned library; versions belong to the packages it delivers.
With an API key, /analyze returns the full stack for a domain. Here is the shape of a complete response for a page that loads Vue from unpkg:
$ curl -s "https://detectzestack.p.rapidapi.com/analyze?url=example.com" \
-H "X-RapidAPI-Key: YOUR_KEY" \
-H "X-RapidAPI-Host: detectzestack.p.rapidapi.com"
{
"url": "https://example.com",
"domain": "example.com",
"technologies": [
{
"name": "Unpkg",
"categories": ["CDN"],
"confidence": 100,
"description": "Unpkg is a content delivery network for everything on npm.",
"website": "https://unpkg.com",
"icon": "Unpkg.png",
"source": "http",
"version": "",
"cpe": ""
},
{
"name": "Vue.js",
"categories": ["JavaScript frameworks"],
"confidence": 100,
"description": "Vue.js is an open-source model–view–viewmodel JavaScript framework for building user interfaces and single-page applications.",
"website": "https://vuejs.org",
"icon": "vue.svg",
"source": "http",
"version": "3.4.21",
"cpe": ""
},
{
"name": "Netlify",
"categories": ["PaaS", "CDN"],
"confidence": 100,
"description": "Netlify providers hosting and server-less backend services for web applications and static websites.",
"website": "https://www.netlify.com/",
"icon": "Netlify.svg",
"source": "http",
"version": "",
"cpe": ""
}
],
"categories": {
"CDN": ["Unpkg", "Netlify"],
"JavaScript frameworks": ["Vue.js"],
"PaaS": ["Netlify"]
},
"meta": { "status_code": 200, "tech_count": 3, "scan_depth": "full" },
"cached": false,
"response_ms": 1842
}
Reading the technologies array and the CDN category
Three entries from one page tell three different stories. Unpkg is the delivery method. Vue.js is the thing being delivered, with the version parsed from the [email protected] path segment. Netlify is the host, and it appears under CDN as well because Netlify fronts static sites with its own edge network. The top-level categories map groups the same detections by category, so .categories.CDN gives you every CDN on the page without walking the array. When both an infrastructure CDN and unpkg appear in that list, you are looking at two independent facts about the site, not a contradiction.
The meta object holds exactly three fields: the HTTP status_code, the tech_count, and the scan_depth. Timing lives at the top level in response_ms, and cached reports whether the result came from a recent identical scan.
Watch scan_depth. A value of "full" means the HTTP fetch succeeded and body detection ran. A value of "partial" means the site blocked or timed out the HTTP request and only the DNS and TLS layers completed. Unpkg lives in the body, so a missing Unpkg entry on a partial scan is an unknown, not a negative. Route those domains to a retry queue.
Building a Companies-Using-Unpkg List with /analyze/batch
POST /analyze/batch accepts up to 10 URLs per request and scans them concurrently. Each item in the response carries either a full result object in the single-domain shape or an error string for a domain that could not be fetched:
$ curl -s -X POST "https://detectzestack.p.rapidapi.com/analyze/batch" \
-H "X-RapidAPI-Key: YOUR_KEY" \
-H "X-RapidAPI-Host: detectzestack.p.rapidapi.com" \
-H "Content-Type: application/json" \
-d '{"urls": ["unpkg.com", "example.com", "example.org"]}'
{
"results": [
{ "url": "unpkg.com", "result": { "...full analysis...": "" } },
{ "url": "example.com", "result": { "...full analysis...": "" } },
{ "url": "example.org", "result": { "...full analysis...": "" } }
],
"total_ms": 2341,
"successful": 3,
"failed": 0
}
Filtering batch results for the Unpkg entry
Because every result matches the single-domain shape, the same jq filter works for one domain or a thousand. The script below reads domains.txt, one domain per line, sends batches of 10, and appends every unpkg-confirmed domain to a CSV along with the packages unpkg is delivering, the scan depth, and the tech count. Domains that came back partial are written to a separate retry file rather than silently dropped:
#!/usr/bin/env bash
# find-unpkg.sh - filter a domain list down to unpkg-confirmed leads
KEY="YOUR_KEY"
HOST="detectzestack.p.rapidapi.com"
echo "domain,delivered_libraries,tech_count" > unpkg_leads.csv
: > unpkg_retry.txt
# Process domains.txt in batches of 10 (the /analyze/batch maximum)
xargs -n 10 < domains.txt | while read -r batch; do
urls=$(printf '%s\n' $batch | jq -R . | jq -s '{urls: .}')
resp=$(curl -s -X POST "https://$HOST/analyze/batch" \
-H "X-RapidAPI-Key: $KEY" \
-H "X-RapidAPI-Host: $HOST" \
-H "Content-Type: application/json" \
-d "$urls")
# Confirmed: Unpkg present in the technologies array
echo "$resp" | jq -r '.results[]
| select(.result != null)
| .result as $r
| select([$r.technologies[].name] | index("Unpkg"))
| [
$r.domain,
([$r.technologies[]
| select(.name != "Unpkg" and (.categories | index("CDN") | not))
| .name] | join(";")),
($r.meta.tech_count | tostring)
]
| @csv' >> unpkg_leads.csv
# Unknown: body fetch failed, so absence of Unpkg proves nothing
echo "$resp" | jq -r '.results[]
| select(.result != null)
| select(.result.meta.scan_depth == "partial")
| .result.domain' >> unpkg_retry.txt
done
echo "leads: $(($(wc -l < unpkg_leads.csv) - 1))"
echo "retries: $(wc -l < unpkg_retry.txt)"
A 1,000-domain list becomes 100 batch calls. The index("Unpkg") guard keeps a domain whenever Unpkg appears in its technology list. The second column collects every non-CDN detection on the page, which for an unpkg site is usually the library being delivered plus whatever else the page runs. The select(.result != null) guard skips domains that failed to resolve, since those come back with an error field instead of a result. For throughput, retry strategy, and a production Python scanner, see how to batch scan 1,000 websites.
To segment by delivered library instead of by delivery method, replace the index("Unpkg") check with a two-part condition, for example Unpkg present and Vue.js present. That yields a list of companies loading Vue from unpkg specifically, which is a sharper audience than either signal alone.
Comparing Unpkg Adoption Across Competitors with /compare
POST /compare takes 2 to 10 URLs and returns each domain's full technologies array, a shared list of technologies present on every domain, and a per-domain unique list. It is the right call when the question is not “who uses unpkg” but “how do these specific competitors ship front-end code”:
$ curl -s -X POST "https://detectzestack.p.rapidapi.com/compare" \
-H "X-RapidAPI-Key: YOUR_KEY" \
-H "X-RapidAPI-Host: detectzestack.p.rapidapi.com" \
-H "Content-Type: application/json" \
-d '{"urls": ["unpkg.com", "example.com", "example.org"]}' \
| jq -r '.domains[]
| [.domain,
([.technologies[] | select(.categories | index("CDN")) | .name] | join(";"))]
| @tsv'
unpkg.com Cloudflare;Unpkg
example.com Unpkg;Netlify
example.org Cloudflare
Each line is a domain followed by every CDN it uses, which puts the infrastructure CDN and the library-delivery CDN side by side. A competitor set where one company shows Unpkg and the others show only Cloudflare or CloudFront is a set where one company ships without a bundler and the rest do not. Each URL in the request counts as one request against your plan, the same as a batch call.
What an Unpkg Signal Tells a Sales or Security Team
An unpkg detection is rarely the end of the query. It is the entry point to a segment, and the segment depends on who is asking.
- Sales and prospecting. Pair the Unpkg flag with the library it delivers. A list of sites loading a specific charting, mapping, or UI library from unpkg is a precise audience for anyone selling a competing or complementary product, and the pinned version in the URL tells you how far behind they are. The delivery method narrows the list; the delivered library qualifies it. The broader playbook is in tech stack enrichment for sales teams.
- Developer tooling and build vendors. Unpkg usage correlates with the absence of a build pipeline. Companies selling bundlers, hosted CI, front-end platforms, or performance tooling can treat an unpkg reference on a production marketing site as a sign the team has not yet adopted the thing they sell.
- Security and supply chain. Every script loaded from a public CDN is executable code the site does not control. Security teams inventory which external hosts a domain pulls scripts from, and unpkg belongs on that inventory alongside jsDelivr and cdnjs. Unpinned unpkg URLs, the ones without an
@version, are the ones to flag first: they resolve to whatever the latest release is on the day the page loads, which is exactly the surface a subresource-integrity or third-party-risk review exists to find.
Limits: No Global Index, Version Pinning, and Self-Hosted Fallbacks
Three limits are worth stating plainly so the list you build means what you think it means.
There is no global index of unpkg users. DetectZeStack scans the domains you give it. It does not maintain a crawled database of every site on the web, so “find companies using unpkg” in practice means “filter my domain list down to the ones using unpkg.” Bring the list from your CRM, a directory, or a competitor set; the API confirms the signal per domain.
Version pinning affects what you learn, not whether Unpkg is detected. A pinned URL such as unpkg.com/[email protected]/... and an unpinned one such as unpkg.com/vue@3/... both match the fingerprint. The difference is that a pinned URL gives the delivered library a precise version, while an unpinned one may leave the version empty or resolve to a major-only value. If version matters for your segmentation, keep the raw script URL from the grep step as well as the API's parsed field.
Self-hosted fallbacks and late-injected scripts can hide the reference. Some pages load a library from their own domain and reference unpkg only in a fallback branch inside inline JavaScript, or add the unpkg tag from client-side code after load. Detection reads the HTML as served, so a reference that only exists after JavaScript runs may not appear. Conversely, a site that vendors every library will show the library, for example Bootstrap from /static/js/bootstrap.min.js, with no Unpkg entry at all. A missing Unpkg detection means the served page does not reference unpkg. It does not mean the company never touches npm.
Conclusion and Getting an API Key
Finding companies using unpkg reduces to reading one signal well: a script src containing unpkg.com/ or a link href containing unpkg.com in the served HTML. Because unpkg is a library-delivery CDN rather than an infrastructure one, it appears only in the page body, never in DNS, headers, or TLS, and it commonly sits beside an infrastructure CDN in the same CDN category. A single /analyze call answers the one-domain question, /analyze/batch turns a domain list into an unpkg-confirmed lead list with the delivered libraries alongside, /compare lines up a competitor set, and meta.scan_depth tells you which negatives are real.
The free tier includes 100 requests per month with no credit card, which is enough to validate the pipeline on a sample before scaling up:
- Get your free API key at rapidapi.com/mlugoapx/api/detectzestack.
- Spot-check a domain you know:
curl -s "https://detectzestack.com/demo?url=yourdomain.com" | jq '.categories.CDN' - Run the batch script above against your first 100 domains and read the retry file before you read the leads file.
Related Reading
- Find Companies Using jsDelivr — The other npm-mirroring library-delivery CDN (cdn.jsdelivr.net), detected from the page HTML the same way
- How to Detect cdnjs on Any Website — The Cloudflare-hosted curated library CDN (cdnjs.cloudflare.com), with the library and version encoded in the URL path
- Find Companies Using Google Hosted Libraries — The older curated library CDN (ajax.googleapis.com), and what it says about a site's age
- How to Detect the CDN and Hosting Provider of Any Website — The infrastructure-CDN layer that sits in front of a site, detected via DNS, headers, and TLS
- How to Detect Vue.js on Any Website — The framework most often seen loading from unpkg in buildless pages, and its own fingerprints
- How to Detect React on Any Website — Another package whose UMD build ships from unpkg on docs and demo sites
- How to Batch Scan 1,000 Websites for Tech Stack Data — Deep dive on /analyze/batch throughput, retries, and a Python scanner
- Tech Stack Enrichment for Sales Teams — Why technographic data matters for prospect qualification
- Lead Enrichment Pipeline with Tech Detection — Turning raw detections into scored, routable leads
Try DetectZeStack Free
100 requests per month, no credit card required. Header, DNS, and TLS detection included on every plan.
Get Your Free API Key