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

@fasl-work/caos-app-shell

v0.15.0

Published

Shared web-app shell, workbench primitives, content primitives, design system and measured gate for the CAOS / Faena public apps (ADR-0016, ADR-0017, ADR-0071).

Readme

@fasl-work/caos-app-shell

License Version

The shared web-app shell, route types, views, drawings, design system and measured gate of the CAOS / Faena public apps, one of the three parts of the CAOS base with the product template (CAOS_PRODUCT_TEMPLATE) and the policy (ADR-0016, ADR-0017, ADR-0071, ADR-0078). The frame, the header, the icons, the tab structure, the viewport, the areas, the text in drawings and the numbers are defined once here; every product composes them, so a fix lands in one place and no product writes them again. Documentation: docs/ (structure, tokens, navigation, views, drawings, icons and numbers, the gate, releasing).

Install

npm i -E @fasl-work/caos-app-shell        # an exact pin: the build you gated is the build you ship
# peer deps (the app provides them):
npm i react react-dom react-router lucide-react katex zustand
# optional: the house chart and the measured gate
npm i uplot && npm i -D playwright

Use

<!-- index.html: apply the stored theme and language before the first frame (THEME_BOOT_SCRIPT, ADR-0011) -->
<script>/* paste THEME_BOOT_SCRIPT here, or inject it at build */</script>
// main.tsx
import "@fasl-work/caos-app-shell/styles.css";
import "@fasl-work/caos-app-shell/chart.css"; // only with the chart entry
import { BrowserRouter, Routes, Route } from "react-router";
import { AppShell, STANDARD_ROUTES, type ShellConfig } from "@fasl-work/caos-app-shell";

const config: ShellConfig = {
  product: { name: "RotorVitals" },
  routes: STANDARD_ROUTES, // App, Introduction, Methodology, Implementation, Experiments, Benchmark
  links: { github: "https://github.com/fsantibanezleal/CAOS_RotorVitals" },
  version: "0.01.000", // X.XX.XXX, checked on mount
  build: import.meta.env.VITE_BUILD_ID, // short commit, shown beside the version
  license: { en: "MIT licence", es: "Licencia MIT" }, // required; no default
  visibility: "public", // "private" hides every source link
  contain: true, // every route is the viewport (ADR-0071 rule 1)
};

<BrowserRouter basename={import.meta.env.BASE_URL}>
  <AppShell config={config}>
    <Routes>{/* / = the workbench; the rest are DocPage routes */}</Routes>
  </AppShell>
