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

maverick-wave-astro

v1.14.0

Published

Shared frame for static Astro homepages built with MaverickWave: layout, SEO, design variants, schedule, building blocks.

Readme

maverick-wave-astro

Shared frame for the Astro homepages built with MaverickWave. A site keeps its site.ts, its content and what is truly its own.

Setup

npm install maverick-wave-astro maverick-wave astro
// astro.config.mjs
import homepage from "maverick-wave-astro";
import { OG_IMAGE, SITE } from "./src/config/site.ts";

export default defineConfig({
  site: "https://example.de",
  integrations: [homepage({ site: SITE, ogImage: OG_IMAGE })],
});

The integration sets the CSP-safe build options, the @ alias, the sitemap, /design.css, /theme.js and the MaverickWave script. site.ts is typed with satisfies Site (src/types.ts). Colours and fonts stay in the site's main.scss.

After the build it writes robots.txt (site.aiCrawlers), llms.txt and, with site.email, /.well-known/security.txt - only for a site at the root of its host, a file in public/ wins. It warns about titles over 60 characters, descriptions outside 140-160, pages without exactly one <h1> and images over 200 KB.

Design

design in site.ts takes the semantic values from src/design.ts, e.g. { corners: 'even', buttonShape: 'pill', spacing: 'airy' }, or the text from the setup box of the MaverickWave overlay. The werkbank section with schemas/design.schema.json overrides it value by value; a site not yet moved there uses src/content/design.json.

Layout

The site wraps BaseLayout once and imports its stylesheet there:

<Frame {...Astro.props}>
  <slot name="head" slot="head" />
  <slot name="header" slot="header" />
  <slot />
  <slot name="footer" slot="footer" />
  <Scripts slot="scripts" />
</Frame>

Slot banner sits below the header; htmlData puts data-* on <html>. bodyClass adds to site.bodyClass; bare renders only the default slot into <body> - no skip link, no <main>, no header or footer.

AppShell is the frame of an app page: render it inside BaseLayout bare, it brings its own skip link. nav groups AppLinks, tabbar takes the phone's destinations, the aside slot a side panel, persist remembers rail and aside. The toggles come from the MaverickWave script.

Components

  • Frame: Header, Footer (social links and notes above a bar with copyright, credit and the legal links; dark, compact), ThemeToggle, LanguageSwitch, Announcement, PromoBar
  • Sections: Hero (variant start | fade), SplitHero (text beside a photo, no parallax), Parallax (a picture band between sections), SectionHead, IconCard, ValueList, OpeningHours, Address, Accordion, Calendar, CalendarLegend, EmptyState (inline)
  • Blocks: Bento with BentoItem (size wide | tall | lg | full), ActionBar (call, route, booking), Marquee, Compare, Stat in a StatGroup, Meter, ProgressRing, Rating, Chat, Pagination
  • Options: Modal drawer (end | start), Progress without value runs indeterminate, Timeline variant="compact", Picture shape (arch | signature | leaf), Table hover and stickyFirst
  • Pages: NotFound, LegalPage, ImprintCard, PrivacyCard
  • Schedule hides expired entries in the browser (data-expires, data-starts, data-schedule-list, data-day)

Helpers live in src/ and import as maverick-wave-astro/<file>.

Presentations

A presentation is one JSON object typed Deck (maverick-wave-astro/deck): format (landscape | portrait), brand, and slides with layout, tone, image or drawing, head texts and blocks (facts, figures, list, chips, steps, notes, jumps, table, packages, images, quote, price, text, actions, swipe, chart). Deck renders it as a page of its own; the site wraps it once to bring its stylesheet, like BaseLayout:

---
import "@/styles/main.scss";
import Frame from "maverick-wave-astro/Deck.astro";
---

<Frame deck={Astro.props.deck}><slot /></Frame>

DeckFrame embeds such a page in an iframe (slot = text beside it), DeckCard links to it. SCSS: components/deck and components/deck-frame.

Deck checks the JSON while building (validateDeck) and stops with the path of every problem - an unknown block type, a jump to a missing slide id, a drawing not in public/. The chrome over the slides wears the second colour; accent: 'primary' keeps it to the first, design.accent: 'single' does so site-wide.

Occasions

Seasonal decoration on the cards, panels and testimonials - snow, a garland, leaves, bunting. Drawn by MaverickWave (components/occasions), switched on by a file: with src/content/occasions.json, or a werkbank section with an occasions.schema.json, the integration sets data-mw-occasions on <html> and serves /occasions.js, MaverickWave's head script, as the first script in <head>. It picks today's entry before the first paint.

{
  "motion": "dynamic",
  "size": "sm",
  "entries": [
    {
      "effect": "christmas",
      "from": "2026-12-18",
      "until": "2026-12-26",
      "yearly": true
    }
  ]
}

motion (static | dynamic) and the optional size (sm | lg) hold for every entry. Needs maverick-wave 5.34 or later.

Werkbank

werkbank/struktur.json lists the languages and the editable sections with their schemas; a site not yet moved has contentmanager/sections.json. schemas/design.schema.json, schemas/promo.schema.json and schemas/occasions.schema.json ship with the package. Put mwa-check && astro build in the build script so a broken file stops the build - it knows the formats date, email, uri and the keywords x-widget, x-item-title, x-labels, x-empty, x-not-before, x-groups, x-newest-first, x-translate. Photos uploaded in the werkbank land in public/images/uploads/; the integration derives their sizes before the build (maverick-wave-astro/uploads), skips a file sharp cannot read and removes the originals from dist/, since they still carry EXIF and GPS. Tooling: re-export maverick-wave-astro/eslint and /prettier.

Pages read sections and the texts of the code through maverick-wave-astro/werkbank:

// src/texts.ts
const de = { hero: { title: "Willkommen" } };
const en: typeof de = { hero: { title: "Welcome" } };
export const textsFor = defineTexts<typeof de>({ de, en });

// a component
const { hero } = textsFor(Astro.url);
const workshops = content<Workshops>("workshops", Astro.url);

A section comes from src/content/werkbank/<schluessel>.json, which the werkbank writes before every build, or else from its start content - so astro dev works without the werkbank. A language without texts, or a text missing in one language, stops the build. The first language lives at /, every other one under /<code>/; localized, alternates and switcher (the props of LanguageSwitch) take Astro.url.

Releasing

  • tools/install-local.sh <site>|--all packs and installs into sites without publishing
  • ./release.sh publishes the version from package.json, then tools/update-all.sh <version> moves all sites and builds each one