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

@hillnote/publish

v2.4.2

Published

Transform your Hillnote workspace into a beautiful documentation or Blog with Next.js. Usage: npx @hillnote/publish init

Downloads

275

Readme

@hillnote/publish

Transform your Hillnote workspace into a beautiful, SEO-optimized documentation website with Next.js and modern UI components.

🚀 Overview

@hillnote/publish is a complete documentation generation system that converts your Hillnote markdown workspace into a production-ready Next.js website. Simply run one command to set up the entire documentation system in your Next.js project.

✨ Features

  • 📚 Beautiful documentation UI with hierarchical navigation sidebar
  • 🎨 Dark/Light theme support with next-themes
  • 📱 Fully responsive design
  • 🔍 Built-in search functionality across all documents
  • 🤖 AI-crawler optimized with llms.txt and structured data
  • 📄 Automatic sitemap.xml and robots.txt generation
  • 📁 Auto-expanding navigation for active documents
  • 🔗 Smart URL routing with SEO-friendly slugs
  • 📝 Advanced markdown rendering with syntax highlighting
  • 🏷️ Support for document metadata, related documents, and author's notes
  • ⚡ Static page generation for optimal performance
  • 🛠️ Simple CLI setup - one command to install everything

🎯 Quick Start (Recommended)

Install in Your Next.js Project

# Navigate to your Next.js project
cd your-nextjs-project

# Run the initialization command
npx @hillnote/publish init

# Or if using src/app structure
npx @hillnote/publish init --src

That's it! The CLI will automatically:

  • ✓ Copy the hillnoteDoc system to your project
  • ✓ Set up API routes for search and document fetching
  • ✓ Add the page generation script
  • ✓ Update your package.json with necessary scripts
  • ✓ Configure everything based on your project structure

Next Steps

  1. Add your Hillnote workspace:

    cp -r "/path/to/Welcome to Hillnote!" public/
  2. Configure your site: Edit hillnoteDoc/config/site.config.js (or src/hillnoteDoc/config/site.config.js)

  3. Generate pages:

    npm run generate-pages
  4. Start your dev server:

    npm run dev

Your documentation site will be live at http://localhost:3000/doc

📦 What Gets Installed

When you run npx @hillnote/publish init, the following structure is added to your project:

your-project/
├── hillnoteDoc/              # Documentation system (or src/hillnoteDoc/)
│   ├── components/          # UI components
│   ├── config/             # Configuration
│   ├── lib/                # Utilities
│   └── styles/             # Styles
├── app/api/                # API routes (or src/app/api/)
│   ├── ai-sitemap/
│   ├── docs/
│   └── search/
└── scripts/
    └── generate-pages.mjs  # Page generation script

🔧 Installation & Setup

Prerequisites

  • Node.js 18+
  • Next.js 15+ project (with App Router)
  • A Hillnote workspace exported with markdown files

Step 1: Initialize

npx @hillnote/publish init

Step 2: Add Your Workspace

Copy your Hillnote workspace folder to public/:

cp -r "/path/to/Welcome to Hillnote!" public/

Step 3: Configure

Edit hillnoteDoc/config/site.config.js:

  • Set your site name and description
  • Update the workspace path to match your folder name
  • Customize routing, SEO, and UI settings

Step 4: Generate & Run

npm run generate-pages
npm run dev

📦 Alternative: Manual Setup (For Advanced Users)

If you prefer not to use the CLI or want more control:

Option 1: Use the NextJS Boilerplate

  1. Copy the boilerplate to your project location:

    cp -r "NextJS Boilerplate" /path/to/your-project-name
    cd /path/to/your-project-name
  2. Install dependencies:

    npm install
  3. Add your Hillnote workspace:

    # Copy your exported Hillnote workspace to the public folder
    cp -r "/path/to/Welcome to Hillnote!" public/
  4. Configure your site: Edit hillnoteDoc/config/site.config.js with your site details (see Configuration section below)

  5. Generate pages and start:

    npm run generate-pages
    npm run dev

    Your site will be live at http://localhost:3000

