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

@webmodern/cms-sdk

v0.4.0

Published

Shared SDK: <Editable> (incl. richtext-accenten), <EditableImage> (incl. remote/CDN-uploads), CmsEditor (visuele editor), Supabase client + types

Readme

@webmodern/cms-sdk

Shared SDK voor alle WebModern apps. Gebruikt door zowel apps/cms als apps/site-starter (en alle geforkte klantsites).

Status: TODO

Scaffolding gepland in sessie 2. Hieronder wat de API straks wordt.

Geplande API

Components

import { Editable, EditableImage } from "@webmodern/cms-sdk";

// Tekst (server component fetcht, of client component met SSR fallback)
<Editable
  blockId="hero-title"
  type="heading"        // 'heading' | 'text' | 'richtext' | 'url'
  defaultValue="Welkom" // gebruikt als CMS leeg is
/>

// Richtext: `*woord*` in de waarde wordt een accent-span, newline een <br/>.
// De site bepaalt de accent-stijl via accentClassName; de klant markeert in
// het CMS alleen wélke woorden het accent krijgen (sterretjes typen).
<Editable
  as="h1"
  className="hero-title"
  blockId="hero-title"
  type="richtext"
  accentClassName="script-accent"
  defaultValue="Hier krijg je *overzicht* en *rust.*"
/>

// Afbeelding
<EditableImage
  blockId="hero-image"
  defaultSrc="/placeholder.jpg"
  defaultAlt="Hero illustratie"
  width={1200}
  height={630}
  priority           // optioneel, voor LCP
/>
// Klanten kunnen via het CMS een nieuwe afbeelding uploaden; `value` wordt dan
// een CDN-URL (CloudFront). Remote bronnen rendert <EditableImage> automatisch
// `unoptimized` (werkt zo ook op Cloudflare Pages, zonder Vercel-optimizer).
// Op Vercel-forks: voeg het CDN-domein toe aan next.config images.remotePatterns.

Visuele editor (CmsEditor)

Eén keer in de root-layout van de klantsite plaatsen. Doet niets tenzij de pagina met ?edit=1 in een iframe binnen het CMS draait; dan maakt het de <Editable>-blokken klikbaar en toont het de concepten die het CMS via postMessage stuurt (de site leest zelf nooit concepten — zie src/editor/protocol.ts).

import { CmsEditor } from "@webmodern/cms-sdk";

// app/layout.tsx (client of server layout)
<body>
  {children}
  <CmsEditor />            {/* optioneel: allowedOrigins={["https://cms.webmodern.nl"]} */}
</body>

Het gedeelde postMessage-protocol staat in @webmodern/cms-sdk/editor (types + isAllowedCmsOrigin), zodat het CMS dezelfde berichtdefinities gebruikt.

Hooks (client-side)

import { useContent, useSite } from "@webmodern/cms-sdk";

const content = useContent("hero-title"); // string
const site = useSite();                   // { id, name, slug, brand }

Server helpers

import { getContent, getSite } from "@webmodern/cms-sdk/server";

export default async function Page() {
  const title = await getContent("hero-title", { siteId: SITE_ID });
  return <h1>{title}</h1>;
}

Types

import type { Site, ContentBlock, ContentBlockType } from "@webmodern/cms-sdk/types";

Architectuur

  • Database client: Supabase met auto-generated types via Drizzle
  • Edit-mode detection: ?edit=1 query param activeert inline editor (alleen als ingelogd in CMS)
  • Caching: Server-side fetches via React cache() + Next.js revalidateTag per siteId
  • Realtime: Supabase Realtime channel per siteId voor instant CMS preview