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

@e11ty/eleventy-plugin-search-index

v0.0.5

Published

11ty plugin for generating JSON structures from markdown site files for creating fuzzy searches.

Readme

@e11ty/eleventy-plugin-search-index

An Eleventy plugin which generates JSON structures from markdown files. Use the output to implement an auto-complete search module.

NOTE

This plugin isn't universally compatible with all Eleventy static sites. It's tailored to my specific development approach, which means usage might require adjustments in certain contexts due to its particular requirements and methods.

Why?

Fuck algolia, that's why.

Install

The @11ty/eleventy module is a peer and needs to be installed along side it.

pnpm add @e11ty/eleventy-plugin-json-fusion -D

Usage

Provide the plugin via eleventyConfig and handling options. The onHeading and onText methods will allow you to hook into the parse operations and give you control of the the generated JSON. You can manipulate the final structure using onOutput method before it is written.

Optionally use with 11ty.ts wrapper for type completions.

const { defineConfig } = require('11ty.ts'); // Optional
const  {search } = require('@e11ty/eleventy-plugin-search-index');

module.exports = defineConfig(eleventyConfig => {

  eleventyConfig.addPlugin(search, {
    shortCode:'search',
    output: '.',
    minify: false,
    stripHtml: true,    // Strips markup tags occurrences (ignores codeblocks)
    stripMarkdown: true, // Strips markdown syntax occurrences (ignores codeblocks)
    ignore: {
      syntax: [],   // Syntax (regexp) to ignore from processing
      heading: [],  // Headings (lowercase string) to ignore
    },
    codeblock: [
      'bash' // Process inner content of bash codeblocks
    ],
    content: [
      'text',  // Process all paragraph content
      'quote', // Process all blockquote content
      'list'  // Process all list content
    ],
    onHeading (heading) {
      // return string to replace
      // return false to skip
    },
    onContent (text) {
      // return string to replace
      // return false to skip
    },
    onOutput (json) {
      // Return new array to replace before writing
    }
  })

});

Example

The plugin will compose a JSON file containing an array list of objects that describe the contents of markdown files. Each page requires a frontmatter reference of title and permalink for a record to be created, failure to provide these will result in the page output not being generated.

Shortcode

In your layout file, include the liquid shortcode. You can customize the shortcode name but it defaults to search

<html>
  <head>
    <title>{{ title }}</title>
    <meta charset="UTF-8">
    <meta name="description" content="{{ description }}">
  </head>
  <body>

    {{ content }}

    {% search 'demo' %} {% # ← output filename: '_site/demo.json' %}

  </body>
</html>

Markdown File

Take the following markdown file, we have provided the required frontmatter references and have some content. The plugin will read, parse and generate an object representation of the page and add it to the output array.

---
title: 'Foo Page'
description: 'Hello World'
permalink: '/foo/index.html'
layout: 'base.liquid'
tags:
  - 'xxx'
---

# First Heading

Example text

### Second Heading

Lorem ipsum dolor

JSON Output

Based on the above structure, the object record generated will take the following shape. There are 3 properties in the structure, pages and heading and content, every reference can be associated with one another. You'll typically be using the content[] reference for your search client.

{
  "pages": [
    {
      "title": "Foo Page",
      "description": "Hello World",
      "url": "/foo/",
      "tags": ["xxx"],
      "pidx": 0,      // page index  (i.e, this index)
      "hidx": [0, 1], // heading indexes start and end location
      "cidx": [0, 3], // content indexes start and end location
    }
  ],
  "heading": [
    {
      "anchor": "/foo#first-heading",
      "pidx": 0,      // page index
      "hidx": 0,      // heading index (i.e, this index)
      "cidx": [0, 1], // content indexes start and end location
    },
    {
      "anchor": "/foo#second-heading",
      "pidx": 0,      // page index
      "hidx": 1,      // heading index (i.e, this index)
      "cidx": [2, 3], // content indexes start and end location
    }
  ],
  "content": [
    {
      "text": "Default Structure",
      "type": "heading",
      "sort": 1, // sort integer for filtering
      "cidx": 0, // content index (i.e, this index)
      "hidx": 0, // index of the heading entry within heading[]
      "pidx": 0, // index of the page entry within pages[]
    },
    {
      "text": "Example text",
      "type": "text", // the type of content
      "sort": 2, // sort integer for filtering
      "cidx": 1, // content index (i.e, this index)
      "hidx": 0, // index of the heading entry within heading[]
      "pidx": 0, // index of the page entry within pages[]
    },
    {
      "text": "Second heading",
      "type": "heading",
      "sort": 1, // sort integer for filtering
      "cidx": 2, // content index (i.e, this index)
      "hidx": 1, // index of the heading entry within heading[]
      "pidx": 0, // index of the page entry within pages[]
    },
    {
      "text": "Lorem ipsum dolor",
      "type": "text", // the type of content
      "sort": 1, // sort integer for filtering
      "cidx": 3, // content index (i.e, this index)
      "hidx": 1, // index of the heading entry within heading[]
      "pidx": 0, // index of the page entry within pages[]
    }
  ]
}

Client Integration

This plugin was designed specifically to be used with a third party solution. The implementation on the client is not the job of this plugin, that logic is left up to you. For those seeking a rough example of how you can go about using the generated JSON output to create your own fuzzy-search can take a look at how I've done this using the static site framework I wrote called spx.

WARNING

SPX (15kb gzip) is a full fledged framework and not suitable for isolated usage, meaning you should not install SPX just to use this plugin but instead, use the linked examples as a reference.

License

Apache 2.0