npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@rankfor/brand-detector

v1.1.0

Published

Detect and analyze brand mentions in LLM/AI responses with 10k+ brand database from Simple Icons and Wikidata

Downloads

249

Readme

@rankfor/brand-detector

Detect and analyze brand mentions in LLM/AI responses with 10,000+ brand database from Simple Icons and Wikidata.

npm version License: MIT

Features

  • 10,847 brands from Simple Icons (curated tech/SaaS) and Wikidata (global brands)
  • Fast O(1) lookups using optimized data structures
  • Multi-word brand support (e.g., "Salesforce Marketing Cloud")
  • Confidence scoring (high/medium/low) to filter ambiguous brands
  • Context extraction to analyze surrounding text for each brand mention
  • TypeScript-first with full type definitions
  • Zero dependencies (except bundled data)

Installation

npm install @rankfor/brand-detector

Quick Start

Using Bundled Database (10,000+ brands)

import { BrandDetector } from '@rankfor/brand-detector';

const detector = new BrandDetector();

// Analyze LLM response
const result = detector.analyzeLLMResponse(
  "For CRM, I recommend Salesforce, HubSpot, or Pipedrive. Salesforce is best for enterprise."
);

console.log(result);
// {
//   totalBrands: 3,
//   totalMentions: 4,
//   topBrand: 'Salesforce',
//   mentions: [
//     { brand: 'Salesforce', count: 2, confidence: 'high' },
//     { brand: 'HubSpot', count: 1, confidence: 'high' },
//     { brand: 'Pipedrive', count: 1, confidence: 'high' }
//   ]
// }

Using Custom Brand Database

import { BrandDetector } from '@rankfor/brand-detector';
import myBrands from './my-brands.json';

const detector = new BrandDetector(myBrands);

// Now detects your custom brands
const result = detector.analyzeLLMResponse(
  "We use CustomCRM and OurBrand products."
);

Custom Database Format:

{
  "meta": {
    "version": "1.0.0",
    "generated_at": "2025-01-20T00:00:00.000Z",
    "sources": [
      {
        "name": "My Brands",
        "url": "https://example.com",
        "count": 100,
        "license": "CC0"
      }
    ],
    "total_raw": 100,
    "total_filtered": 100,
    "ignored_terms": ["apple", "orange"]
  },
  "brands": ["CustomCRM", "OurBrand", "CompetitorX"],
  "high_confidence": ["CustomCRM", "OurBrand"]
}

API Reference

analyzeLLMResponse(llmResponse, options?)

Primary API for analyzing AI/LLM responses.

brandDetector.analyzeLLMResponse(llmResponse: string, options?: {
  extended?: boolean;          // Include context around each mention
  contextRadius?: number;      // Characters before/after (default: 50)
  minConfidence?: 'high' | 'medium' | 'low';
}): BrandAnalysisResult

Basic Mode (counts only)

const result = brandDetector.analyzeLLMResponse(
  "I recommend Salesforce and HubSpot."
);

// {
//   totalBrands: 2,
//   totalMentions: 2,
//   topBrand: 'Salesforce',
//   mentions: [
//     { brand: 'Salesforce', count: 1, confidence: 'high' },
//     { brand: 'HubSpot', count: 1, confidence: 'high' }
//   ]
// }

Extended Mode (with context)

const result = brandDetector.analyzeLLMResponse(
  "Salesforce offers robust features but HubSpot has better UX.",
  {
    extended: true,
    contextRadius: 30,
  }
);

// {
//   totalBrands: 2,
//   totalMentions: 2,
//   mentions: [
//     {
//       brand: 'Salesforce',
//       count: 1,
//       confidence: 'high',
//       contexts: ['Salesforce offers robust features but...']
//     },
//     {
//       brand: 'HubSpot',
//       count: 1,
//       confidence: 'high',
//       contexts: ['...features but HubSpot has better UX.']
//     }
//   ]
// }

Other Methods

// Check if text is a brand
brandDetector.isBrand('Salesforce');  // true

// Get confidence level
brandDetector.getConfidence('HubSpot');  // 'high'
brandDetector.getConfidence('Oracle');   // 'low' (dictionary word)

// Extract unique brand names
brandDetector.extractBrandNames(text, 'medium');  // ['Salesforce', 'HubSpot']

// Count mentions
brandDetector.countBrandMentions(text);             // 5
brandDetector.countBrandMentions(text, 'Salesforce');  // 2

// Get autocomplete suggestions
brandDetector.getSuggestions('Sales', 10);  // ['Salesforce', 'Salesforce Marketing Cloud', ...]

// Get database metadata
brandDetector.getMetadata();  // { version, sources, total_brands, ... }

Use Cases

1. Competitive Intelligence

Track which brands AI platforms recommend:

const chatGPT = brandDetector.analyzeLLMResponse(chatGPTResponse);
const claude = brandDetector.analyzeLLMResponse(claudeResponse);
const gemini = brandDetector.analyzeLLMResponse(geminiResponse);

// Compare recommendation share across models
for (const brand of allBrands) {
  console.log(`${brand}:`, {
    chatGPT: chatGPT.mentions.find(m => m.brand === brand)?.count || 0,
    claude: claude.mentions.find(m => m.brand === brand)?.count || 0,
    gemini: gemini.mentions.find(m => m.brand === brand)?.count || 0,
  });
}

2. Gender Bias Research

Detect brand mentions in gender-framed queries:

