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

scrollylite

v0.1.1

Published

Declarative scrollytelling visualization grammar for browser ESM.

Readme

ScrollyLite

Declarative scrollytelling visualization grammar for browser ESM. Authors describe story steps, chart idioms, semantic object identity, and transitions; ScrollyLite renders the sticky visualization and scroll interaction with D3.

const spec = story()
  .data("weatherDays", { url: "./weather_days_tidy.csv", type: "csv" })
  .layout("floatToText")
  .step("Baseline",     bar("weatherDays").x("decade").y("count").key("decade"))
  .step("Focus",        bar("weatherDays").x("decade").y("count").key("decade").where({ period: "recent" }))
  .step("Granularity",  bar("weatherDays").x("decade").y("count").key("decade").breakdown("type"))
  .toSpec();

await createStory(spec, { target: "#app", d3, aq });

You write what each step looks like — ScrollyLite diffs consecutive steps, infers what changed (filter? re-orientation? aggregation level? encoded field?), and animates the transition for you.

📖 Read the full documentation →

Install

Use your package manager, the same way you would install D3:

npm install scrollylite d3 arquero
yarn add scrollylite d3 arquero
pnpm add scrollylite d3 arquero

Then import ScrollyLite, D3, and Arquero explicitly:

import * as d3 from "d3";
import * as aq from "arquero";
import { createStory, story, bar } from "scrollylite";
import "scrollylite/style.css";
// Optional: import "scrollylite/themes/default.css";

const spec = story()
  .data("rows", {
    values: [
      { category: "A", value: 12 },
      { category: "B", value: 18 },
      { category: "C", value: 9 }
    ]
  })
  .view("main", { height: 520 })
  .step("Baseline", bar("rows").x("category").y("value").key("category"))
  .step(
    "Highlight B",
    bar("rows").x("category").y("value").key("category")
      .highlight({ category: "B" })
  )
  .toSpec();

await createStory(spec, { target: "#app", d3, aq });

Browser ESM from a CDN

For vanilla HTML, follow D3's modern CDN practice: use a module script and jsDelivr's +esm endpoint.

<div id="app"></div>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/scrollylite.css">
<script type="module">
import * as d3 from "https://cdn.jsdelivr.net/npm/d3@7/+esm";
import * as aq from "https://cdn.jsdelivr.net/npm/arquero@8/+esm";
import { createStory, story, bar } from "https://cdn.jsdelivr.net/npm/[email protected]/+esm";

const spec = story()
  .title("Revenue")
  .data("rows", {
    values: [
      { category: "A", value: 12 },
      { category: "B", value: 18 },
      { category: "C", value: 9 }
    ]
  })
  .view("main", { height: 420 })
  .step("Baseline", bar("rows").x("category").y("value").key("category"))
  .step(
    "Highlight B",
    bar("rows").x("category").y("value").key("category")
      .highlight({ category: "B" })
  )
  .toSpec();

await createStory(spec, { target: "#app", d3, aq });
</script>

Pin exact versions in production. latest URLs are convenient for experiments but bad for durable stories.

rows is a dataset name. .data("rows", ...) defines it; bar("rows") uses it.

The ESM entry follows D3's explicit dependency style: import the packages you need and pass d3 and aq to createStory().

Plain script fallback

If you cannot use module scripts, load the global bundle instead:

<script src="https://cdn.jsdelivr.net/npm/d3@7/dist/d3.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/arquero@8/dist/arquero.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/scrollylite.global.js"></script>

The global build exposes window.ScrollyLite and falls back to globalThis.d3 / globalThis.aq when createStory() runs.

Public API

The top-level package exports a small, stable surface:

import {
  createStory,        // async (spec, { target, d3, aq, debug }) => StoryRuntime
  story,              // chainable story-spec authoring builder
  bar, line, point, unit,            // chainable chart-idiom builders (the only built-ins — no aliases)
  defineChartIdiom,   // define a custom chart idiom plugin
  registerChartIdiom, // register a custom idiom at runtime
  registerChartModule,
  availableChartIdioms
} from "scrollylite";

Type definitions ship with the package at dist/index.d.ts. For the full reference — every chainable method, every config option, the runtime object shape, scene-inference rules, and how to plug in your own chart idiom — see the docs.

Development

Serve the demo:

python3 -m http.server 5510

Then open:

http://localhost:5510/examples/weather/

Build the CDN-ready files:

npm run build
npm run smoke

The build writes:

  • dist/scrollylite.esm.js
  • dist/scrollylite.browser.js
  • dist/scrollylite.global.js
  • dist/index.d.ts
  • dist/browser.d.ts
  • dist/scrollylite.css
  • dist/themes/default.css
  • copied ESM modules under dist/

Architecture

The runtime has four clean layers:

  • src/grammar/: chainable story and idiom authoring API.
  • src/charts/: chart idiom plugins, renderers, compilers, state, and keys.
  • src/transitions/: scene inference and spec compilation from plugin capabilities.
  • src/scrollylite.js: story lifecycle, data loading, layout, scene rendering, scroll control, and cleanup.

Each idiom exposes one plugin:

export const plugin = defineChartIdiom({
  key: "point",
  createRenderer,
  createSpecCompiler,
  scenes: ["focus", "guide", "granularity", "observation"],
  stateOperations: {
    focus: "filter",
    guide: "coordinate",
    granularity: "aggregate"
  },
  transition: {
    plan,
    intermediateSpecs
  },
  defaults: { margin }
});

The runtime idiom is flat: key, renderer, prepareSpec, resolveTransitionPlan, intermediateSpecs, defaultMargin, inspect, scenes, and stateOperations.

See Extending with Plugins for a full guide to authoring and registering your own chart idiom.

Publish

Release flow:

npm version patch
npm run release:check
npm publish
git push --follow-tags

Update CHANGELOG.md before tagging a release. npm publish runs npm run release:check automatically.

jsDelivr can serve npm packages with:

https://cdn.jsdelivr.net/npm/[email protected]/dist/scrollylite.esm.js
https://cdn.jsdelivr.net/npm/[email protected]/dist/scrollylite.browser.js
https://cdn.jsdelivr.net/npm/[email protected]/dist/scrollylite.global.js

It can also serve tagged GitHub releases:

https://cdn.jsdelivr.net/gh/SonghaiFan/[email protected]/dist/scrollylite.esm.js

For GitHub CDN links, commit dist/ before tagging because GitHub CDN does not run the build step for you.

Docs

Pick the guide that matches how you're using ScrollyLite:

  • docs/for-cdn-users.md: browser ESM, no build tools — paste a module script into any page and go. Start here if you're not running npm/bundlers.
  • docs/for-developers.md: npm/bundler projects & contributors — install, architecture, scripts, release flow, extending the library.
  • llms.txt: AI agents / LLMs — a dense, single-file reference covering the entire grammar and API, written for machine consumption.

Or start at docs/getting-started.md, which links to everything below in reading order:

License

MIT