@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.
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-detectorQuick 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';
}): BrandAnalysisResultBasic 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.pyIntegration 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
- @rankfor/dice-roller - AI response stability analyzer
Support
- Documentation
- Issues
- Discord (coming soon)
Changelog
See CHANGELOG.md for release history.
