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

@kirigami/plugin-embed

v0.2.2

Published

<youtube>/<vimeo> video embed cards for Kirigami — oEmbed-backed, localStorage-cached, cover thumbnail + play button, powered by @kirigami/canva's observer.

Readme


@kirigami/plugin-embed

YouTube / Vimeo embed cards for the Kirigami static site generator.

npm version License: GPL-3.0-or-later Node.js >=24.0.0 Website


Overview

@kirigami/plugin-embed turns a bare <youtube id="…"> or <vimeo id="…"> tag into a real video card — a cover thumbnail, the video title, and a play button — with no build-time network call: the oEmbed lookup happens in the visitor's browser, on first paint, via @kirigami/canva's observer.

The result is cached in localStorage, so later lookups can reuse stored metadata. Concurrent first-time requests are not deduplicated, and thumbnails still load. The play button is a single inline SVG themed off the project's own --accent — nothing to draw yourself.

Part of the Kirigami project ecosystem.


Table of contents


What's new in 0.2.2

  • The YouTube player URL carries feature=oembed, like the iframe YouTube's own oEmbed endpoint returns.

What's new in 0.1.5

  • Dependency bump to @kirigami/canva 2.6.0 / @kirigami/sdk 0.2.1; homepage + README pointed at the site (metadata only).

What's new in 0.1.4

  • Dependency bump to @kirigami/canva 2.5.1.

What's new in 0.1.3

  • Superseded the 16∶9 aspect-ratio floor with a maxWidth cap + the real ratio. A full-page-wide .embed (no max-width) still read as huge even at a "correct" ratio, so the floor hack is gone: .embed now caps at max-width: var(--embed-max-width, 40rem), and the video's actual aspect-ratio is used. Two new options: maxWidth (default "40rem", "none" removes the cap) and forcedAspectRatio (e.g. "1 / 1" to pin every card in a grid to one uniform shape).

What's new in 0.1.1

  • Aspect-ratio floored at 16∶9 — a real, reported bug: a narrower source video (4∶3, portrait, a Short) produced an unusually tall card that dominated the page next to normal widescreen ones. The real player, once clicked, still showed at its own true ratio, pillarboxed rather than stretched. (Superseded by 0.1.3's maxWidth cap, above.)

Installation

kiri install embed

or by hand:

npm install --save-dev @kirigami/plugin-embed
plugins:
  - name: "@kirigami/plugin-embed"
    active: true

Needs an esbuild task in kirigami.yaml — that's where the observer script ships to the browser.


Configuration

Options

| Option | Type | Default | Description | |---|---|---|---| | style | boolean | true | Append the default .embed card styles to every sass task. Set false to write your own. | | maxWidth | string | "40rem" | Caps how wide (and, via aspect-ratio, how tall) a card can get — any CSS length, or "none" to remove the cap. Ignored when style is false. | | forcedAspectRatio | string | "" | Pin every card to one shape ("16 / 9", "1 / 1", …) instead of each video's own real ratio — handy for a uniform grid. Empty uses each video's real ratio. Ignored when style is false. |


Usage

Straight in HTML — the tag is deliberately non-closing, like <img>:

<youtube id="dQw4w9WgXcQ">
<vimeo id="1084537">

or, inside Markdown, the shorthand:

{% youtube dQw4w9WgXcQ %}
{% vimeo 1084537 %}

Both forms produce the exact same tag — the shorthand just saves typing raw HTML in prose.

Only YouTube and Vimeo providers are implemented. Other providers require a custom observer registration and an endpoint the browser can access; provider access policies are not part of this package’s API.


How it works

  1. src/embed.js registers youtube and vimeo on @kirigami/canva's observer, which sweeps the page for those tags (on load, and for anything added later) and hands each one to the plugin.
  2. The tag is swapped immediately for a .embed placeholder — sized by the default 16∶9 aspect-ratio — reserving space while metadata loads. A later aspect-ratio change can still move surrounding content.
  3. The video's oEmbed data is read from localStorage (kirigami-embed:<provider>:<id>) if a previous visit already resolved this id, or fetched from the provider's oEmbed endpoint otherwise and cached for next time.
  4. Once that resolves, the thumbnail and title are patched into the same placeholder, and the aspect-ratio is updated to the video's own real ratio (4∶3, square, portrait, a Short — whatever it actually is). It's the card's max-width (maxWidth, default 40rem) that keeps a narrower video from ever looking oversized, not a distorted ratio — the real player, once clicked, shows at that same real ratio too, nothing is ever stretched.
  5. Clicking the play button swaps the placeholder's content for the real player <iframe> — the player loads only after that click; metadata and thumbnail requests happen earlier.

Generated assets and failure behavior

The prepros:php hook includes php/embed.php for the Markdown shortcuts. Without an esbuild task, registration warns and skips the browser script; the shortcuts still emit tags, but they do not become cards. Include the generated JavaScript in the page.

With style: true, each sass:after call writes .generated-vars.scss in the installed plugin directory and appends it with assets/_embed.scss. The generated file sets --embed-max-width and, when requested, an !important aspect-ratio rule. The install directory must be writable. Builds sharing that installation share the file; their options are not isolated there. style: false skips both files and ignores the sizing options.

The browser accepts YouTube IDs matching 10–12 word/hyphen characters and Vimeo IDs containing only digits. Missing or malformed IDs leave the HTML tag unchanged; a Markdown shortcut without an ID emits a comment.

Metadata cache entries have no expiry. Invalid JSON triggers a refetch; failed cache writes are ignored, but a failed localStorage read prevents fetching (audit A18). Requests are subject to browser network and CORS rules; this plugin supplies no proxy, timeout, or retry. A failed request logs to the console and leaves the play button usable without metadata. Playback uses youtube-nocookie.com or player.vimeo.com with autoplay requested. Metadata and thumbnail requests occur before the click.


Styling

The bundled .embed card (.embed__title, .embed__play, .embed__player) is themed off @kirigami/canva conf's --accent / --surface-2, so it tracks your project's own palette automatically. Set style: false and target those same class names to restyle it from scratch.


Requirements

The current localStorage read can throw in restricted browser contexts and prevent metadata retrieval (audit A18). This is a known limitation, not an automatic in-memory fallback.

  • Node.js >= 24.0.0
  • npm >= 10.2.3
  • @kirigami/kirigami >= 3.0.0 (declared kirigami.minVersion)
  • A sass task for the bundled styles
  • An esbuild task in kirigami.yaml

License

GPL-3.0-or-later © Maxime Larrivée-Roy, 2026