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

@supatent/supatent-docs

v0.6.0

Published

Static-first docs framework for Next.js using Supatent content.

Readme

@supatent/supatent-docs

Static-first docs framework for Next.js using Supatent content.

Install

npm i @supatent/supatent-docs

Minimal setup

// docs.config.ts
import { defineDocsConfig } from "@supatent/supatent-docs";

export const docsConfig = defineDocsConfig({
  supatent: {
    baseUrl: process.env.SUPATENT_BASE_URL || "https://app.supatent.ai",
    projectSlug: process.env.SUPATENT_PROJECT_SLUG!,
  },
  schemas: {
    settings: process.env.DOCS_SCHEMA_SETTINGS!,
    page: process.env.DOCS_SCHEMA_PAGE!,
    category: process.env.DOCS_SCHEMA_CATEGORY!,
  },
  routing: {
    basePath: process.env.DOCS_BASE_PATH || "/docs",
    defaultLocale: process.env.DOCS_DEFAULT_LOCALE || "en-US",
    locales: (process.env.DOCS_LOCALES || "en-US").split(",").map((x) => x.trim()),
  },
});
// app/layout.tsx
import "@supatent/supatent-docs/styles.css";

export { docsMetadata as metadata } from "@supatent/supatent-docs/next";
export { DocsRootLayout as default } from "@supatent/supatent-docs/next";
// app/page.tsx
export { DocsHomePage as default } from "@supatent/supatent-docs/next";
// app/[locale]/docs-internal/[[...slug]]/page.tsx
export {
  DocsInternalPage as default,
  generateDocsPageStaticParams as generateStaticParams,
} from "@supatent/supatent-docs/next";

export const dynamicParams = false;

To opt into request-time rendering instead:

import { DocsInternalPageDynamic } from "@supatent/supatent-docs/next";

export const dynamic = "force-dynamic";
export default DocsInternalPageDynamic;

The docs entry URL is /docs (or your configured DOCS_BASE_PATH). It redirects to the resolved locale route.

// next.config.ts
import type { NextConfig } from "next";
import { withSupatentDocs } from "@supatent/supatent-docs/next-config";

const nextConfig: NextConfig = {};
export default withSupatentDocs(nextConfig);

next build generates:

  • public/.supatent-docs/search/* search index assets
  • public/.supatent-docs/ai/{locale}/{index|all}.json static AI outputs

By default, /docs/{locale}/ai/{index|all} is served from static AI artifacts. To force dynamic AI handlers instead:

export default withSupatentDocs(nextConfig, {
  ai: { mode: "dynamic" },
});

The navbar brand/logo link target is read from the docs settings singleton. Add a brand-href text field to your docs-settings schema and set it in content when the brand should link somewhere like /. If that setting is missing, the brand falls back to the locale docs home such as /docs/en-US.

Bundler compatibility

  • Public runtime entrypoints (@supatent/supatent-docs/next, @supatent/supatent-docs/next-config) resolve to built ESM in dist/*.
  • This avoids Turbopack module-type failures that can occur when dependency subpaths point to raw TypeScript files.

Required Supatent schemas

DOCS_SCHEMA_SETTINGS, DOCS_SCHEMA_CATEGORY, and DOCS_SCHEMA_PAGE must point to schemas that include the fields below.

Recommended schema slugs:

  • docs-settings (isSingleton: true)
  • docs-category (isSingleton: false)
  • docs-page (isSingleton: false)

Settings schema fields:

| Field slug | Required | Type | Interface | Purpose | |---|---|---|---|---| | site-title | Yes | text | textInput | Navbar/site title | | logo | No | image | singleImage | Navbar logo (left of title) | | brand-href | No | text | textInput | Navbar brand/logo click target |

Category schema fields:

| Field slug | Required | Type | Interface | Purpose | |---|---|---|---|---| | title | Yes | text | textInput | Category label in nav | | order | Yes | number | numberInput | Category sort order |

Page schema fields:

| Field slug | Required | Type | Interface | Purpose | |---|---|---|---|---| | title | Yes | text | textInput | Page title | | body | Yes | markdown | markdownEditor | Page content | | category | Yes | text | textInput | Category content slug reference | | order | Yes | number | numberInput | Page sort order inside category |

Minimal schema examples:

{
  "slug": "docs-settings",
  "name": "Docs Settings",
  "isSingleton": true,
  "fields": [
    { "slug": "site-title", "name": "Site Title", "type": "text", "interface": "textInput", "order": 0 },
    { "slug": "logo", "name": "Logo", "type": "image", "interface": "singleImage", "order": 1 },
    { "slug": "brand-href", "name": "Brand Href", "type": "text", "interface": "textInput", "order": 2 }
  ]
}
{
  "slug": "docs-category",
  "name": "Docs Category",
  "isSingleton": false,
  "fields": [
    { "slug": "title", "name": "Title", "type": "text", "interface": "textInput", "order": 0 },
    { "slug": "order", "name": "Order", "type": "number", "interface": "numberInput", "order": 1 }
  ]
}
{
  "slug": "docs-page",
  "name": "Docs Page",
  "isSingleton": false,
  "fields": [
    { "slug": "title", "name": "Title", "type": "text", "interface": "textInput", "order": 0 },
    { "slug": "body", "name": "Body", "type": "markdown", "interface": "markdownEditor", "order": 1 },
    { "slug": "category", "name": "Category", "type": "text", "interface": "textInput", "order": 2 },
    { "slug": "order", "name": "Order", "type": "number", "interface": "numberInput", "order": 3 }
  ]
}
// proxy.ts
import { docsProxy } from "@supatent/supatent-docs/next";

export const proxy = docsProxy;
export const config = {
  matcher: ["/((?!_next|api|favicon.ico|robots.txt|sitemap.xml).*)"],
};

For the full integration guide and examples, see: