GEO AI Core
Universal TypeScript engine for AI Search Optimization. Zero dependencies. Works with any Node.js 20+ framework.
Installation
bash
npm install geo-ai-coreQuick start
typescript
import { createGeoAI } from 'geo-ai-core';
const geo = createGeoAI({
siteName: 'My Site',
siteUrl: 'https://example.com',
provider: {
Pages: [
{ title: 'Home', url: '/', description: 'Welcome' },
{ title: 'About', url: '/about', description: 'About us' },
],
Products: [
{
title: 'Widget Pro',
url: '/products/widget-pro',
description: 'Our flagship widget',
price: '$29.99',
available: true,
},
],
},
crawlers: 'all',
});
// Generate llms.txt / llms-full.txt
const llmsTxt = await geo.generateLlms(false);
const llmsFullTxt = await geo.generateLlms(true);
// robots.txt block
const robotsTxt = geo.generateRobotsTxt();
// SEO signals
const metaTags = geo.generateMetaTags();
const linkHeader = geo.generateLinkHeader();
const jsonLd = geo.generateJsonLd();ContentProvider
For dynamic data sources, implement the ContentProvider interface. The getSections() method is called each time GEO AI generates content.
typescript
import { createGeoAI, type ContentProvider, type Section } from 'geo-ai-core';
class StrapiProvider implements ContentProvider {
async getSections(options?: { locale?: string }): Promise<Section[]> {
const products = await fetchProducts(options?.locale);
const posts = await fetchPosts(options?.locale);
return [
{
name: 'Products',
type: 'product',
resources: products.map((p) => ({
title: p.name,
url: p.slug,
description: p.summary,
price: p.price,
available: p.inStock,
})),
},
{
name: 'Blog',
type: 'article',
resources: posts.map((p) => ({
title: p.title,
url: p.slug,
description: p.excerpt,
content: p.body,
})),
},
];
}
}
const geo = createGeoAI({
siteName: 'My Site',
siteUrl: 'https://example.com',
provider: new StrapiProvider(),
cache: '24h',
crawlTracking: true,
});Caching
GEO AI supports pluggable caching via the CacheAdapter interface. Two built-in adapters are included:
| Adapter | Description |
|---|---|
| MemoryCacheAdapter | In-memory with TTL and automatic eviction. Default 1,000 max entries. |
| FileCacheAdapter | File-based with JSON metadata. Good for build-time caching. |
Pass a duration string as a shorthand — GEO AI creates a MemoryCacheAdapter automatically:
typescript
// Shorthand duration strings
cache: '1h' // 1 hour
cache: '24h' // 24 hours
cache: '7d' // 7 days
// Or pass a custom adapter
import { FileCacheAdapter } from 'geo-ai-core';
cache: new FileCacheAdapter({ dir: '.cache/geo-ai' })Crawl tracking
GDPR-compliant bot visit logging with SHA-256 IP anonymization. Uses the Web Crypto API — compatible with Edge Runtime.
typescript
const geo = createGeoAI({
// ...
crawlTracking: true, // uses built-in MemoryCrawlStore (10,000 max entries)
// Or with custom store and secret:
crawlTracking: {
store: new MyCustomStore(),
secret: process.env.CRAWL_SECRET,
},
});AI descriptions
Optional module for generating AI-optimized descriptions via Claude or OpenAI. Imported from a separate entry point — fully tree-shakeable.
typescript
import { AiGenerator } from 'geo-ai-core/ai';
const ai = new AiGenerator({
provider: 'anthropic',
apiKey: process.env.ANTHROPIC_API_KEY!,
model: 'claude-sonnet-4-20250514',
});
// Single item
const description = await ai.generate({
title: 'Widget Pro',
content: 'A high-quality widget made from premium materials...',
type: 'product',
price: '$29.99',
});
// Bulk generation (up to 50 items, batched by 5)
const results = await ai.bulkGenerate(items, {
batchSize: 5,
maxItems: 50,
onProgress: (completed, total) => {
console.log(`${completed}/${total}`);
},
});The AI generator uses a sliding window rate limiter (default 10 req/min) and classifies errors by type — auth, rate limit, server, network — for clean error handling.
Entry points
| Entry | Import | Contents |
|---|---|---|
| Main | geo-ai-core | createGeoAI, BotRulesEngine, CrawlTracker, SeoGenerator, cache adapters, all types |
| AI | geo-ai-core/ai | AiGenerator, RateLimiter, buildPrompt, classifyAiError |
Requirements
- Node.js 20 or higher
- TypeScript 5.5+ (recommended — ships .d.ts)