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

@curiolabs/toc

v0.1.2

Published

Curio Table of Contents

Readme

@curiolabs/toc

A lightweight JavaScript library that automatically generates table of contents from H2 headers with smooth scrolling navigation.

Features

  • 🚀 Automatic TOC Generation: Scans content blocks for H2 headers and builds navigation
  • 🎯 Smooth Scrolling: Animated scroll with customizable easing and duration
  • 🔗 Smart ID Generation: Auto-generates unique IDs with proper slugification
  • ⚙️ Configurable: Customizable scroll offset, duration, and URL hash behavior
  • 📱 Webflow Compatible: Built-in Webflow integration
  • 🎨 Template-Based: Uses your existing HTML structure as a template
  • 📦 Zero Dependencies: Pure vanilla JavaScript, works everywhere
  • 🔧 UMD Compatible: Works with AMD, CommonJS, or as a global

Installation

Via Script Tag

<script src="https://unpkg.com/@curiolabs/toc@latest/toc.js"></script>

Via npm

npm install @curiolabs/toc

Quick Start

1. HTML Structure

Set up your HTML with the required cur-toc-element attributes:

<!-- TOC Container -->
<div cur-toc-element="container">
  <ul>
    <!-- Template item (will be cloned and removed) -->
    <li>
      <a href="#" cur-toc-element="link">Template Link</a>
    </li>
  </ul>
</div>

<!-- Content with headers -->
<div cur-toc-element="contents">
  <h2>First Section</h2>
  <p>Content here...</p>

  <h2>Second Section</h2>
  <p>More content...</p>
</div>

2. Automatic Initialization

The library automatically initializes when the DOM is ready. No additional JavaScript required!

Configuration

Configure behavior using attributes on the container element:

<div
  cur-toc-element="container"
  cur-toc-offset="80"
  cur-toc-duration="600"
  cur-toc-hideurlhash="true"
>
  <!-- TOC structure -->
</div>

Configuration Options

| Attribute | Type | Default | Description | | --------------------- | ------- | ------- | ------------------------------------------------------ | | cur-toc-offset | Number | 0 | Scroll offset in pixels (useful for fixed headers) | | cur-toc-duration | Number | 400 | Scroll animation duration in milliseconds | | cur-toc-hideurlhash | Boolean | false | If true, prevents URL hash changes during navigation |

Advanced Usage

Multiple Content Blocks

You can have multiple content areas - the TOC will include H2s from all of them:

<div cur-toc-element="container">
  <!-- TOC structure -->
</div>

<div cur-toc-element="contents">
  <h2>Introduction</h2>
  <p>Intro content...</p>
</div>

<article cur-toc-element="contents">
  <h2>Main Content</h2>
  <p>Article content...</p>
</article>

<aside cur-toc-element="contents">
  <h2>Additional Info</h2>
  <p>Sidebar content...</p>
</aside>

Manual Initialization

For dynamic content or custom timing:

// Initialize specific container
const result = CurTOC.init(containerElement);

// Check if TOC was built
if (result.built) {
  console.log("TOC successfully created");
} else if (result.removed) {
  console.log("TOC removed (no headers found)");
}

Custom Header IDs

Headers can have pre-existing IDs, or the library will generate them:

<div cur-toc-element="contents">
  <!-- Will use existing ID -->
  <h2 id="custom-id">Section with Custom ID</h2>

  <!-- Will generate: "auto-generated-section" -->
  <h2>Auto Generated Section</h2>
</div>

API Reference

CurTOC.init(container)

Manually initialize a TOC container.

Parameters:

  • container (Element, optional): The container element. If not provided, searches for [cur-toc-element="container"]

Returns:

  • { built: true } - TOC successfully created
  • { built: false } - TOC creation failed
  • { built: false, removed: true } - Container removed (no headers found)

How It Works

  1. Scans Content: Finds all elements with cur-toc-element="contents"
  2. Extracts Headers: Collects all H2 elements from content blocks
  3. Generates IDs: Creates unique IDs for headers (if they don't have one)
  4. Builds Navigation: Clones the template link for each header
  5. Adds Interactivity: Sets up smooth scrolling click handlers
  6. Handles URLs: Manages browser history and hash navigation

Development

Build Process

# Install dependencies
npm install

# Build minified version
npm run build

The build process uses Terser to create the minified toc.js from src/toc.js.

Project Structure

curio-toc/
├── src/
│   └── toc.js          # Source code
├── toc.js              # Minified build output
├── package.json        # Project configuration
└── README.md           # This file

Browser Support

Works in all modern browsers that support:

  • querySelector / querySelectorAll
  • requestAnimationFrame
  • performance.now()
  • history.replaceState

License

This project is licensed under "none" - see package.json for details.

Links


Made with ❤️ by Curio