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

@reiwuzen/tabria

v1.3.0

Published

pnpm publish --access public

Readme

Tabria

Core idea

Tabria separates state management from UI rendering.

UI (React / Vue / etc)
        |
Tabria (state engine)
        |
Application logic

The library only handles state transitions, such as:

  • opening tabs
  • closing tabs
  • switching tabs
  • navigating between pages inside a tab
  • restoring closed tabs from closed history

Your UI framework simply subscribes to the state and renders it.

Main concepts

Workspace

The global state container.

Workspace
  activeTab
  limits { openTabs, closedTabs, totalTabs }
  tabs.openOrder[]
  tabs.closedOrder[]
  tabs.storage{}

Tab

Represents a working context.

Tab
  id
  title
  createdAt
  updatedAt
  runtimeState
  pages.order[]
  pages.storage{}
  currentPageId

A tab can contain multiple pages.

Page

A navigation entry inside a tab.

Page
  id
  key
  url
  type
  view
  state
  meta

Example:

type: "reader"
view: "vertical"
state: { page: 12 }

Page History

Each tab maintains its own ordered page history.

Example navigation:

Library
  -> Manga
    -> Reader

History representation:

[Library, Manga, Reader]

Operations include:

  • pushPage
  • popPage
  • replacePage
  • updatePageState

Core capabilities

Tabria provides primitives for:

Tab management

  • createWorkspace
  • createTab
  • openTab
  • addTab
  • activateTab
  • closeTab
  • moveTab
  • reopenClosedTab

Page navigation

  • createPage
  • pushPage
  • popPage
  • replacePage
  • updatePageState

Closed tab history

  • tabs.closedOrder
  • reopenClosedTab()

Design goals

Tabria is designed to be:

  • headless: no UI components
  • framework-agnostic: works with React, Vue, Svelte, etc.
  • predictable: pure state transition functions
  • portable: usable in web, desktop (Tauri/Electron), or Node apps

Installation

pnpm add @reiwuzen/tabria
npm install @reiwuzen/tabria

Usage

import {
  createWorkspace,
  createTab,
  createPage,
  addTab,
  openTab,
  pushPage,
  updatePageState,
  getActiveTab,
  getActivePage,
  type Workspace,
} from "@reiwuzen/tabria";

let workspace: Workspace = createWorkspace();

const tab = createTab({ title: "Library" });
workspace = addTab(workspace, tab);

workspace = openTab(workspace, { title: "Manga" });

const library = createPage({
  type: "library",
  view: "grid",
});
workspace = pushPage(workspace, tab.id, library);

workspace = updatePageState(workspace, tab.id, {
  section: "favorites",
});

const activeTab = getActiveTab(workspace);
const activePage = getActivePage(workspace);

// Customize or bypass limits (null disables a limit)
workspace = createWorkspace({
  limits: {
    openTabs: 20,
    closedTabs: 20,
    // openTabs: null,
  },
});

API Reference

Grouped exports (optional)

  • core
  • actions
  • selectors
  • api (merged convenience API)

Types

  • Workspace
  • Tab
  • TabID
  • TabState
  • Page
  • PageID
  • PageState
  • JsonObj

core

  • createTab
  • createPage
  • createWorkspace

actions

  • openTab
  • addTab
  • activateTab
  • closeTab
  • moveTab
  • reopenClosedTab
  • pushPage
  • popPage
  • replacePage
  • updatePageState

selectors

  • getTabs
  • getTab
  • getActiveTab
  • getActivePage
  • getPageStack

Selectors are read-only helpers for view code. Use actions for any state updates.

Behavior Notes

  • All operations are pure: they return new state objects instead of mutating inputs.
  • Selectors are pure read helpers and should be used for view/derived access only.
  • If an operation targets a non-existent tab, the original state is returned.
  • closeTab moves the tab ID from tabs.openOrder to tabs.closedOrder, sets closedAt, and marks the tab runtimeState as discarded.
  • reopenClosedTab() restores the most recently closed tab by default.
  • reopenClosedTab(tabId) restores a specific closed tab when found.
  • Workspace defaults are openTabs: 20, closedTabs: 20, and totalTabs: 40.
  • Set any workspace limit to null when creating a workspace to bypass that limit.
  • totalTabs is derived internally as openTabs + closedTabs and is not user-configurable.

Development

pnpm install
pnpm build

Build output:

  • ESM: dist/index.js
  • CJS: dist/index.cjs
  • Types: dist/index.d.ts

License

ISC