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

@booleanpress/nimbus

v0.2.1

Published

Reusable BooleanPress documentation layout and components for Astro and Nimbus.

Readme

@booleanpress/nimbus

A reusable Astro + Nimbus documentation shell. It supplies the header, search UI, sidebars, article layout, table of contents, feedback, footer, styles, and MDX components. The site supplies its own content, navigation tree, logos, and links. The visible components and styles began with the MIT-licensed Nimbus starter; see NOTICE and LICENSE.

Requirements

Use Node 22.14 or newer and install these directly in the consuming site's root package.json: @booleanpress/nimbus, @cloudflare/nimbus-docs 0.14.2, Astro 7, @iconify-json/ph, Tailwind 4, and @tailwindcss/vite. Nimbus discovers the Phosphor icon collection from the site's manifest; the package's peer dependency alone does not make the icons available to Nimbus. astro-og-canvas is a package dependency used by the reusable OG routes. Install @astrojs/mdx only if your content uses MDX, following Nimbus's setup for that content type.

Minimal site wiring

The examples/basic directory in this package is a complete starting site. Its nimbus.json records the reviewed Nimbus 0.14.2 upgrade baseline; keep that file and follow Nimbus's migration review when upgrading Nimbus. The key files are shown below.

Configure Nimbus and Tailwind in astro.config.mjs:

import nimbus, { defineConfig as defineNimbusConfig } from '@cloudflare/nimbus-docs';
import tailwindcss from '@tailwindcss/vite';
import { defineConfig } from 'astro/config';

const docs = defineNimbusConfig({
  site: 'https://docs.example.com',
  title: 'Example documentation',
  description: 'Guides for Example.',
  socialImage: '/og.png',
  socialImageAlt: 'Example documentation preview',
  sidebar: {
    items: [
      { label: 'Guides', autogenerate: { directory: 'guides' } },
      { label: 'Blog', autogenerate: { directory: 'blog' } },
    ],
  },
});

export default defineConfig({
  site: docs.site,
  trailingSlash: 'always',
  output: 'static',
  vite: { plugins: [tailwindcss()] },
  integrations: [nimbus(docs)],
});

Register the Nimbus docs collection in src/content.config.ts:

import { docsCollection } from '@cloudflare/nimbus-docs/content';
import { defineCollection } from 'astro:content';
import { seoSchemaFields } from '@booleanpress/nimbus/seo/schema';

export const collections = {
  docs: defineCollection(docsCollection({ schemaFields: seoSchemaFields })),
};

The package schema requires a non-empty description on each page and validates optional author, publication date, representative image, article type, and subject fields. Use seo.type: WebPage on an archive or profile page to avoid default article markup. It does not impose a character-count target.

Provide product branding in src/site.ts:

import type { BooleanPressSiteConfig } from '@booleanpress/nimbus/config';
import { booleansmtp } from '@booleanpress/brand';

export const siteConfig: BooleanPressSiteConfig = {
  productName: 'Example',
  seo: {
    publisher: {
      name: 'Example Docs',
      url: 'https://docs.example.com/',
      logo: { url: '/brand/publisher-mark.svg', width: 128, height: 128 },
    },
    about: { type: 'SoftwareApplication', name: 'Example' },
    ogCard: {
      bgGradient: [[24, 31, 54], [51, 38, 92]],
      border: { color: [115, 92, 220], width: 10, side: 'inline-start' },
      fonts: ['./public/brand/inter-bold.ttf'],
      logo: { path: './public/brand/publisher-mark.svg', size: [80] },
      format: 'PNG',
    },
  },
  navigationLabel: 'Documentation',
  brand: booleansmtp, // from '@booleanpress/brand': the product's logo, footer and colours
  headerLinks: [{ label: 'Get started', href: '/guides/' }],
};

Put the SEO publisher logo and any Open Graph font files in public/brand/; include the font's license when required. Use local fonts in ogCard.fonts so static image generation does not depend on a third-party font fetch. Navigation links honor Astro's base setting. The optional githubUrl and reportIssueUrl fields customize the remaining shell; chatLinks: false leaves "Ask GPT" and "Ask Claude" out of the page actions under each title ("Ask Agent" stays).

brand names the product the site belongs to, one object from @booleanpress/brand that every site of the product passes. It supplies the header logo (BrandHeader in its docs layout: the logo block as wide as the sidebar, then the search box, the section links and the buttons), the footer (BrandFooter, identical on every site of the product), and the accent colours (set as --bp-primary-* on <html>). Without it, the header shows productName as text and the footer is a single copyright line.

