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

aeo-lens

v1.0.0

Published

AI Engine Optimization (AEO) analyzer - Analyze web content for AI readability, citation potential, and schema optimization

Downloads

29

Readme

npm version License: MIT

What is AEO?

AI Engine Optimization (AEO) is the practice of optimizing content so that AI systems (like ChatGPT, Perplexity, Claude, Google AI Overviews) can easily understand, cite, and reference your content. As AI-powered search becomes mainstream, AEO is becoming as important as traditional SEO.

Installation

npm install aeo-lens

Or use directly with npx (no installation required):

npx aeo-lens https://example.com

Three Ways to Use AEO-Lens

1. 📦 As a Library (Programmatic)

Import into your backend, CMS, or build pipeline:

import { aeoAudit, extractFromText } from 'aeo-lens';

// When a writer saves a blog post in your CMS
const content = extractFromText(blogPostContent);
const audit = aeoAudit(content);

if (audit.hallucinationRisk > 50) {
  throw new Error('Content has high hallucination risk - needs review');
}

if (audit.overallScore < 60) {
  return { status: 'draft', issues: audit.actionableFixes };
}

// Access detailed analysis
console.log(audit.details.vagueClaims);      // Vague words that need quantification
console.log(audit.details.ambiguity);         // Ambiguous pronouns
console.log(audit.details.answerBlocks);      // Self-contained answer blocks
console.log(audit.details.entities);          // Named entities detected
console.log(audit.details.citeableSentence);  // Best sentence for AI citation

2. 🖥️ As a CLI Tool (Command Line)

Analyze any website or local file directly from your terminal:

# Analyze any URL (uses headless browser for JavaScript-rendered sites)
npx aeo-lens https://example.com/blog/article

# Analyze local files
npx aeo-lens ./my-content.md
npx aeo-lens ./article.html
npx aeo-lens ./blog-post.txt

# Get JSON output for scripting
npx aeo-lens https://example.com --json

# Set minimum score threshold (for CI/CD)
npx aeo-lens ./content.md --min-score 70

# Choose persona for analysis
npx aeo-lens https://example.com --persona technical

Example CLI Output:

╔═══════════════════════════════════════╗
║         �  AEO-LENS v1.0.0            ║
║   AI Engine Optimization Analyzer     ║
╚═══════════════════════════════════════╝

╔═══════════════════════════════════════╗
║           AEO SCORE: 65               ║
║           Grade: C                    ║
╚═══════════════════════════════════════╝

═══ QUICK STATS ═══

  Words: 1250  │  FK Grade: 8.5  │  Headings: 6  │  Ext Links: 4  │  Data Pts: 8  │  Chunks: 3

═══ SCORE BREAKDOWN ═══

  Trust Score          ██████████████████░░░░░░░░░░░░ 58/100
  Extractability       ████████████████████████░░░░░░ 78/100
  Structure            ██████████████████████░░░░░░░░ 72/100
  Hallucination Risk   ██████░░░░░░░░░░░░░░░░░░░░░░░░ 20/100

═══ 🔍 RETRIEVABILITY SCORE ═══

  ██████████████████████████████░░░░░░░░░░ 75%
  Status: CRAWLABLE

═══ 📋 SCHEMA "SPEAKING AI" VALIDATOR ═══

  ❓ FAQ Page     ✓ DETECTED
  📝 How-To       ✗ MISSING
  📰 Article      ✓ DETECTED
  🛍️ Product      ✗ MISSING
  ⭐ Review       ✗ MISSING

═══ 📦 SELF-CONTAINED CHUNKS AUDITOR ═══

  3 citeable chunks found (target: 3+)
  Chunks are H2/H3 sections with 90-120 word direct answers

═══ ⚠️  HALLUCINATION RISK METER ═══

  LOW                              HIGH
  ──────▼───────────────────────────────
  20% - LOW RISK

═══ 🔎 VAGUE CLAIMS DETECTOR ═══

  3 vague terms found that may cause AI misinterpretation

  1. "significant" in: "We saw significant improvements in conversion rates..."
     → Fix: Use specific numbers (e.g., "35% increase")
  2. "many" in: "Many users reported better results after..."
     → Fix: Specify the quantity (e.g., "over 500 users")

═══ 🏷️  ENTITY OPTIMIZER ═══

  HubSpot(8)  SEO(6)  Marketing(5)  AI(4)  Content(3)

  Topic Cluster: marketing (70% match)
  Missing keywords: engagement, campaign

═══ 💬 CITEABLE SNIPPET MOCK-UP ═══

  ┌─────────────────────────────────────────────────────────┐
  │ "According to HubSpot research, companies that blog..."  │
  └─────────────────────────────────────────────────────────┘
  Citeability: HIGH (score: 75)

═══ 🔧 ACTIONABLE FIXES ═══

  1. Replace 3 vague terms with specific data
  2. Add How-To schema markup
  3. Create more self-contained answer blocks (90-120 words)

3. 🔄 In CI/CD (Automation)

Add to your GitHub Actions, GitLab CI, or any build pipeline to ensure content quality:

# .github/workflows/aeo-check.yml
name: AEO Quality Check

on: [push, pull_request]

jobs:
  aeo-audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'
      
      - name: Run AEO Audit
        run: npx aeo-lens ./content/**/*.md --min-score 70
        # Fails the build if any content scores below 70

Exit Codes: | Code | Meaning | |------|---------| | 0 | Success - score meets minimum threshold | | 1 | Failure - score below minimum threshold | | 2 | Error - invalid input, network error, etc. |


Features

🎯 Hallucination Risk Engine

Detects content patterns that may cause AI to misinterpret or hallucinate information.

import { detectAmbiguity, detectVagueClaims } from 'aeo-lens';

// Detect dangling pronouns (>15 words from proper noun)
const ambiguity = detectAmbiguity('The system processes data. After several steps, it sends results.');
// Flags "it" as ambiguous - too far from "system"

// Detect vague claims without quantification
const vague = detectVagueClaims('Many users saw significant improvements.');
// Flags: "many" → "Specify the quantity (e.g., over 500 users)"
// Flags: "significant" → "Use specific numbers (e.g., 35% increase)"

📊 Citation Probability Scorer

Identifies content with high citation potential based on claim-evidence structure.

import { scoreClaimEvidence } from 'aeo-lens';

const result = scoreClaimEvidence(content);
// Rewards: numerical stat + declarative verb + external link/citation
// { wellSupportedCount: 5, totalClaims: 8, score: 75 }

📦 AI Chunking Auditor

Checks for self-contained answer blocks that AI can easily extract.

import { auditAnswerBlocks } from 'aeo-lens';

const chunks = auditAnswerBlocks(content);
// Optimal: H2/H3 header + direct answer (90-120 words) with key entities
// { optimalBlocks: 3, totalBlocks: 8, score: 65 }

🤖 Bot-Blocker Check

Validates robots.txt permissions for AI crawlers.

import { validateRobotsTxt } from 'aeo-lens';

const robots = await validateRobotsTxt('https://example.com');
console.log(robots.aiBots);
// [
//   { bot: 'GPTBot', allowed: true },
//   { bot: 'ClaudeBot', allowed: false },
//   { bot: 'Google-Extended', allowed: true }
// ]
console.log(robots.hasLlmsTxt); // false
// Recommendation: "Add llms.txt file for LLM-specific instructions"

📝 Answer-First Grading

Ensures key information isn't buried where AI might miss it.

import { gradeAnswerFirst } from 'aeo-lens';

const result = gradeAnswerFirst(content);
// {
//   answerPosition: 'first' | 'second' | 'buried' | 'not-found',
//   score: 85,
//   keyInfoInLead: ['data/statistics', 'direct answer'],
//   recommendations: []
// }

🏷️ Entity & Topic Detection

Identifies named entities and matches content to topic clusters.

import { aeoAudit } from 'aeo-lens';

const audit = aeoAudit(content);
console.log(audit.details.entities);
// [{ entity: 'HubSpot', count: 8 }, { entity: 'SEO', count: 6 }]

console.log(audit.details.topicCluster);
// { cluster: 'marketing', score: 0.7, matches: ['seo', 'content'], missing: ['engagement'] }

💬 Citeable Snippet Finder

Identifies the most AI-citeable sentence in your content.

import { aeoAudit } from 'aeo-lens';

const audit = aeoAudit(content);
console.log(audit.details.citeableSentence);
// {
//   text: "According to HubSpot research, companies that blog get 55% more visitors.",
//   score: 85,
//   rating: 'HIGH'
// }

API Reference

Main Functions

| Function | Description | |----------|-------------| | aeoAudit(content) | Main audit returning all scores and detailed analysis | | aeoAuditWithRobots(content, url) | Full audit including robots.txt validation (async) | | extractFromText(text, options?) | Extract structured content from plain text | | extractFromHTML(html) | Extract structured content from HTML | | analyzeText(text, options?) | Quick text analysis with AEOAnalyzer |

Analysis Functions

