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

@verevoir/admin

v0.5.1

Published

Composable building blocks for a Verevoir-powered admin site — shell, editor, list, with first-class slots for versioning, preview, and user management.

Readme

@verevoir/admin

Composable admin-UI building blocks. Mounts on top of @verevoir/storage and @verevoir/editor to give you a working content admin — shell, sidebar, document list, document editor, sections editor, tag scheduler — with zero opinion about routing, auth, or deployment target.

npm install @verevoir/admin @verevoir/editor @verevoir/schema @verevoir/storage

What's in the box

Layout and shell

  • AdminLayout — persistent React tree that wraps every admin page. Owns the sidebar, context providers, and a slot for page content. Lets consumers compose SPA-style navigation with the sidebar mounted once.
  • AdminShell — chrome (header, breadcrumbs, identity display, body container). Used by AdminLayout or directly if you want a simpler shell.
  • AdminSidebar — categorised navigation of block types, with an inline filter, collapse state persisted via preferences context, and singleton vs collection handling.

Context

  • AdminProvider — shares groups, base path, current path, and filter text across every admin component below it.
  • AdminPreferencesProvider — persists per-user admin preferences (sidebar collapsed, expanded type IDs) via localStorage.
  • useAdminGroups, useAdminBasePath, useAdminCurrentPath, useAdminFilter, useFilteredGroups, useSidebarOpen, useExpandedTypes — typed hooks for everything the providers expose.

Document UI

  • DocumentList — filtered, grouped listing of documents per block type with edit links.
  • DocumentEditor — the full editor: metadata form (via @verevoir/editor's BlockEditor), polymorphic sections, optional live preview iframe, save flow, auto-save for structural changes.
  • SectionsEditor — polymorphic page-section editor with drag-and-drop reordering and stacked move-up / move-down controls.

Tag scheduling

  • TagList — listing of every tag in use across the registered block types with counts.
  • TagScheduler — bulk-edit form: set publishFrom / publishTo across every doc carrying a tag. Denied docs (where canEdit returns false) are shown greyed out with a lock indicator.

Save handler

  • createSaveHandler — framework-agnostic function. Validates the request, merges with the existing document, writes through your StorageAdapter.
  • createAstroSaveRoute (@verevoir/admin/astro) — thin Astro wrapper around the save handler.

Server helpers (@verevoir/admin/server)

  • loadAdminGroups({ storage, blocks }) — serialisable view model for the sidebar: one group per block type with its docs. Pass the result into AdminLayout's groups prop.
  • loadTagsSummary({ storage, blocks }) — every tag in use across registered block types with counts + which types it spans.
  • loadTagDetail({ storage, blocks, tag }) — every doc carrying the given tag, with title + publish window.

Import only what you need; the server subpath stays out of the client bundle.

Quick start (Astro)

---
// src/pages/admin.astro
import { loadAdminGroups } from '@verevoir/admin/server';
import '@verevoir/admin/styles/admin.css';
import { storage } from '@/storage';
import { blocks } from '@/schema/registry';
import { AdminHomeIsland } from '@/admin/AdminHomeIsland';

export const prerender = false;
const groups = await loadAdminGroups({ storage, blocks });
---

<html lang="en">
  <body>
    <AdminHomeIsland client:only="react" groups={groups} basePath="/admin" currentPath={Astro.url.pathname} />
  </body>
</html>
// src/admin/AdminHomeIsland.tsx
import { AdminLayout, DocumentList } from '@verevoir/admin';
import type { AdminGroup } from '@verevoir/admin';

export function AdminHomeIsland({ groups, basePath, currentPath }) {
  return (
    <AdminLayout
      groups={groups}
      basePath={basePath}
      currentPath={currentPath}
      shell={{ title: 'My Admin' }}
    >
      <DocumentList />
    </AdminLayout>
  );
}
// src/pages/api/admin/save.ts
import { createAstroSaveRoute } from '@verevoir/admin/astro';
import { storage } from '@/storage';
import { blocks } from '@/schema/registry';

export const prerender = false;
export const POST = createAstroSaveRoute({ storage, blocks });

A full working consumer: Verevoir starter.

Block registry

AdminLayout expects a registry of block types in a specific shape:

import type { BlockRegistry } from '@verevoir/admin';

export const blocks: BlockRegistry = {
  page: {
    block: pageBlockDefinition,
    label: 'Pages',
    category: 'Content',
    preview: (data) => `/${data.slug ?? ''}`,
  },
  siteConfig: {
    block: siteConfigBlockDefinition,
    label: 'Site config',
    category: 'Configuration',
    singleton: true,
  },
};

category groups block types in the sidebar (preserves order-of-first-appearance). preview returns a public URL; when set, the editor shows a side-by-side preview iframe. singleton: true for single-instance block types like site config.

Theming

Fully themable via CSS custom properties. Override any of these on :root or the .verevoir-admin selector:

| Variable | Default | What it controls | | ----------------------- | ------------------------ | -------------------- | | --admin-bg | #f8fafc | Page background | | --admin-surface | #ffffff | Cards, forms | | --admin-text | #0f172a | Body text | | --admin-text-muted | #64748b | Secondary text | | --admin-accent | #ffae9c | Buttons, focus rings | | --admin-radius | 0.375rem | Border radius | | --admin-font | Mulish, system-ui, ... | Font family | | --admin-content-width | 64rem | Max content width |

Full list in src/styles/admin.css. Every element exposes data-* attributes for granular CSS targeting — no class names to lock onto.

The starter ships an alternative dark "glass" theme; see its src/styles/admin-theme.css for what a substantial override looks like.

Design posture

  • Routing-agnostic. Each admin route in your host framework (Astro, Next.js, Remix, Vite + React Router) renders an AdminLayout with the appropriate content. The toolkit doesn't ship its own router.
  • Auth-agnostic. Configure auth at the route level (middleware) and pass an identity prop to AdminShell. Components like TagScheduler accept canEdit callbacks so the host owns the policy check. @verevoir/access pairs naturally but isn't required.
  • Storage-agnostic. Any StorageAdapter works. Components take data as props and call consumer-provided save handlers; the toolkit never touches storage directly.
  • Composable. You can use AdminShell + DocumentList alone for a minimal admin, or bolt in DocumentEditor + SectionsEditor + TagScheduler as your content model grows.

See it in a real app

The Verevoir starter wires every component from this package into a working Astro admin with auth, tag scheduling, and a glass theme.

Docs

License

MIT