</BrowserRouter>
  • Three route types (docs/01): the workbench (CaseWorkbench, a product about cases), the surface (SurfacePage, a hub, an explorer or a console: a head, one row of views, the open view filling the rest), the document (DocPage). Under contain each fills or scrolls inside the viewport; no product writes containment CSS.
  • Land on the tool: / is the App route; the five documentation routes are separate pages.
  • One React, one router: set resolve.dedupe: ['react', 'react-dom', 'react-router'] in Vite. A second copy leaves the shell outside the router context; AppShell reports it with console.error and names the cause.
  • Product metadata: license and visibility are required: the footer shows the product's licence and a private product shows no source link. footer.attribution accepts bilingual text or false.
  • Hub case (Faena): pass routes: [] (or one) and the nav is hidden; header and footer stay identical.
  • The App route: one CaseWorkbench is the whole route: the rail holds the case picker (cases, the CaseSelector props), the variants (variants) and your rail (parameters as Knob and ChipGroup, live values as Readout / Gauge / Verdict); the instrument holds at most six question groups, then the variant comparison and the context. Pickers and numbers live in the rail so the drawing keeps the instrument. Every control writes data-control. PlotCard and Readout take lane, provenance and a dataKey: pass useWorkbenchState().stateKey as captured when the computation started (rail and instrument share it), and a view still showing an earlier selection is overlaid as stale. Anything that loads declares data-state="loading" until it is ready; the gate waits for that, never for the network. A view whose data is absent declares data-state="unavailable" on an element a reader can see (a visible box of 40 by 12 px at least inside the instrument, opaque, its text painted inside the box: not pushed out by text-indent, cut by clip-path or under 8 px) whose rendered text states the reason (12 letters or digits in two words at least) and renders no drawing element; the gate then accepts it under G6, while an unreadable note, a declaration without a reason, or one beside a blank, collapsed or invisible chart still fails. The gate checks that a reason exists, not that it is true.
  • Fill the instrument: <PlotCard fill> takes the height its panel leaves (several fill cards share it, a .caos-views-row puts them side by side), and a Stage or <UPlotChart height="fill"> inside it gets a real size. A table (.caos-table) is sized to its rows: put it above the drawing of the same numbers, never alone.
  • Drawing: put canvas, WebGL and SVG instruments in a Stage (or useStageSize): nothing draws at zero size, and colours come from useThemeTokens() (a canvas cannot read CSS variables).
  • Charts: import { UPlotChart } from "@fasl-work/caos-app-shell/chart": x and y titles with units, series by token colour, marks for what the engine detected (placed inside the plot, haloed), a key of every series when there are two or more, a cursor readout row, theme and language rebuilds, one tick notation per axis. Categories go in BarChart (main entry, no uPlot). A drawing of your own measures its labels with the text kit (textWidth, fitLabel, niceTicks) and declares data-chart (docs/05).
  • Views in the URL: CaseWorkbench and SurfacePage hold the open view in ?view= (and the case selector the case in ?case=), so a view can be shared and survives a reload.
  • Focus mode for the App (0.14.0): <CaseWorkbench focus /> adds a Focus button to the rail head that opens the selected case's open group in the full viewport (FocusShell: the stage is the view, the rail stays), keeps ?focus=1 beside ?case= and ?view=, and returns with Escape or the exit button to the same case, group and sub-view; a product with a simulation must offer it (ADR-0070, caos-shell-gate --require-focus). See docs/04.
  • Small cards and animation (0.14.0): FlipCard and CardDeck for SMALL cards the reader scans by title (a flip card shows its title and turns to its content; a deck is a row up to four cards and a carousel above), used by the executive view for its bearers, roles, approaches and 4 C's; an executive illustration may be an animated SVG with a prefers-reduced-motion block (docs/04, docs/06).
  • Icons: lucide icons are sized by where they sit (svg.lucide); pass no size (docs/06).
  • Numbers: formatNumber(value, lang, opts) or useFormat(); never toFixed in a view. A magnitude below 1e-4 is written in scientific notation (a p-value of 1e-200 is 1E-200, not two hundred zeros); give digits, not decimals, for p-values. A percent and a unit are joined by a no-break space.
  • Documentation routes: DocPage and DocSection (each section ends in its own Refs, or states why it cites nothing), Equation with a caption, CitationsProvider and Cite (every citation has a DOI or URL). Tabs, SubTabs and TabGroups are controllable and render only the open panel inside a PanelBoundary.
  • Architecture modal: five or more tabs, each an inline SVG string (import svg from "./x.svg?raw") that uses only SHELL_TOKENS; validateArchitectureConfig reports anything else on mount.
  • Measure it: npx caos-shell-gate --serve dist --expect-brand "RotorVitals" serves the build as GitHub Pages does (no SPA fallback), or --url https://... measures the deployed origin (needs playwright). It walks every route, tab, sub-tab and case at five sizes, both themes and both languages, and fails on: a wrong subject (G1) or mode (G2), console errors and 4xx/5xx (G3), broken deep links or HTML for an artifact (G4), anything a reader cannot scroll to, see whole or click (G5), blank or underfilled drawings and an instrument under half the viewport (G6), a view that never settles (G7), loops at rest (G8), controls that change nothing (G9), labels cut or overlapping in a drawing, also in a wider fallback font (G10), a decimal point on a Spanish page (G11), a number or percentage broken across lines (G19), a vertical sub-tab list that scrolls away (G12), text under WCAG AA contrast (G13, every language on a documentation page), and a documentation page without the required areas of its kind (ADR-0017.2: executive and technical Introduction, Methodology, Implementation, Experiments, Benchmark; declared with <DocSection area="...">, waived only with a reason of 12 letters or digits in two words through floorWaivers; the executive view opens first, every Introduction section sits in a view, a method cites references, a live control is registered with data-control, and a tab list inside a section belongs to it; docs/04). The report (gate-output/gate-report.json) lists every failure and the smallest margins against each floor; index.html beside it shows every capture (G14). Details: docs/07.
  • Your own CSS: never restyle a class of reserved-classes.json components; a modifiers word (on, active, fill, wide) may be joined to your own class (.my-row.on), never used alone. The template's guard reads that list. Values come from the tokens (var(--rail-w), var(--space-3), docs/02).
  • Animated views: drive every canvas or 3D loop through usePausedViz (default paused, run once, halt on a hidden tab), never call requestAnimationFrame directly.

