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

@jens4m/unbase-pages

v0.2.0

Published

Keeps draft pages out of a site's production build: an Astro integration and a Vite plugin, for Unbase.

Readme

@jens4m/unbase-pages

Keeps draft pages out of a site's production build. A page marked as a draft stays off the live site however often the rest is published, while previews and the dev server show it as it is.

It is a build step only: an Astro integration and a Vite plugin for React Router apps. Nothing it does reaches a visitor's browser, and it never calls a hosted service. Made for Unbase, which writes the list of drafts; it works the same without it.

npm install --save-exact @jens4m/unbase-pages

Astro

// astro.config.mjs
import { defineConfig } from "astro/config";
import sitemap from "@astrojs/sitemap";
import unbasePages from "@jens4m/unbase-pages/astro";

export default defineConfig({
  // Last, or at least after sitemap() and comment-modus: it cleans the page lists they write.
  integrations: [sitemap(), unbasePages()],
});

Vite + React Router

// vite.config.ts
import react from "@vitejs/plugin-react";
import { unbasePages } from "@jens4m/unbase-pages/vite";

export default { plugins: [react(), unbasePages()] };

Which pages are drafts

unbase.pages.json at the app's root lists them. Without the file, or without a draft in it, the build is untouched.

{ "pages": { "/pricing-2027": { "draft": true } } }

What a production build does with a draft

  • Its page is not built. Astro: the page file compiles to an empty page, so nothing it imports is bundled, and its HTML is removed. React Router: its <Route /> leaves the router and its module becomes empty, so the address falls to the app's own Not Found.
  • Its address leaves every page list: sitemaps, comment-modus's pages.json and content map, and the entries the page owns in Astro's content store.
  • The output is checked for its text. If a sentence only the draft has is still in a served file, the build stops.

Which builds are production

UNBASE_DEPLOY_CONTEXT (production, preview, development) when it is set; otherwise a dev server is development, and the host decides (VERCEL_ENV, Netlify's CONTEXT). Anything else counts as production, so a draft only shows where a host says it is a preview. NODE_ENV is never read: previews are production-optimised builds too.

Fails closed

A production build stops, with the page and the reason, when a draft cannot be kept out: a dynamic route, a page another file imports, content it cannot attribute to the page, an invalid unbase.pages.json, or a draft's text still in the output. Mark the page as ready, or fix the reason, and build again.

Removing it

Publish or delete the drafts first: without the package, a draft in unbase.pages.json is simply built. Then remove the package, its line in the config, and unbase.pages.json.

Exports

| | | |---|---| | @jens4m/unbase-pages/astro | The Astro integration (default export, and unbasePages) | | @jens4m/unbase-pages/vite | The Vite plugin (unbasePages) | | @jens4m/unbase-pages | The core: discovering a site's pages and checking a draft, as pure functions on the app's files |

Node 18.17 or newer. MIT licence.

Developing

The source lives in the Unbase repository, kit/pages/. core.mjs is the one implementation of page discovery and the draft check; Unbase's backend runs an exact copy (supabase/functions/_shared/pages-core.mjs, and a test fails when they differ). After changing it: cp kit/pages/core.mjs supabase/functions/_shared/pages-core.mjs.

  • node --test kit/pages/test/core.test.mjs (also in the repository's npm test).
  • A11, the acceptance test, on lab sites only: npm run test:a11 -- vibe (the Lovable-shaped fixture in test/fixtures/lab-vibe) and npm run test:a11 -- astro --dir <lab copy> (a git repository without a remote). It needs playwright-core (PLAYWRIGHT_CORE=<path>) and Chrome (CHROME_PATH).