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

@onyx-ai/opal

v0.1.2

Published

Opal — Onyx's Typescript component library and design system.

Readme

Opal

Onyx's TypeScript component library and design system.

Install

npm install @onyx-ai/opal

Peer dependencies (install whichever the lib actually exercises in your usage):

npm install react react-dom next \
  @radix-ui/react-popover @radix-ui/react-separator \
  @radix-ui/react-slot @radix-ui/react-tooltip \
  @dnd-kit/core @dnd-kit/sortable @dnd-kit/modifiers @dnd-kit/utilities \
  @tanstack/react-table formik \
  react-markdown remark-gfm rehype-sanitize

Setup

1. Import the design tokens once

In your app's root entry (e.g. Next.js app/layout.tsx):

import "@onyx-ai/opal/styles.css";

The CSS file defines the custom properties (--text-01, --background-neutral-00, etc.) that the Tailwind preset references.

2. Wire up the Tailwind preset

In your tailwind.config.js:

module.exports = {
  presets: [require("@onyx-ai/opal/tailwind-preset")],
  content: [
    "./src/**/*.{ts,tsx}",
    "./node_modules/@onyx-ai/opal/dist/**/*.{js,mjs}",
  ],
};

The content glob ensures Tailwind picks up the classes used inside Opal components.

You also need to define the underlying CSS variables (--text-01, etc.) in your own colors.css or import a copy from Onyx. The preset references them but does not define them — they live with the consumer so the consumer controls the palette.

Usage

import { Button, Text } from "@onyx-ai/opal/components";
import { Content } from "@onyx-ai/opal/layouts";
import SvgPlus from "@onyx-ai/opal/icons/plus";

function MyComponent() {
  return (
    <Content
      icon={SvgPlus}
      title="Hello"
      description="World"
      sizePreset="main-ui"
      variant="section"
    />
  );
}

Subpath imports

| Subpath | Contents | | ------------------------------- | ---------------------------------------------------- | | @onyx-ai/opal/components | Buttons, Text, Tag, Tooltip, Popover, Table, etc. | | @onyx-ai/opal/layouts | Content, ContentAction, IllustrationContent, Section | | @onyx-ai/opal/core | Interactive primitives, Hoverable, Disabled | | @onyx-ai/opal/icons | SVG icon components | | @onyx-ai/opal/illustrations | Larger SVG illustrations | | @onyx-ai/opal/types | Shared types (RichStr, IconProps, etc.) | | @onyx-ai/opal/utils | cn, markdown helpers | | @onyx-ai/opal/styles.css | Bundled component CSS | | @onyx-ai/opal/tailwind-preset | Tailwind preset with tokens |

Structure

web/lib/opal/
├── src/
│   ├── core/             # Low-level primitives (Interactive, Hoverable, Disabled)
│   ├── components/       # High-level components (Button, Popover, Tooltip, Table, ...)
│   ├── layouts/          # Layout primitives (Content, ContentAction, Section, ...)
│   ├── icons/            # SVG icon components
│   ├── illustrations/    # Larger SVG illustrations
│   ├── logos/            # Brand / product logos
│   ├── types.ts          # Shared types (RichStr, IconProps, etc.)
│   ├── utils.ts          # cn, markdown helpers
│   ├── shared.ts
│   └── root.css          # Library-owned design tokens
├── scripts/
│   └── bundle-css.mjs    # Concatenates root.css + leaf component CSS into dist/styles.css
├── package.json
├── tsconfig.json         # Source typecheck config
├── tsconfig.build.json   # Used by tsup to emit dist/
├── tsup.config.ts
├── tailwind-preset.cjs
└── README.md

Local development (inside the Onyx repo)

Opal reuses /web/node_modules — it does not have its own node_modules. To add a runtime dependency, declare it under peerDependencies in web/lib/opal/package.json AND add the matching version in the root web/package.json dependencies block, then run npm i in /web so Onyx's web app keeps building.

The package is consumed by web/ as a workspace via web/package.json's "@onyx-ai/opal": "./lib/opal". During Onyx development, web/ resolves Opal source through the @opal/* TypeScript path alias (defined in web/tsconfig.json), so changes are picked up live without running npm run build.

To produce the published artifact:

cd web/lib/opal
npm run build       # tsup -> dist/, then bundle-css.mjs -> dist/styles.css

Releasing to npm

Releases go out through the Release Opal GitHub Actions workflow (.github/workflows/release-opal.yml). It uses npm OIDC Trusted Publishers — no NPM_TOKEN, signed provenance attestation. Pushing a tag is the only thing that triggers a release.

Steps:

  1. Bump version in web/lib/opal/package.json (semver: MAJOR.MINOR.PATCH, prerelease suffix -rc.N allowed).

  2. Open a PR with the version bump and any release-shaped changes. Merge it.

  3. From main, tag and push:

    git switch main && git pull
    git tag opal/v0.1.1
    git push origin opal/v0.1.1
  4. The workflow runs automatically on tag push. It builds (tsup + CSS barrel) and runs npm publish --provenance --access public. Watch the run under the Actions tab; verify the new version on https://www.npmjs.com/package/@onyx-ai/opal.

The tag pattern must match opal/v*.*.* for the workflow to fire.

Conventions

  • Component directories are kebab-case (e.g. select-button/, open-button/, content-action/).
  • Each component dir contains components.tsx, README.md, styles.css (when needed), and a <PascalName>.stories.tsx (when applicable).
  • Imports inside the lib use the @opal/ path alias; never @/.
  • Types/interfaces are declared at the top of components.tsx without export; everything is re-exported from a single export { Foo, type FooProps }; block at the bottom.
  • See web/AGENTS.md for broader frontend standards.