How to Detect dc.js on Any Website (API Guide)

June 29, 2026 · 9 min read

dc.js is a dimensional charting library: a thin layer that sits on top of D3.js and the crossfilter engine to render coordinated, drill-down dashboards. You will find it powering internal BI tools, financial dashboards, log-analytics front ends, and a long tail of data-heavy admin panels. Because it always travels with D3 and crossfilter, spotting dc.js on a page tells you a lot about how that site handles client-side data visualization.

This post covers two ways to detect dc.js: the manual browser-console method for a single site, 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.

What Is dc.js and Why Detect It

dc.js (the "dc" stands for "dimensional charting") renders charts that are wired directly into a crossfilter dataset. Click a bar in one chart and every other chart on the page re-filters instantly, all in the browser with no round trip to the server. That makes it a popular choice for dashboards where an analyst needs to slice the same dataset many ways at once.

Knowing whether a page uses dc.js is useful in several contexts:

How dc.js Leaves Fingerprints in Page Source

dc.js is straightforward to detect because it announces itself in two independent ways, and its dependencies leave their own marks.

First, when dc.js loads through a normal <script> tag it attaches a global dc object to window, exposing dc.version and a set of chart constructors such as dc.barChart and dc.pieChart. Second, the script tag itself usually points at a recognizable file:

Because dc.js renders through D3 and reads from crossfilter, a page that loads it nearly always loads d3.min.js right before it. That dependency chain is itself a strong signal: see all three (or even just dc.js plus D3) and you are almost certainly looking at a dimensional-charting dashboard.

Manual Ways to Detect dc.js

For a one-off check on a single site, the browser is the fastest tool. There are two complementary approaches: inspecting the script tags, and probing the live JavaScript globals in the console.

Checking Script Tags and the Console

Without running any JavaScript, a quick grep against the HTML answers the question for most sites. The library file is almost always named dc.js or dc.min.js:

curl -s https://example.com | grep -oE 'dc(\.min)?\.js' | head -3

To also surface the version when the CDN path includes it:

curl -s https://example.com | grep -oE 'dc[@/][0-9]+\.[0-9]+\.[0-9]+' | head -3

For the live check, open DevTools on the target page and run the following in the console. It probes the dc global, reads the version, and checks for the D3 and crossfilter dependencies that travel with it:

(function () {
  var hasDc = typeof window.dc === 'object' && window.dc !== null;
  var version = hasDc && window.dc.version ? window.dc.version : null;
  var hasD3 = typeof window.d3 === 'object' && window.d3 !== null;
  var hasCrossfilter = typeof window.crossfilter === 'function';
  console.log({ dc: hasDc, version: version, d3: hasD3, crossfilter: hasCrossfilter });
})();

A dashboard built on the full stack prints something like:

{ dc: true, version: "4.2.7", d3: true, crossfilter: true }

The version is coupled to D3. dc.js 2.x targets D3 v3/v4, while dc.js 3.x and 4.x target D3 v5+. If you are auditing for a D3 upgrade, the dc.version string is the number that tells you whether a page can move with you or will break. Capture it, do not just record "uses dc.js".

The console method is perfect for one URL, but it does not scale to 200 domains, let alone 200,000. For that you want an API.

Detect dc.js Programmatically With the DetectZeStack API

The DetectZeStack /analyze endpoint returns every detected technology on a page as structured JSON, including dc.js and its D3 dependency when present. The detector reads the HTTP response — headers and HTML — so async loaders and noConflict-style tricks that fool a too-early console check are not a problem server-side.

Try It Without an API Key

The public /demo endpoint runs the same detector pipeline against any URL with no authentication. It is rate-limited but perfect for confirming the response shape before you wire up a real key:

curl -s "https://detectzestack.com/demo?url=https://dc-js.github.io/dc.js/" | python3 -m json.tool

The response is a single JSON object. Trimmed to the relevant entries, a dc.js hit looks like this:

{
  "url": "https://dc-js.github.io/dc.js/",
  "domain": "dc-js.github.io",
  "technologies": [
    {
      "name": "dc.js",
      "categories": ["JavaScript graphics", "JavaScript libraries"],
      "confidence": 100,
      "description": "A multi-dimensional charting library built to work natively with crossfilter and rendered using d3.js",
      "website": "https://dc-js.github.io/dc.js/",
      "icon": "dc.js.png",
      "source": "http",
      "version": "4.2.7",
      "cpe": ""
    },
    {
      "name": "D3",
      "categories": ["JavaScript graphics"],
      "confidence": 100,
      "description": "D3.js is a JavaScript library for producing dynamic, interactive data visualisations in web browsers.",
      "website": "https://d3js.org",
      "icon": "D3.png",
      "source": "http",
      "version": "",
      "cpe": ""
    }
  ],
  "categories": {
    "JavaScript graphics": ["dc.js", "D3"],
    "JavaScript libraries": ["dc.js"]
  },
  "meta": { "status_code": 200, "tech_count": 5, "scan_depth": "full" },
  "cached": false,
  "response_ms": 1638
}

Reading the JSON Response for dc.js and Its D3.js Dependency

Two things in that response are worth pointing out. First, dc.js carries two categories — JavaScript graphics and JavaScript libraries — so it shows up in both buckets of the top-level categories map. Second, D3 appears as its own entry because D3 has an independent fingerprint. dc.js does not "imply" D3 automatically; D3 is reported because the page genuinely loads it. In practice that is exactly what you want: confirmation of the whole stack, not just the top layer.

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 the response counts against your monthly quota:

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

If dc.js is detected, that pipe prints exactly the matching object:

{
  "name": "dc.js",
  "categories": ["JavaScript graphics", "JavaScript libraries"],
  "confidence": 100,
  "description": "A multi-dimensional charting library built to work natively with crossfilter and rendered using d3.js",
  "website": "https://dc-js.github.io/dc.js/",
  "icon": "dc.js.png",
  "source": "http",
  "version": "4.2.7",
  "cpe": ""
}

If dc.js is not present, jq outputs nothing and the script exits cleanly — easy to wire into a shell pipeline that filters a list of domains. To confirm the whole charting stack in one pass, widen the filter to either name:

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

That returns an array such as ["dc.js", "D3"] when both are present, or just ["D3"] on a site that uses D3 directly without the dc.js charting layer.

Parsing the Version Field

The version field is a plain string when the detector found one ("4.2.7", "3.2.0") and empty when it did not. It is empty when dc.js is bundled into a single application file so neither the URL nor a banner comment exposes the number. In both cases the name still reports dc.js. For an audit that needs a real version inventory, treat an empty string as "present, version not detectable from this signal," not as "absent."

Batch-Scanning Many Sites for dc.js

The whole point of an HTTP API is that "scan one site" and "scan ten thousand" are the same code with a different loop. A minimal worker that reads a domain list, calls /analyze, and writes one JSON line per domain:

#!/usr/bin/env bash
# scan-dcjs.sh — usage: scan-dcjs.sh domains.txt > results.jsonl
set -euo pipefail

KEY="${RAPIDAPI_KEY:?set RAPIDAPI_KEY}"
HOST="detectzestack.p.rapidapi.com"

while IFS= read -r domain; do
  [ -z "$domain" ] && continue
  curl -s "https://${HOST}/analyze?url=https://${domain}" \
    -H "x-rapidapi-key: ${KEY}" \
    -H "x-rapidapi-host: ${HOST}" \
  | jq -c --arg d "$domain" '{
      domain: $d,
      dcjs: (.technologies[]? | select(.name == "dc.js")) // null,
      d3: ([.technologies[]? | select(.name == "D3")] | length > 0)
    }'
done < "$1"

Each output line is either {"domain":"...","dcjs":{...},"d3":true} when dc.js is present or {"domain":"...","dcjs":null,"d3":false} when it is not. Pipe the result into a database, a spreadsheet, or another jq filter to produce the report you actually need — for example, every site that loads D3 but not dc.js, which is a useful prospecting list if you sell a charting layer.

For higher-throughput patterns (concurrency, retries, quota handling), see Batch Scan 1,000 Websites for Tech Stack.

Conclusion and Next Steps

Detecting dc.js on a single page takes one line in the DevTools console. Detecting it across a portfolio takes one HTTP call per domain. The two details that turn a yes/no answer into a real decision are the version field — because dc.js is locked to specific major versions of D3 — and the presence of the D3 entry alongside it, which confirms you are looking at the full dimensional-charting stack rather than an unrelated script that happens to be named dc.

The same /analyze call that surfaces dc.js also names every other framework, library, CDN, analytics tag, and CMS on the page. One quota, one response shape, every technology in one shot.

Related Reading

Detect dc.js and Every Other Library 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.