Option 2: Add to Existing Next.js Project

  1. Copy the hillnoteDoc folder to your project root:

    cp -r hillnoteDoc /path/to/your-nextjs-project/
  2. Copy the necessary files:

    # Copy API routes
    cp -r "hillnoteDoc/-- TO BE MOVED --/api/"* your-project/app/api/
    # OR if using src folder:
    cp -r "hillnoteDoc/-- TO BE MOVED --/api/"* your-project/src/app/api/
    
    # Copy the generation script
    cp "hillnoteDoc/-- TO BE MOVED --/scripts/generate-pages-app.mjs" your-project/scripts/generate-pages.mjs
    # OR if using src folder:
    cp "hillnoteDoc/-- TO BE MOVED --/scripts/generate-pages-src.mjs" your-project/scripts/generate-pages.mjs
  3. Install required dependencies:

    npm install @radix-ui/react-accordion @radix-ui/react-checkbox @radix-ui/react-dialog \
      @radix-ui/react-scroll-area @radix-ui/react-separator @radix-ui/react-slot \
      @radix-ui/react-tabs class-variance-authority clsx gray-matter lucide-react \
      marked marked-gfm-heading-id next-themes tailwind-merge
  4. Add the generation script to package.json:

    {
      "scripts": {
        "generate-pages": "node scripts/generate-pages.mjs",
        "prebuild": "node scripts/generate-pages.mjs"
      }
    }
  5. Copy your Hillnote workspace to public folder and configure site.config.js

⚙️ Configuration

Edit hillnoteDoc/config/site.config.js:

export const siteConfig = {
  // Basic site information
  siteName: "Your Documentation Site",
  siteDescription: "Your site description",
  siteUrl: "https://your-domain.com",

  // Project Structure
  projectStructure: {
    useSrcFolder: false, // true if using src/app, false if using app/
  },

  // SEO Configuration
  seo: {
    titleTemplate: "%s | Your Site",
    defaultTitle: "Your Documentation",
    defaultDescription: "Default meta description",
    keywords: "your, keywords, here",
    author: "Your Name",
    publisher: "Your Organization",
    llmsIntro: "Introduction for AI crawlers",
    allowAIBots: true,
    crawlDelay: null,
  },

  // Routing Configuration
  routing: {
    docBase: "doc", // Base path for docs (e.g., /doc, /docs, /wiki)
    trailingSlash: false,
  },

  // Workspace Configuration
  workspace: {
    path: "/Welcome to Hillnote! /", // Your workspace folder name in public/
    enabled: true,
    documentsFolder: "documents",
    registryFile: "documents-registry.json",
    initialFile: "documents/Start Here .md",
  },

  // UI Configuration
  ui: {
    navigationMode: "wiki", // "emoji" or "wiki"
    showHeaders: true,
    authorsNotes: {
      enabled: true,
      title: "Author's Notes",
    },
    relatedDocuments: {
      enabled: true,
      title: "Related Documents",
    }
  }
}

📁 Project Structure

your-project/
├── app/ (or src/app/)          # Next.js app directory
│   ├── api/                    # API routes
│   │   ├── ai-sitemap/         # AI-readable sitemap
│   │   ├── docs/               # Document fetch API
│   │   └── search/             # Search API
│   └── doc/                    # Generated static pages (auto-generated)
├── hillnoteDoc/                # Documentation system
│   ├── components/             # UI components
│   │   ├── ask-ai-dialog.jsx
│   │   ├── navigation-sidebar.jsx
│   │   ├── search-dialog.jsx
│   │   ├── table-of-contents.jsx
│   │   ├── theme-provider.jsx
│   │   └── theme-toggle.jsx
│   ├── config/
│   │   └── site.config.js      # Main configuration file
│   ├── lib/                    # Utility functions
│   │   ├── debounce.js
│   │   ├── documents-server.js
│   │   ├── slug-utils.js
│   │   ├── static-routes.js
│   │   └── workspace.js
│   ├── styles/
│   │   └── markdown.css        # Markdown styling
│   └── -- TO BE MOVED --/      # Files to copy to your project
│       ├── api/                # API routes templates
│       └── scripts/            # Generation scripts
├── components/
│   └── ui/                     # Shadcn UI components
├── public/
│   ├── Welcome to Hillnote!/   # Your Hillnote workspace
│   ├── robots.txt              # Auto-generated
│   ├── sitemap.xml             # Auto-generated
│   └── llms.txt                # Auto-generated
├── scripts/
│   └── generate-pages.mjs      # Page generation script
└── package.json

🔧 Components

Navigation Components

NavigationSidebar

Hierarchical sidebar with collapsible sections.

import { NavigationSidebar } from '@/hillnoteDoc/components/navigation-sidebar'

<NavigationSidebar />

TableOfContents

Automatically generated from document headings.

import { TableOfContents } from '@/hillnoteDoc/components/table-of-contents'

<TableOfContents />

Interactive Components

SearchDialog

Full-text search across all documents.

import { SearchDialog } from '@/hillnoteDoc/components/search-dialog'

<SearchDialog />

AskAIDialog

AI-powered question answering (requires API integration).

import { AskAIDialog } from '@/hillnoteDoc/components/ask-ai-dialog'

<AskAIDialog />

ThemeToggle

Dark/light theme switcher.