const husbandGifts = brandDetector.analyzeLLMResponse(husbandResponse);
const wifeGifts = brandDetector.analyzeLLMResponse(wifeResponse);

// Find gender-locked brands
const onlyHusband = husbandGifts.mentions.filter(
  m => !wifeGifts.mentions.some(w => w.brand === m.brand)
).map(m => m.brand);

console.log('Husband-only brands:', onlyHusband);

3. Stability Analysis (Dice Roll)

Analyze brand consistency across multiple responses:

const results = [];
for (let i = 0; i < 5; i++) {
  const response = await getChatGPTResponse(prompt);
  results.push(brandDetector.analyzeLLMResponse(response));
}

// Calculate stability
const allBrands = new Set(results.flatMap(r => r.mentions.map(m => m.brand)));

for (const brand of allBrands) {
  const appearances = results.filter(r =>
    r.mentions.some(m => m.brand === brand)
  ).length;

  const stability = (appearances / results.length) * 100;
  console.log(`${brand}: ${stability}% stability`);
}

4. Sentiment Analysis

Use extended mode to analyze how brands are described:

const result = brandDetector.analyzeLLMResponse(llmResponse, {
  extended: true,
});

const positiveWords = /excellent|great|best|recommended/i;
const negativeWords = /expensive|complex|difficult/i;

for (const mention of result.mentions) {
  if (mention.contexts) {
    const sentiment = mention.contexts.reduce((score, context) => {
      if (positiveWords.test(context)) score += 1;
      if (negativeWords.test(context)) score -= 1;
      return score;
    }, 0);

    console.log(`${mention.brand}: sentiment score ${sentiment}`);
  }
}

Confidence Levels

| Level | Source | Examples | Use Case | |-------|--------|----------|----------| | High | Simple Icons | Salesforce, HubSpot, Microsoft | Primary detection | | Medium | Wikidata | Regional brands, B2B companies | Comprehensive analysis | | Low | Dictionary words | Target, Apple, Oracle | Contextual only |

Filter by confidence:

// High-confidence only (curated tech/SaaS brands)
const result = brandDetector.analyzeLLMResponse(llmResponse, {
  minConfidence: 'high',
});

// Include all brands (including dictionary words)
const result = brandDetector.analyzeLLMResponse(llmResponse, {
  minConfidence: 'low',
});

TypeScript Types

interface BrandAnalysisResult {
  totalBrands: number;
  totalMentions: number;
  mentions: BrandMention[];
  topBrand: string | null;
}

interface BrandMention {
  brand: string;
  count: number;
  confidence: 'high' | 'medium' | 'low';
  contexts?: string[];  // Only in extended mode
}

Database

The package includes a pre-generated database of 10,847 brands from:

  • Simple Icons (3,245 brands): Curated tech/SaaS brands with logos
  • Wikidata (8,732 brands): Global brands with verified logos

Both sources are CC0 licensed (public domain), making them safe for commercial use.

Custom Brand Databases

You can provide your own brand database to detect custom or niche brands:

import { BrandDetector } from '@rankfor/brand-detector';
import type { BrandDatabase } from '@rankfor/brand-detector';

// Your custom brands
const myBrands: BrandDatabase = {
  meta: {
    version: '1.0.0',
    generated_at: new Date().toISOString(),
    sources: [{ name: 'My Brands', url: '', count: 3, license: 'CC0' }],
    total_raw: 3,
    total_filtered: 3,
    ignored_terms: []
  },
  brands: ['CustomCRM', 'OurBrand', 'CompetitorX'],
  high_confidence: ['CustomCRM', 'OurBrand']
};

const detector = new BrandDetector(myBrands);

Extending the Bundled Database

To add your brands to the bundled database:

import { BrandDetector } from '@rankfor/brand-detector';
import brandsDb from '@rankfor/brand-detector/data/brands.json';
import type { BrandDatabase } from '@rankfor/brand-detector';

// Merge bundled + custom brands
const extendedDb: BrandDatabase = {
  ...brandsDb,
  brands: [
    ...brandsDb.brands,
    'CustomCRM',
    'OurBrand',
    'CompetitorX'
  ],
  high_confidence: [
    ...brandsDb.high_confidence,
    'CustomCRM',
    'OurBrand'
  ]
};

const detector = new BrandDetector(extendedDb);

Regenerating the Database

To update the brand database with latest data:

cd node_modules/@rankfor/brand-detector
python scripts/fetch-brands.py

Integration with @rankfor/dice-roller

Perfect companion to @rankfor/dice-roller for comprehensive AI visibility analysis:

import { DiceRoller } from '@rankfor/dice-roller';
import { brandDetector } from '@rankfor/brand-detector';

const roller = new DiceRoller({ apiKey: process.env.GEMINI_API_KEY });

// Run stability analysis
const result = await roller.roll({
  prompt: "What are the best CRM tools?",
  iterations: 5,
  model: 'gemini',
});

// Analyze brand mentions in each response
for (const response of result.responses) {
  const brands = brandDetector.analyzeLLMResponse(response.text);
  console.log(`Iteration ${response.iteration}:`, brands.mentions);
}

Performance

  • Lookups: O(1) using Set and Map
  • Memory: ~10MB (bundled database)
  • Multi-word: Supports up to 3-word brand names
  • Detection: O(n) where n = word count

Contributing

Contributions welcome! Please see CONTRIBUTING.md.

License

MIT © Rankfor.AI

Brand database sources (Simple Icons, Wikidata) are CC0 (public domain).

Related Packages

Support

Changelog

See CHANGELOG.md for release history.