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

programmatic-seo

v1.4.0

Published

Programmatic SEO CLI — Generate SEO pages with AI and serve via local API for any CMS

Readme

PSEO

Programmatic SEO CLI — Generate SEO pages with AI and serve them via a local REST API for any CMS.

Built by metehan.ai

██████╗ ███████╗███████╗ ██████╗
██╔══██╗██╔════╝██╔════╝██╔═══██╗
██████╔╝███████╗█████╗  ██║   ██║
██╔═══╝ ╚════██║██╔══╝  ██║   ██║
██║     ███████║███████╗╚██████╔╝
╚═╝     ╚══════╝╚══════╝ ╚═════╝

What is PSEO?

PSEO is a CLI tool that generates programmatic SEO pages using AI and serves them through a local REST API. This makes it universally compatible with any website platform — WordPress, Webflow, Framer, or your own custom CMS.

How it works:

  1. Provide seed data (keywords) as CSV or JSON
  2. PSEO generates full pages (title, meta description, HTML body) using your chosen AI
  3. Start the local API server
  4. Connect your CMS to the API endpoints to pull content

Supported AI Providers

| Provider | Model | API | |----------|-------|-----| | OpenAI | gpt-5.2 | Responses API | | Google Gemini | gemini-3-flash-preview / gemini-3-pro-preview | Generative AI | | Anthropic | claude-opus-4-6 | Messages API | | X.ai | grok-3 | OpenAI-compatible | | Qwen | qwen-max | OpenAI-compatible | | Ollama | any local model | Local |

Installation

npm install -g programmatic-seo
# or
npm install -g pseo-ai

Quick Start

# Generate a page — just pass a keyword
pseo generate "best running shoes 2024"

# Generate multiple pages at once
pseo generate "best running shoes" "marathon training guide" "running injuries"

# Start the API server to access your pages
pseo serve

Your pages are now available at http://localhost:3099/api/pages. Open http://localhost:3099 for the live dashboard.

Optional setup

# Interactive config wizard (set provider, API key, linking, etc.)
pseo init

# Bulk generate from a seed file
pseo generate -i seeds.csv

CLI Commands

pseo init

Optional interactive setup wizard that creates pseo.config.json:

pseo init

Configures: AI provider, API key, language, tone, word count, internal linking, and server port. Not required — you can skip this and pass everything via flags or env vars.

pseo generate

Generate SEO pages — pass keywords directly or use a seed file:

# Simplest usage — just a keyword
pseo generate "best coffee makers"

# Multiple keywords
pseo generate "best coffee makers" "espresso vs drip coffee" "coffee grinder guide"

# With provider override
pseo generate "best coffee makers" -p gemini

# Interactive — prompts you for keywords
pseo generate

# Bulk from seed file (optional)
pseo generate -i seeds.csv
pseo generate -i seeds.json --provider anthropic

Options:

| Flag | Description | |------|-------------| | [keywords...] | One or more keywords as arguments | | -i, --input <file> | Seed data file — CSV or JSON (optional) | | -p, --provider <name> | AI provider override | | -m, --model <name> | Model override | | -k, --api-key <key> | API key override | | -l, --language <lang> | Content language (default: en) |

pseo serve

Start the local API server with built-in dashboard:

pseo serve
pseo serve --port 8080

Opens a dashboard at http://localhost:3099 with live page listing and an API documentation page at http://localhost:3099/docs.

Seed Data Format

CSV

keyword,category,slug
best running shoes 2024,shoes,best-running-shoes-2024
marathon training guide,training,
how to prevent running injuries,health,

Required column: keyword. Optional: category, slug, custom_prompt.

JSON

[
  { "keyword": "best running shoes 2024", "category": "shoes" },
  { "keyword": "marathon training guide", "category": "training" }
]

Or:

{
  "keywords": ["best running shoes 2024", "marathon training guide"]
}

REST API

Once pseo serve is running, these endpoints are available:

GET /api/health

{ "status": "ok", "timestamp": "2024-03-18T09:00:00Z" }

GET /api/pages?page=1&limit=20

{
  "data": [
    {
      "slug": "best-running-shoes-2024",
      "keyword": "best running shoes 2024",
      "title": "Best Running Shoes in 2024 — Complete Guide",
      "meta_description": "Discover the top running shoes...",
      "body": "<h2>Introduction</h2><p>...</p>",
      "internal_links": [],
      "published_date": "2024-03-18T00:00:00Z",
      "created_at": "2024-03-18T09:00:00Z"
    }
  ],
  "total": 1,
  "page": 1,
  "limit": 20,
  "totalPages": 1
}

GET /api/pages/:slug

Returns a single page by slug.

POST /api/generate

Generate pages via API:

curl -X POST http://localhost:3099/api/generate \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "openai",
    "seed_data": [
      { "keyword": "best coffee makers 2024" }
    ]
  }'

DELETE /api/pages/:slug

Delete a page by slug.

Internal Linking

PSEO can automatically add internal links to generated content:

From sitemap.xml:

{
  "internalLinking": {
    "enabled": true,
    "source": "sitemap",
    "sitemapUrl": "https://example.com/sitemap.xml"
  }
}

From manual URL list:

{
  "internalLinking": {
    "enabled": true,
    "source": "manual",
    "urls": [
      "https://example.com/guide-1",
      "https://example.com/guide-2"
    ]
  }
}

Both sources:

{
  "internalLinking": {
    "enabled": true,
    "source": "both",
    "sitemapUrl": "https://example.com/sitemap.xml",
    "urls": ["https://example.com/extra-page"]
  }
}

CMS Integration Examples

WordPress (via WP REST API or custom plugin)

Fetch from PSEO API and create posts:

const response = await fetch("http://localhost:3099/api/pages");
const { data } = await response.json();

for (const page of data) {
  await fetch("https://your-site.com/wp-json/wp/v2/posts", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: "Basic " + btoa("user:password"),
    },
    body: JSON.stringify({
      title: page.title,
      content: page.body,
      status: "publish",
      meta: { _yoast_wpseo_metadesc: page.meta_description },
    }),
  });
}

Webflow (via CMS API)

const response = await fetch("http://localhost:3099/api/pages");
const { data } = await response.json();

for (const page of data) {
  await fetch(`https://api.webflow.com/v2/collections/{id}/items`, {
    method: "POST",
    headers: {
      Authorization: "Bearer YOUR_TOKEN",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      fieldData: {
        name: page.title,
        slug: page.slug,
        "meta-description": page.meta_description,
        "post-body": page.body,
      },
    }),
  });
}

Config Reference

pseo.config.json:

{
  "provider": "openai",
  "model": "gpt-5.2",
  "apiKey": "sk-...",
  "language": "en",
  "tone": "informative",
  "wordCount": 1500,
  "internalLinking": {
    "enabled": false,
    "source": "manual",
    "urls": []
  },
  "server": {
    "port": 3099,
    "host": "localhost"
  }
}

Environment Variables

Instead of storing keys in the config file, use environment variables:

| Variable | Provider | |----------|----------| | OPENAI_API_KEY | OpenAI | | GEMINI_API_KEY | Google Gemini | | ANTHROPIC_API_KEY | Anthropic | | XAI_API_KEY | X.ai (Grok) | | QWEN_API_KEY | Qwen | | OLLAMA_HOST | Ollama (default: http://localhost:11434) |

License

MIT — built by metehan.ai