import { ThemeToggle } from '@/hillnoteDoc/components/theme-toggle'

<ThemeToggle />

🛠️ Utilities

Workspace Functions

import {
  getWorkspaceFileTree,
  buildFileTree,
  fetchWorkspaceRegistry
} from '@/hillnoteDoc/lib/workspace'

Document Functions

import {
  getDocumentRegistry,
  getDocumentByPath,
  findDocumentBySlug
} from '@/hillnoteDoc/lib/documents-server'

Slug Utilities

import {
  pathToSlug,
  documentPathToStaticUrl
} from '@/hillnoteDoc/lib/slug-utils'

📝 Page Generation

The generate-pages.mjs script automatically:

  1. Scans your Hillnote workspace for markdown files
  2. Generates static Next.js pages in app/doc/ (or src/app/doc/)
  3. Creates SEO files:
    • public/sitemap.xml - XML sitemap for search engines
    • public/robots.txt - Robot crawling rules
    • public/llms.txt - AI-readable content index
    • public/llms-txt.txt - Extended AI crawler content

Running Generation

# Manual generation
npm run generate-pages

# Automatic on build (configured in package.json prebuild)
npm run build

Command Line Options

node scripts/generate-pages.mjs [options]

Options:
  --no-sitemap     Do not generate sitemap.xml
  --no-robots      Do not generate robots.txt
  --no-llms        Do not generate llms.txt and llms-txt.txt files
  -h, --help       Show help message

Note: doc/page.* and doc/layout.* files are always preserved if they exist, allowing you to customize the root documentation page and layout without them being overwritten.

Examples

# Generate everything (default)
npm run generate-pages

# Skip sitemap and robots.txt generation
node scripts/generate-pages.mjs --no-sitemap --no-robots

# Only generate document pages (no SEO files)
node scripts/generate-pages.mjs --no-sitemap --no-robots --no-llms

📰 Blog Support

@hillnote/publish includes a full-featured blog system that integrates seamlessly with your documentation site.

Setting Up the Blog

# Initialize the blog system in your project
node scripts/generate-blog.mjs --setup

This creates the following structure:

your-project/
├── public/
│   └── blog/
│       ├── draft/              # Draft posts (not published)
│       ├── published/          # Published posts (live on site)
│       └── resources/          # Images and assets
│           └── images/
├── app/ (or src/app/)
│   ├── api/
│   │   └── blog/
│   │       └── route.js        # Blog API endpoint
│   └── blog/
│       ├── page.jsx            # Blog listing page
│       └── [slug]/
│           └── page.jsx        # Individual blog post page
└── hillnoteDoc/
    └── components/
        └── blog/               # Blog UI components

Blog Workflow: Draft → Published

  1. Create a draft: Write your blog post in public/blog/draft/my-post.md

  2. Add YAML frontmatter at the top of your markdown file:

    ---
    title: "Your Blog Post Title"
    author: "Your Name"
    publishDate: "2025-01-15"
    description: "A brief description for SEO and previews"
    coverImage: "my-cover-image.jpg"  # or full URL
    tags:
      - Tutorial
      - Feature
    ---
    
    Your blog content starts here...
  3. Publish the post: Move the file to public/blog/published/

    mv public/blog/draft/my-post.md public/blog/published/
  4. Generate the blog:

    node scripts/generate-blog.mjs --publish

Blog Commands

# Initial setup - creates blog folder structure and components
node scripts/generate-blog.mjs --setup

# Publish - generates blog pages and updates registry
node scripts/generate-blog.mjs --publish

# Update - regenerates pages after editing posts
# Note: Does NOT update sitemap.xml - run --publish for full regeneration
node scripts/generate-blog.mjs --update

# Help - show all available options
node scripts/generate-blog.mjs --help

Adding Images to Blog Posts

For images in your blog posts:

  1. Place images in public/blog/resources/images/

  2. Reference in frontmatter (for cover images):

    coverImage: "my-image.jpg"  # Resolves to /blog/resources/images/my-image.jpg

    Or use a full URL:

    coverImage: "https://example.com/image.jpg"
  3. Reference in content (for inline images):

    ![Alt text](/blog/resources/images/my-image.jpg)

Blog Templates

Three pre-built blog templates are available:

  • featured-grid - Hero post with grid layout
  • minimal-list - Clean, simple list view
  • magazine - Publication-style layout

Specify the template during setup or edit the generated page.

Blog Components

BlogSection - Embeddable Homepage Component

Display recent blog posts on your homepage or landing pages:

import { BlogSection } from '@/hillnoteDoc/components/blog'

// Basic usage - shows 3 posts
<BlogSection />

// Customized
<BlogSection
  limit={6}
  title="Latest Articles"
  description="News and updates from our team"
  showViewAll={true}
  className="bg-muted/50"
