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

hexo-generator-llms

v0.1.1

Published

GEO for Hexo: generate a Markdown (.md) twin of every page plus llms.txt so AI/LLM crawlers get clean, token-efficient content (generative engine optimization).

Readme

hexo-generator-llms

npm version npm downloads license

GEO (Generative Engine Optimization) for Hexo.

Generate a clean Markdown (.md) copy of every Hexo page for AI/LLM crawlers, advertise it with <link rel="alternate" type="text/markdown">, and emit an llms.txt index — the static-site equivalent of Cloudflare's "serve Markdown to AI" content-negotiation, done at build time (works on GitHub Pages and any static host).

Why: LLMs pay per token, and a page of <div>/class/script HTML costs ~4–5× the tokens of the same content in Markdown. Serving a clean .md saves the crawler tokens and helps it read your content hierarchy (headings, lists, tables) without visual-markup noise.

Install

npm install hexo-generator-llms

The plugin auto-loads (its name starts with hexo-). On the next hexo generate it emits, for each page, an index.md next to the index.html:

public/2016/12/25/my-post/index.html
public/2016/12/25/my-post/index.md   ← new
public/llms.txt                      ← new

and injects into each page's <head>:

<link rel="alternate" type="text/markdown" href="https://example.com/2016/12/25/my-post/index.md">

How it works

  • Converts the rendered page HTML (post.content) to Markdown with Turndown + turndown-plugin-gfm (tables, fenced code, strikethrough). Using rendered HTML means any templating tags in your source Markdown are already expanded — nothing leaks into the .md.
  • Rewrites image/link URLs to absolute so a fetched .md is self-contained.
  • Records which pages got a .md and injects the alternate link only on those, by reading each page's own <link rel="canonical"> inside an after_render:html filter — no theme edits required.
  • Only emits for pages that resolve to an HTML document (path ends in / or .htm(l)). Files Hexo copies verbatim but still lists as pages — sw.js, web-app-manifest.json, a raw feed.xml, any data JSON in your source root — are skipped automatically: converting them to Markdown is meaningless, and emitting <asset>/index.md would make Hexo create a directory that collides with the asset file of the same name.

Themes without a canonical link

The alternate link injection keys off <link rel="canonical">. If your theme doesn't emit one, add this one line to your <head> instead:

<%- md_alternate_link() %>

Configuration

All optional — sensible defaults, works with no config:

# _config.yml
llms:
  enable: true
  types: [post, page]     # which sources to emit a .md for
  exclude: []             # paths to skip, e.g. [projects, photography]
  llms_txt: true          # /llms.txt index
  llms_full_txt: false    # /llms-full.txt (all bodies concatenated)
  alternate_link: true    # inject <link rel="alternate"> into <head>
  front_matter: true       # YAML header (title/source/date/tags) in each .md
  absolute_urls: true      # rewrite links/images to absolute URLs

Data-driven pages (e.g. a portfolio or gallery whose content is rendered from a template/data file rather than a Markdown body) have no meaningful body to convert — list their paths in exclude to skip them.

Note on GitHub Pages

GitHub Pages can't set a custom Content-Type on .md files, but AI crawlers discover the Markdown via the rel="alternate" hint, the .md extension, and llms.txt — not the response MIME type — so it works regardless.

License

MIT