page sets the width of mode: custom pages and of the footer (with productHeader, of the whole page): { max: '81.25rem', gutter: '1.25rem' } gives a 1300px box with 20px gutters (defaults: 72rem, 1rem / 1.5rem from 64rem). page.sidebar sets the sidebar's width (default 18.75rem); measure the widest titles with every group open before narrowing it.

productHeader: true is for docs served on the product's own domain (booleansmtp.com/docs/): the product's header (ProductHeader from @booleanpress/brand, with brand.nav) comes first and scrolls away; the docs bar under it stays, with navigationLabel, the search box starting where the page's text does, and headerLinks, GitHub and the theme toggle on the right. Both bars, the docs columns and the footer sit in the page box, so nothing moves between the product's site and its docs. defaultMode: 'light' keeps pages light until a visitor picks dark (the default, system, follows the operating system); the choice is stored in localStorage["ui-mode"], which a site on the same domain can share.

seo.publisher is required. Supply the actual publisher name, its canonical home page, and a public square logo at least 112×112 px owned by the consuming site; optional sameAs values must be official profiles. Set the site name in Nimbus's title; seo.about and OG card colors, fonts, and logo are also site inputs. The package generates the card routes but does not invent brand or article content.

Register the MDX components in src/components.ts:

import { Aside, Card, CardGrid, LinkCard, Step, Steps, TabItem, Tabs } from '@booleanpress/nimbus/components';

export const components = { Aside, Card, CardGrid, LinkCard, Step, Steps, TabItem, Tabs };

Create src/pages/[...slug].astro using Nimbus route helpers and the package layout:

---
import DocsLayout from '@booleanpress/nimbus/layout';
import { components } from '../components';
import {
  getDocsStaticPaths, getDocsPage, getRouteFlags, getSidebar, getPrevNext,
  getBreadcrumbs, getEditUrl, getLastUpdated, getTOC, entryRouteKey, stripBase,
} from '@cloudflare/nimbus-docs/runtime';
import { siteConfig } from '../site';

export const prerender = true;
export const getStaticPaths = getDocsStaticPaths;

const page = await getDocsPage(Astro);
if (page instanceof Response) return page;
const { entry, Content, headings } = page;
const slug = stripBase(Astro.url.pathname, import.meta.env.BASE_URL).replace(/\/$/, '') || '/';
const { sidebar: sidebarOn, tableOfContents: tocOn } = await getRouteFlags(entry);
const sidebar = sidebarOn ? await getSidebar(slug, { collection: entry.collection }) : false;
const prevNext = await getPrevNext(slug, {
  sidebarTree: sidebar === false ? [] : sidebar,
  overrides: { prev: entry.data.prev, next: entry.data.next },
});
const breadcrumbs = await getBreadcrumbs(slug, { collection: entry.collection });
const editUrl = await getEditUrl(entry);
const lastUpdated = entry.data.lastUpdated ?? await getLastUpdated(entry);
const tocConfig = entry.data.tableOfContents;
const toc = tocOn && tocConfig !== false ? getTOC(headings, tocConfig) : false;
const routeKey = entryRouteKey(entry.id);
const markdownUrl = routeKey ? `/${routeKey}/index.md` : '/index.md';
const socialImage = entry.data.socialImage ?? `/og/${entry.id}.png`;
---
<DocsLayout
  brandConfig={siteConfig}
  title={entry.data.title}
  description={entry.data.description}
  sidebar={sidebar}
  headings={toc}
  breadcrumbs={breadcrumbs}
  prevNext={prevNext}
  mode={entry.data.mode}
  banner={entry.data.banner}
  head={entry.data.head}
  searchable={entry.data.searchable}
  noindex={entry.data.noindex}
  markdownUrl={markdownUrl}
  socialImage={socialImage}
  lastUpdated={lastUpdated}
  editUrl={editUrl}
  draft={entry.data.draft}
  seo={entry.data.seo}
  collection={entry.collection}
  entryId={entry.id}
>
  <Content components={components} />
</DocsLayout>

Add src/pages/search-index.json.ts so search works during astro dev:

export { prerender, GET } from '@booleanpress/nimbus/routes/search-index';

Register the package's agent endpoints too. examples/basic/src/pages/ contains these small route files; for example, src/pages/[...slug]/index.md.ts is:

export { prerender, getStaticPaths, GET } from '@booleanpress/nimbus/routes/markdown';

Its index.mdx.ts counterpart exports from /routes/source. The site-wide llms.txt.ts and llms-full.txt.ts export from /routes/llms and /routes/llms-full; [section]/llms.txt.ts exports from /routes/section-llms. These routes make Copy page, View as Markdown, and LLM index links usable in the consumer.

For a blog post, author and publication facts belong in frontmatter and should also be visible on the page:

seo:
  type: BlogPosting
  publishedAt: 2026-09-27
  authors:
    - type: Person
      name: Jane Doe
      url: https://docs.example.com/authors/jane-doe/
  images:
    - /blog/release-overview.jpg
  about:
    type: SoftwareApplication
    name: Example

The layout displays authors and publication date, then emits matching BlogPosting JSON-LD with the publisher, canonical page, update date, representative image URLs, and subject. TechArticle is the default for documentation pages. Use only accurate metadata that matches visible content; article image URLs should be representative and crawlable.

Nimbus emits the WebSite site-name signal on the homepage from the configured Nimbus title; keep it concise and consistent with the visible site name. The package emits the publisher Organization node once on the homepage and refers to it from article markup. Structured data can make a page eligible for a search feature but never guarantees display or ranking. Google recommends validating with the Rich Results Test; use the Schema Markup Validator for broader Schema.org checks and Search Console URL Inspection after deployment. Google currently limits FAQ rich results to select authoritative sites and removed How-to rich results, so this package does not emit either type.

Add a robots route and per-page OG image route:

// src/pages/robots.txt.ts
import { config } from 'virtual:nimbus/config';
import { createRobotsTxtResponse } from '@booleanpress/nimbus/routes/robots';

export const prerender = true;
export const GET = () => createRobotsTxtResponse({ siteUrl: config.site, baseUrl: import.meta.env.BASE_URL });
// src/pages/og/[...slug].ts
import { createOpenGraphImageRoutes } from '@booleanpress/nimbus/routes/open-graph';
import { siteConfig } from '../../site';

export const prerender = true;
export const { getStaticPaths, GET } = await createOpenGraphImageRoutes(siteConfig.seo.ogCard);

For /og.png, call createHomeOpenGraphImageResponse() with the Nimbus site title, description, and the same site-owned ogCard options. Nimbus supplies canonical URLs, titles, descriptions, Open Graph/Twitter tags, version alternates, sitemap integration, baseline WebPage data, and homepage WebSite site-name markup. This package adds publisher identity, TechArticle/BlogPosting, and breadcrumb JSON-LD. Run bp-docs-seo-check --site https://docs.example.com after building to check metadata, schema, social images, robots, and sitemap output.

For Cloudflare static hosting, add this to public/_headers so generated Markdown files have the correct media type:

/*.md
  Content-Type: text/markdown; charset=utf-8

Other hosts should set the Markdown content type through their own static-asset or route configuration.

Production search uses the Pagefind index Nimbus generates during the build. This endpoint includes page bodies only in development; the built JSON includes public titles and descriptions. Create at least src/content/docs/index.md with title and description frontmatter before building.

Customize the shell

@booleanpress/nimbus/components exports components for MDX and named Aside, Card, CardGrid, LinkCard, Steps, Step, Tabs, and TabItem. It also exports Render for reusable MDX partials. Register a partials collection with Nimbus and add src/content/partials/ before using Render; a site that does not use it needs no partials collection. The package exports /base-layout, /header, and /footer for custom routes such as 404 pages.

The layout loads styles/globals.css and styles/prose.css, including self-hosted Inter and JetBrains Mono. Its default primary colors follow BooleanSMTP. For another brand, define these custom properties in site CSS loaded on the page; the package resolves them at use time, independent of CSS import order:

:root {
  --bp-primary-light: oklch(0.47 0.18 240);
  --bp-primary-hover-light: oklch(0.41 0.18 240);
  --bp-ring-light: oklch(0.47 0.18 240 / 0.5);
  --bp-primary-dark: oklch(0.74 0.12 240);
  --bp-primary-hover-dark: oklch(0.8 0.12 240);
  --bp-ring-dark: oklch(0.74 0.12 240 / 0.6);
}

Other layout, surface, and typography values are --nb-* properties in styles/globals.css. Existing --sl-* aliases keep older Learn widgets styled during migration.

<Code> highlights with github-light / github-dark-default. Markdown code fences go through @cloudflare/nimbus-docs's own pipeline, whose default dark theme (github-dark) puts comments at 3.95:1 on the dark card — under WCAG AA. Set the same themes in the site's astro.config.mjs so fences match <Code> and pass; nimbus-docs keeps an explicitly set theme:

markdown: { shikiConfig: { themes: { light: 'github-light', dark: 'github-dark-default' }, defaultColor: false } },

The right table of contents uses Cloudflare's orange active rail by default. Override --bp-toc-active on :root if a consuming site needs a different navigation accent.

Guide feedback and Edit page / Report issue links render below the right table of contents, or below the article when the rail is hidden. Feedback saves a Yes/No vote in localStorage under booleanpress:docs:feedback:v1:<canonical-page-url>. The client code is isolated in components/ui/feedback/feedback.client.ts for a future API integration; no vote is sent to a server.