/>

Props:

  • limit (number, default: 3) - Number of posts to display
  • title (string) - Section heading
  • description (string) - Subheading text
  • showViewAll (boolean, default: true) - Show "View all posts" link
  • className (string) - Additional CSS classes

Other Blog Components

import {
  BlogHeader,      // Post header with title, author, date
  BlogFooter,      // Post footer with tags and sharing
  BlogCoverImage,  // Responsive cover image
  BlogContent,     // Markdown content renderer
  RelatedArticles, // Related posts section
  BlogArticle,     // Full article wrapper
  BackToBlog       // Navigation back to blog list
} from '@/hillnoteDoc/components/blog'

Blog API

The blog API is available at /api/blog:

// Get all posts
fetch('/api/blog')
  .then(res => res.json())
  .then(data => console.log(data.posts))

// Get single post by slug
fetch('/api/blog?slug=my-post-title')
  .then(res => res.json())
  .then(data => console.log(data.post))

Blog Registry

For performance, the blog system generates a blog-registry.json file containing metadata for all posts. This is automatically updated when you run --publish or --update.

🎨 Customization

Styling

The package uses Tailwind CSS. Customize by:

  1. Edit Tailwind config in tailwind.config.js
  2. Modify markdown styles in hillnoteDoc/styles/markdown.css
  3. Customize component styles directly in component files

Navigation Modes

  • wiki mode: Clean accordion-style navigation
  • emoji mode: Shows emoji icons from document titles

Set in site.config.js:

ui: {
  navigationMode: "wiki" // or "emoji"
}

URL Customization

Change the base documentation path:

routing: {
  docBase: "docs" // Changes /doc/* to /docs/*
}

🚢 Deployment

Vercel (Recommended)

  1. Push your code to GitHub
  2. Import project in Vercel
  3. Vercel automatically detects Next.js and configures build
  4. Deploy!

Other Platforms

  • Netlify: Supports Next.js with adapter
  • AWS Amplify: Full Next.js support
  • Self-hosted: npm run build && npm start

Pre-deployment Checklist

  • [ ] Update siteUrl in site.config.js
  • [ ] Run npm run generate-pages
  • [ ] Test build locally with npm run build
  • [ ] Verify all images and assets are in public/

🔍 SEO Features

  • Automatic sitemap generation - Search engines discover all pages
  • Structured metadata - Rich snippets in search results
  • Open Graph tags - Beautiful social media previews
  • AI crawler optimization - llms.txt for AI search engines
  • Semantic HTML - Proper heading hierarchy
  • Fast page loads - Static generation for optimal performance

📋 Requirements

Dependencies

{
  "@radix-ui/react-accordion": "^1.2.12",
  "@radix-ui/react-checkbox": "^1.1.3",
  "@radix-ui/react-dialog": "^1.1.4",
  "@radix-ui/react-scroll-area": "^1.2.2",
  "@radix-ui/react-separator": "^1.1.0",
  "@radix-ui/react-slot": "^1.1.1",
  "@radix-ui/react-tabs": "^1.1.2",
  "class-variance-authority": "^0.7.1",
  "clsx": "^2.1.1",
  "gray-matter": "^4.0.3",
  "lucide-react": "^0.468.0",
  "marked": "^16.1.0",
  "marked-gfm-heading-id": "^5.1.0",
  "next": "^15.5.2",
  "next-themes": "^0.5.1",
  "react": "^19.0.0",
  "react-dom": "^19.0.0",
  "tailwind-merge": "^2.6.0"
}

System Requirements

  • Node.js 18+
  • Next.js 15+
  • A Hillnote workspace exported with:
    • documents/ folder with markdown files
    • documents-registry.json metadata file
    • Optional: resources/ folder for images

🐛 Troubleshooting

Pages not generating?

  • Verify workspace folder is in public/
  • Check documents-registry.json exists
  • Ensure workspace.path in config matches folder name

Import errors?

  • All imports should use @/hillnoteDoc alias
  • Check jsconfig.json or tsconfig.json has correct paths

Styling issues?

  • Clear .next cache: rm -rf .next
  • Rebuild: npm run dev

API routes not working?

  • Ensure API files are in app/api/ (or src/app/api/)
  • Check Next.js console for errors
  • Verify projectStructure.useSrcFolder setting

📄 License

MIT License - Free to use, modify, and distribute.

🤝 Support

  • Issues: Report bugs or request features in your repository
  • Documentation: Check the example site in NextJS Boilerplate
  • Community: Join the Hillnote community

Built with ❤️ for the Hillnote ecosystem using Next.js, Tailwind CSS, and Radix UI