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

v0.1.2

Published

Adds Unbase to an Astro site, checks it, and takes it out again: unbase init, unbase doctor, unbase uninstall.

Readme

@jens4m/unbase

Adds Unbase to an Astro site, checks it, and takes it out again.

npx @jens4m/unbase init      # the packages, their lines in astro.config, comment-modus.json
npx unbase doctor            # per feature: on, or what is missing, where, and how to fix it
npx unbase uninstall         # all of it out again; the built pages compared before and after

Unbase works on a connected site without any of this: the canvas, comments on the canvas, publishing, and visual editing (on Astro, nothing installed). What has to live in the site's own code is what this adds: comments on the live site (?comment), and page management (draft pages kept off Live, page and site settings). The packages change how the site is edited and built, never how it renders, and nothing here calls Unbase.

Astro only, for now. Node 18.17 or newer for the CLI (comment-modus itself needs 22.12).

For a coding agent

Add Unbase to this site.

1. Run `npx @jens4m/unbase init --yes` and keep its changes.
2. Read node_modules/@jens4m/unbase/AGENTS.md and do the steps it leaves to you.
3. Don't move or rewrite the site's content. Unbase edits text where it is written.
4. Run `npx unbase doctor` until it passes. Commit on a new branch and push it.

AGENTS.md is in the package, so the steps are pinned by the site's lockfile.

unbase init

| Flag | | |---|---| | --comments / --no-comments | Comments on the live site, with ?comment (@jens4m/comment-modus). Default: in | | --project <id or slug> | Link comment mode to an Unbase project now (see Linking) | | --pointer[=AGENTS.md\|CLAUDE.md] / --no-pointer | One line in the site's AGENTS.md (or CLAUDE.md) pointing its agent at this package's AGENTS.md. Default: no | | --no-install | Write package.json only; install yourself | | --tarballs <dir> | Install the packages from npm pack tarballs in <dir>, for testing a release before it is on npm | | --yes | The default for every choice not given | | --json, --dir <path> | Output for programs; the site's folder (default: here) |

It adds, with the site's own package manager (npm, pnpm or yarn, from its lockfile), at these versions:

| Package | Version | | |---|---|---| | @jens4m/unbase-pages | 0.2.0 | Keeps draft pages out of production builds | | @jens4m/comment-modus | 1.8.1 | Comments on the live site; writes the content schemas Unbase reads | | @jens4m/unbase | this one | devDependency: AGENTS.md and doctor, pinned |

In astro.config, found and changed through its syntax tree, never by text substitution:

import commentModus from "@jens4m/comment-modus";
import commentModusConfig from "./comment-modus.json";
import unbasePages from "@jens4m/unbase-pages/astro";
// …
integrations: [
  // …the site's own
  commentModusConfig.project
    ? commentModus({ project: commentModusConfig.project, layerUrl: "https://layer.unbase.app/v1/loader.js", edit: true })
    : null,
  unbasePages(),
],

A config it cannot change with certainty (CommonJS, no export default, integrations that is not an array literal, a spread that may hold it) stops the run with the file named and nothing changed. A package that is already there at an older version is moved up to the pinned one, so running init again is also how a site updates; a newer one is kept and reported, never moved down. A second run changes nothing. It touches no content.

Linking

comment mode needs the site's Unbase project, which a site added before Unbase knows it does not have yet. So init writes comment-modus.json with "project": null, and the config only turns comment mode on once that file names the project: until then the site builds and renders as before. Unbase fills the value in when the site is connected (one JSON value, never a change to the config), or init --project <id> does. comment-modus.json is the same file comment-modus's own CLI reads.

A config that sets up commentModus() itself, with its own project (a site that had comment mode before init existed), keeps it: init --project with that same project changes nothing there and writes no comment-modus.json; another project is refused, to be changed in the config by a person.

unbase doctor

Builds the site once (production, into a folder of its own), then reads it with Unbase's own readers, the code the Edge Functions run, bundled into this package. Per feature it gives a state and per check what is missing, the file, and the AGENTS.md step that fixes it.

| Check state | | |---|---| | ok | Works | | missing | The site has to change. Fails the run | | waiting | Outside this repository: Unbase linking the project, or a package release. Named, does not fail the run | | info | Worth knowing | | skipped | Not checked (--no-build, or a build that failed) |

Features: Visual editing (Astro, the site builds), Comments on the site (the package, its line, the link, the markers, the loader), Page management (the kit, the drafts in unbase.pages.json, the kit running in a production build, the content schemas, the route files and the site settings and that the layout reads them). --no-build skips the build and what needs it.

The markers are comment mode's data-c: a pin on the live site takes its title and source file from them, so with comments they belong in the production build. A site without comment mode, or whose commentModus() says componentMarker: "preview" (comment-modus 1.9.0: markers in the dev server and previews only) or false, must have none there; doctor fails when it does, and names an older comment-modus that ignores "preview".

unbase uninstall

Refuses while unbase.pages.json holds a draft, and lists them: without the kit a draft is built and goes live, so each is published or deleted in Unbase first. Then it builds the site, removes the packages, their lines in astro.config, comment-modus.json, unbase.pages.json, src/content/.schemas/ and the pointer line, builds again, and compares every page's HTML. Taken out first: comment mode's markers and loader, and what differs between any two builds (asset hashes, Astro's ids, white space, attribute order). When pages still differ it builds the after state once more, and what differs between those two builds (an id a component makes at random on every render) is noise, not a change. "No differences in the built pages" is the pass. --yes without a terminal; --no-build skips the comparison; --no-install writes package.json only.

The route files, the settings file and the layout's reads stay: they are the site's own code.

For programs

  • Never asks without a terminal. A choice without its flag is an error (exit 2) naming the flags; --json never asks.
  • --json on every command. init: packages (name, the pinned version, dev, and action: added, updated with from and to, or kept, with a note when the one there is newer) and files (file, created, changed or removed, and the changes; the lockfile too when the package manager ran). doctor: features, each with state (on, off, waiting, not-installed) and checks (id, state, message, and for a missing or waiting check missing, file, step). uninstall: files (every file it touched, the lockfile included), packages, comparison (pages, differences, secondBuild), or refused: "drafts" with drafts. An error: { ok: false, exitCode: 2, error: { code, message, file? } }.
  • Exit codes: 0 passed, 1 failed (doctor found something missing; uninstall refused or found a difference), 2 could not run (usage, no Astro site, a config it cannot edit safely, an install that failed).
  • No login, no project, no network beyond the package manager's install: it never calls Unbase, and the versions are pinned.

Developing

In the Unbase repository, kit/cli/. lib/readers.mjs is generated from the Edge Functions' readers (detect.ts, settings.ts, pages.ts, the kit's core): after changing one of them, node kit/cli/scripts/readers.mjs; npm test fails while it is out of date. Tests: node --test kit/cli/test/*.test.mjs (in the repository's npm test).

MIT licence.