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

@rx-ventures/quiz-runtime

v0.5.4

Published

Renders a published Atlas quiz. One component, one stylesheet, no Tailwind in your repo.

Readme

@rx-ventures/quiz-runtime

A published Atlas quiz, rendered. One component, one stylesheet, no Tailwind in your repo.

Public on the registry so two private repositories can both install it. That is a distribution decision, not a licence — UNLICENSED, no rights granted, and it is built for one product's data model rather than for general use.

npm i @rx-ventures/quiz-runtime
import { QuizRunner, fetchAtlasQuiz } from "@rx-ventures/quiz-runtime";
import "@rx-ventures/quiz-runtime/styles.css";
import { notFound } from "next/navigation";

export default async function Page({
  params,
}: {
  params: Promise<{ handle: string }>;
}) {
  const { handle } = await params;

  const quiz = await fetchAtlasQuiz({
    base: process.env.ATLAS_URL!,
    org: process.env.ATLAS_ORG!,
    brand: process.env.ATLAS_BRAND!,
    key: process.env.ATLAS_KEY!,
    handle,
  });
  if (!quiz) notFound();

  return (
    <main className="flex min-h-svh flex-col">
      <QuizRunner quiz={quiz.document} theme={quiz.theme} />
    </main>
  );
}

That is the whole integration. The min-h-svh column is the one thing worth copying: the quiz fills the height it is given, so a page that gives it none leaves the footer under the last question instead of at the foot of the screen.

Why it lives in Atlas's repository

Atlas is the builder. It is also a consumer of this package — its Simulate tab and its /run page import from here exactly as a storefront does.

That is not tidiness. A builder and a renderer that disagree produce a quiz that previews one way and runs another, and the only structural defence is for there to be one renderer with the builder importing it. If Atlas ever stops importing this package, that defence is gone.

What ships

| Entry point | What | | -------------------------------- | -------------------------------------------- | | @rx-ventures/quiz-runtime | QuizRunner, fetchAtlasQuiz, QuizDocument, AtlasTheme | | @rx-ventures/quiz-runtime/styles.css| The compiled, scoped stylesheet | | @rx-ventures/quiz-runtime/document | The quiz model — types, schemas, predicates. No React. | | @rx-ventures/quiz-runtime/react | The renderer in pieces, for Atlas's builder | | @rx-ventures/quiz-runtime/quiz.css | The quiz's own rules, uncompiled, for a Tailwind consumer |

The first two are the promise. Everything in index.ts can be added to and nothing taken away. The other three move with the renderer — depend on them the way Atlas does, in step, or not at all.

QuizRunner({ quiz, theme })

Takes both, because a document without a theme is the right words at the wrong size in the wrong typeface. It injects the @font-face rules and the type scale itself, so there is nothing to remember to mount alongside it.

fetchAtlasQuiz({ base, org, brand, key, handle })

Resolves the pointer, then the document and theme together. Returns null when nothing is published at that address — a 404 you should answer with your own — and throws on anything else, because a 500 rendered as "not found" sends people looking for something that is in fact there.

The cache hints mirror Atlas's own Cache-Control: 30s on the pointer and the theme, forever on the document, which is written once at a version and never edited.

key is server-side only. Issue it in Atlas under Settings → Brands; it is shown once and stored there only as a hash, so a lost key is re-issued rather than recovered. It both authenticates the request and identifies the brand — Atlas resolves the brand from the key and refuses if org/brand disagree, so a key cannot read a brand it was not issued for.

Call this from a server component, a route handler or a build step. Never from code that reaches a browser: anything in a client bundle is public. Atlas sends no CORS headers at all, so a browser cannot make the request even holding a key — that is deliberate, not an oversight to work around.

The stylesheet

styles.css is compiled from Tailwind and then scoped: every selector is prefixed with .ay-quiz, :root and html are rewritten to it, and the cascade layers are flattened so the rules compete on specificity rather than losing to any unlayered rule in your page. Preflight is included, scoped the same way, so the quiz gets the reset its utilities were designed against without touching anything outside it.

You do not need Tailwind, @base-ui/react, a --muted-foreground, or a cn. scripts/check-dist.mjs asserts the scoping and the surviving "use client" directives on every build, because both failures are invisible here and only appear in your repository.

Isolation runs both ways. Scoping stops the package's rules escaping; a second set of resets on .ay-quiz stops the host's typography inheriting IN, and a :where() reset handles host rules that name an element directly — a base layer setting letter-spacing on h1h6 reaches quiz headings without inheriting through anything. Both are kept at one class of specificity, so the quiz's own utilities still win.

Three things stay global, because CSS gives them no scope:

  • the @font-face families a brand registers — a host with the same family name and different files is a coin toss;
  • @property --tw-* registrations, which a host running Tailwind v4 also declares (identically, today);
  • text-decoration set on a host ancestor, which propagates to descendants and cannot be removed by them.

@keyframes would be a fourth and is namespaced ay-quiz-* instead.

Dark mode is off. A quiz renders in its brand's palette; following the host page's night mode would be the brand rendering as something else.

Version skew

An author can publish a block kind older runtimes have never heard of. That renders as a placeholder and the rest of the quiz carries on — the unknown block captures nothing, so nothing waits on an answer that cannot be given. Keeping up to date is still the right thing; it just isn't load-bearing.

Working on it

pnpm --filter @rx-ventures/quiz-runtime build   # tsc, then the scoped CSS, then the checks
pnpm --filter @rx-ventures/quiz-runtime dev     # tsc --watch, for editing alongside Atlas

Atlas consumes dist, so a change here needs a build before Atlas sees it — pnpm dev and pnpm build at the repository root do that for you.

Atlas does not load styles.css. It scans this package's source with its own Tailwind (@source in src/app/globals.css) so the builder's chrome, its tokens and its theme toggle stay coherent around the quiz. The rules no utility expresses live in quiz.css, which both sides import — one copy, no drift.