Exports

AppShell, STANDARD_ROUTES, WorkbenchShell, FocusShell, ArchitectureModal, validateArchitectureConfig, ThemeToggle, LanguageToggle, useThemeStore, applyTheme, readTheme, THEME_BOOT_SCRIPT, THEME_STORAGE_KEY, LANG_STORAGE_KEY, useLangStore, useShellLang, formatNumber, useFormat, NOT_AVAILABLE, SHELL_TOKENS, resolveToken, useThemeTokens, PanelBoundary, usePausedViz, createVizLoop, CaseSelector (and the caseModel helpers), Tabs, MAX_PEER_TABS, SubTabs, TabGroups, Callout, Equation, InlineMath, Figure, CitationsProvider, Cite, Refs, ReferenceList (deprecated), DocPage, DocSection, WorkbenchLayout, CaseWorkbench, MAX_WORKBENCH_GROUPS, VariantBar, LaneBadge, Readout, Gauge, Verdict, PlotCard, Knob, ChipGroup, Stage, useStageSize, makeStateKey, isStale, useWorkbenchState, WorkbenchStateContext, pick; since 0.8.0 SurfacePage, useUrlView, viewParamOf, replaceQueryParam, BREAKPOINTS, BarChart, textWidth, widestLabel, fitLabel, niceTicks, niceStep, fontFamily, formatTicks, NBSP, SCIENTIFIC_BELOW, the type ShellColorToken; since 0.9.0 ViewsRow. Since 0.14.0 FlipCard, CardDeck (with FLIP_LIMITS, FLIP_TEXT, DECK_TEXT, perPageFor, deckWindow, deckPosition), the focus prop of CaseWorkbench (CaseFocusConfig, FOCUS_TEXT, FOCUS_PARAM) and removeQueryParam. Separate entries: /chart (UPlotChart with x.log, parity, onPick; drawMarks, tickSteps, repeatedLabels, seriesStyle, sortOrder, parityRange), /keys (the storage keys, no React), /styles.css, /chart.css, /reserved-classes.json. Bin: caos-shell-gate.

Authenticated workbenches

WorkbenchShell is the shared frame for products whose authenticated UI needs a desktop sidebar and mobile bottom navigation. It renders typed routes and the main landmark while the product supplies its own stateful controls through brand, sidebarFooter, headerLead, headerActions, and overlays. Authentication, account policy, preference persistence, chat, and modal content remain product-owned. The component uses the stable core NavLink contract and supports react-router 6, 7, and 8. Browser applications on 6/7 install the matching react-router-dom, which supplies the core peer; Router 8 applications provide react-router directly. Do not mix different core and DOM majors in one application.

MIT · part of the Faena mining-analytics hub.