# Open-Source Wappalyzer Alternative: Bulk Tech Stack Detector (`neorhapsody/tech-stack-detector`) Actor

Check what technology any website uses (CMS, ecommerce, analytics, frameworks, CDN, hosting and 7,600+ more) from the homepage and HTTP headers. An open-source (GPL-3.0) Wappalyzer and BuiltWith alternative for bulk lists.

- **URL**: https://apify.com/neorhapsody/tech-stack-detector.md
- **Developed by:** [fikri marhan](https://apify.com/neorhapsody) (community)
- **Categories:** Lead generation, Developer tools, Open source
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 website checkeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Open-Source Wappalyzer Alternative: Bulk Tech Stack Detector

**Find out what any website is built with.** Paste a list of domains and get each site's CMS, ecommerce platform, analytics and marketing tags, JavaScript frameworks, CDN, hosting, payment providers, live chat and more. It checks against **7,600+ technology fingerprints** and returns versions where they can be detected.

Built for **bulk lists**: it makes one lightweight request per site (homepage HTML + HTTP headers), with no browser and no proxy. That keeps it fast and cheap.

### How to check what technology a website uses, in bulk

Paste a list of domains (hundreds or thousands), run it, and download a table with one row per site, or one row per site and technology. It identifies the CMS, ecommerce platform, analytics, tag managers, JavaScript frameworks, CDN, web server, payment and chat tools, with version numbers where the page exposes them.

### Wappalyzer and BuiltWith alternative: what's different

- **Open source**: GPL-3.0-or-later code, and an open fingerprint database (webappanalyzer) that you can inspect.
- **Bulk and cheap**: $2 per 1,000 sites, with no subscription. Failed sites are free.
- **Honest limits**: it reads the homepage HTML and headers only. It doesn't run JavaScript or crawl history, so it won't show past technologies or spending data the way BuiltWith does.

### Use cases

- **Lead generation and sales prospecting**: find every Shopify, WooCommerce, HubSpot or Salesforce user in your lead list.
- **Agency and SaaS targeting**: segment prospects by CMS, analytics stack or competing tools.
- **Competitor and market research**: see what your competitors use and how technology adoption is spread.
- **Security and IT inventory**: spot outdated CMS or framework versions across your own domains.
- **Enrichment**: add a `technologies` column to CRM exports or Google Maps or LinkedIn company lists.

### What you get

For each website:

- `domain`, `finalUrl` (after redirects), `statusCode`, page `title`
- `technologies`: name, version (when detectable), confidence, categories, vendor website, and whether it was implied
- `technologyNames`: a single comma-separated string, handy for CSV and Excel
- `categories`: technologies grouped by category, e.g. `{ "CMS": ["WordPress"], "Analytics": ["Google Analytics"] }`
- `error` if the site was unreachable or blocked automated requests

Use the **"One row per technology"** view to export one row per domain × technology.

### Input example

```json
{ "urls": ["shopify.com", "wordpress.org", "https://www.mudah.my"], "categoriesFilter": ["CMS", "Ecommerce", "Analytics"] }
```

### Output example

```json
{
  "domain": "wordpress.org", "statusCode": 200,
  "technologyNames": "Google Tag Manager, MySQL, Nginx, PHP, WordPress 7.2, ...",
  "technologies": [{ "name": "WordPress", "version": "7.2", "confidence": 100, "categories": ["CMS", "Blogs"], "website": "https://wordpress.org", "implied": false }],
  "categories": { "CMS": ["WordPress"], "Web servers": ["Nginx"] }
}
```

### Pricing

Pay per event, with no extra platform-usage charges: **$2 per 1,000 sites** (`site`, $0.002 per website result). Sites that can't be analysed (unreachable, blocked, invalid URL) still get a result row with the reason, and **those error rows are free**. If you set a **maximum cost per run**, the actor stops cleanly once the limit is reached.

### How it works and its limits

It looks at the response headers, cookies, meta tags, script URLs, HTML patterns and DOM selectors on the page you give it. It doesn't run JavaScript, so tools that are detectable only at runtime (some JS-only tags) may be missed. Sites that block automated requests return an error, and only header-based detection is possible for them. The actor never tries to bypass such protections.

### Troubleshooting

A failing site never stops the run. It gets a row with `isError: true`, an `errorCode`, a plain-English `errorMessage` and the `inputUrl`. The *Errors* view shows these columns. Error rows are not charged. Counts per code are in the run's `RUN_SUMMARY` key-value record.

| Code | Meaning | What to do |
|---|---|---|
| `INVALID_INPUT` | The value isn't a valid URL or domain, or another input field is invalid. | Fix the value. |
| `DNS_NOT_FOUND` | The domain doesn't resolve. | Check the spelling, or whether the domain still exists. |
| `TIMEOUT` | The site didn't respond within *Timeout per site*. | Raise the timeout, or retry later. |
| `CONNECTION_FAILED` / `TLS_ERROR` / `TOO_MANY_REDIRECTS` | The site couldn't be reached properly. | Check the site in a browser. |
| `SITE_BLOCKED` | HTTP 403/429/503: the site blocks automated requests. Header-based detections are still returned. No bypass is attempted. | None. |
| `HTTP_ERROR` / `EMPTY_RESPONSE` | The site returned an error page or nothing. | Try the exact homepage URL. |
| `NOT_HTML` (warning) | The URL isn't an HTML page. | Use the site's homepage. |
| `MAX_CHARGE_REACHED` (warning) | Your maximum cost per run was reached; the remaining sites were skipped. | Raise the limit. |
| `ALL_SITES_FAILED` | No site could be analysed, so the run is marked failed. | See the error rows. |
| `INTERNAL_ERROR` | An unexpected bug. | Please report it (see below). |

**Found a bug or a wrong result?** Open an **Issue** on this Actor's page in Apify Store (the *Issues* tab) and describe what you expected. Please **paste the run URL into the issue**: Apify then shares that run (log, input, dataset and RUN_SUMMARY) with the developer automatically, and only that run. Alternatively, enable **Settings → Login & Privacy → Share run data with developers** for this Actor. The Actor sends no telemetry anywhere; everything stays in your own run storage.

### Data and license

This actor is free software, licensed under the **GNU General Public License v3.0 or later (GPL-3.0-or-later)**. The complete source code, including the `LICENSE` (GPL-3.0 text) and `NOTICE.md` files, is published with the Actor (see its *Source* tab), and it's also available on request through the Issues tab.

Technology fingerprints come from the open-source [webappanalyzer](https://github.com/enthec/webappanalyzer) project (© its contributors), a community continuation of the open-source Wappalyzer fingerprints, licensed **GPL-3.0**. They are included unmodified with attribution; the snapshot commit is in `data/SOURCE_COMMIT`. Wappalyzer and BuiltWith are trademarks of their owners; this actor is not affiliated with or endorsed by them.

# Actor input Schema

## `urls` (type: `array`):

Domains or URLs, one per line (e.g. shopify.com or https://www.example.com). Only the given page (usually the homepage) is fetched.

## `categoriesFilter` (type: `array`):

Optional. Keep only technologies in these categories, e.g. CMS, Ecommerce, Analytics, JavaScript frameworks, CDN, Payment processors, Live chat, Marketing automation.

## `minConfidence` (type: `integer`):

Drop detections below this confidence (0-100).

## `includeImplied` (type: `boolean`):

Include technologies implied by others (e.g. WordPress implies PHP and MySQL).

## `maxConcurrency` (type: `integer`):

How many websites to check at the same time.

## `timeoutSecs` (type: `integer`):

Seconds to wait for each website.

## Actor input object example

```json
{
  "urls": [
    "wordpress.org",
    "shopify.com",
    "apify.com"
  ],
  "minConfidence": 50,
  "includeImplied": true,
  "maxConcurrency": 10,
  "timeoutSecs": 20
}
```

# Actor output Schema

## `results` (type: `string`):

One row per site with the detected technologies, plus error records for sites that could not be analysed.

## `byTechnology` (type: `string`):

Compact view: site and technology names.

## `errors` (type: `string`):

Error columns: code, message and input.

## `runSummary` (type: `string`):

RUN_SUMMARY JSON: input/output counts, errors and warnings by code, charged events.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "urls": [
        "wordpress.org",
        "shopify.com",
        "apify.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("neorhapsody/tech-stack-detector").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "urls": [
        "wordpress.org",
        "shopify.com",
        "apify.com",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("neorhapsody/tech-stack-detector").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "urls": [
    "wordpress.org",
    "shopify.com",
    "apify.com"
  ]
}' |
apify call neorhapsody/tech-stack-detector --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,neorhapsody/tech-stack-detector"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/0GoHCqQrx1wmG69tr/builds/JhuLChrHTukLflEJV/openapi.json