| Function | Description | |----------|-------------| | detectVagueClaims(text) | Find vague words without quantification | | scoreClaimEvidence(content) | Score claim-evidence structure | | auditAnswerBlocks(content) | Check for self-contained answer blocks | | detectAmbiguity(text) | Find dangling pronouns | | gradeAnswerFirst(content) | Check if answer is in first paragraph | | validateRobotsTxt(url) | Check AI bot permissions (async) |

CLI Options

npx aeo-lens <url-or-file> [options]

Arguments:
  <url-or-file>    URL to analyze or path to local file (.txt, .html, .md)

Options:
  --json           Output results as JSON (for scripting)
  --min-score <n>  Exit with code 1 if score < n (for CI/CD)
  --persona <p>    Set analysis persona: consumer | technical | c-suite
  --no-color       Disable colored output
  --help, -h       Show help message

AEO Audit Result Structure

interface AEOAuditResult {
  // Main Scores (0-100)
  trustScore: number;        // Citation probability
  hallucinationRisk: number; // Risk of AI misinterpretation (lower is better)
  extractability: number;    // How easily AI can extract info
  structureScore: number;    // Content structure quality
  overallScore: number;      // Combined weighted score
  
  // Recommendations
  actionableFixes: string[]; // Specific improvements to make
  
  // Detailed Analysis
  details: {
    vagueClaims: VagueClaimsResult;      // Vague words needing quantification
    claimEvidence: ClaimEvidenceResult;   // Claim-evidence pairs
    answerBlocks: AnswerBlocksResult;     // Self-contained chunks
    ambiguity: AmbiguityResult;           // Dangling pronouns
    
    // Additional metrics
    wordCount: number;
    fleschKincaid: number;
    headingCount: number;
    externalLinks: number;
    dataPoints: number;
    schemaTypes: string[];
    hasFAQ: boolean;
    entities: EntityCount[];
    topicCluster: TopicClusterMatch | null;
    citeableSentence: CiteableSentenceResult;
  };
}

Scoring Algorithm

AEO-Lens uses a weighted scoring algorithm:

| Component | Weight | What it Measures | |-----------|--------|------------------| | Trust Score | 30% | Citation probability based on evidence, links, specificity | | Hallucination Risk (inverted) | 25% | Ambiguous pronouns, vague claims, unsupported statements | | Extractability | 25% | Schema markup, FAQ sections, answer blocks | | Structure | 20% | Headings, lists, content organization |

Grade Scale: | Score | Grade | |-------|-------| | 80-100 | A | | 70-79 | B | | 60-69 | C | | 50-59 | D | | 0-49 | F |


Use Cases

CMS Integration

Block publishing if content quality is too low:

// Strapi/Sanity/WordPress plugin
const audit = aeoAudit(extractFromText(post.content));

if (audit.hallucinationRisk > 60) {
  return { error: 'High hallucination risk - please review flagged sections' };
}

if (audit.overallScore < 50) {
  return { warning: 'Content needs improvement', fixes: audit.actionableFixes };
}

Content Auditing

Analyze existing content library:

import { aeoAudit, extractFromHTML } from 'aeo-lens';
import fs from 'fs';

const files = fs.readdirSync('./content');
const results = files.map(file => {
  const html = fs.readFileSync(`./content/${file}`, 'utf-8');
  const content = extractFromHTML(html);
  return { file, audit: aeoAudit(content) };
});

// Sort by score to find content needing improvement
results.sort((a, b) => a.audit.overallScore - b.audit.overallScore);

Real-time Writing Feedback

Provide feedback as users write:

// Debounced analysis on text change
const analyzeContent = debounce((text) => {
  const content = extractFromText(text);
  const audit = aeoAudit(content);
  
  updateUI({
    score: audit.overallScore,
    issues: audit.details.vagueClaims.claims,
    suggestions: audit.actionableFixes
  });
}, 500);

Requirements

  • Node.js >= 16.0.0
  • Chrome/Chromium (for CLI URL analysis - auto-detected)

For CLI URL analysis, AEO-Lens uses Puppeteer to render JavaScript-heavy sites. Chrome is automatically detected on:

  • Windows: C:\Program Files\Google\Chrome\Application\chrome.exe
  • macOS: /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
  • Linux: /usr/bin/google-chrome or /usr/bin/chromium

Troubleshooting

CLI can't fetch a website

Some websites block automated requests. Workarounds:

  1. Save the page locally (Ctrl+S in browser) and analyze the HTML file
  2. Copy the article text to a .txt file and analyze that
  3. Use the library programmatically with your own fetching logic

Low scores on JavaScript-heavy sites

The CLI uses a headless browser, but some sites may still not render fully. For best results with SPAs, save the rendered page locally.


License

MIT © Aryan Patankar

Links