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

@properui/ui

v0.2.0

Published

Accessible React 19 component library built on React Aria Components and Tailwind CSS v4, shipped as source TSX.

Readme

@properui/ui

An accessible React 19 component library: base primitives, application patterns, marketing sections and whole page examples, built on React Aria Components and Tailwind CSS v4, typed with strict TypeScript.

The package ships source TSX: no bundled build. Your app's compiler sees the same code the library authors do, so tree-shaking, source maps and "go to definition" all work, and Tailwind can scan real class names. In exchange, your bundler has to be told to compile it (one line in Next.js, nothing in Vite: see below).

src/components/base/                primitives (buttons, inputs, badges, ...)
src/components/application/         app patterns (tables, modals, navigation, charts, ...)
src/components/marketing/           marketing sections (heroes, pricing, footers, ...)
src/components/app-examples/        whole app pages (dashboards, settings, login, ...)
src/components/marketing-examples/  whole marketing pages (landing, pricing, blog, ...)
src/components/foundations/         featured icons, logo, social/payment icons, rating
src/components/shared-assets/       background patterns, illustrations, mockups
src/hooks  src/utils  src/providers  src/styles

Install

pnpm add @properui/ui
# or: npm install @properui/ui / yarn add @properui/ui

Peer dependencies: react ^19, react-dom ^19, tailwindcss ^4.3. next ^15.1 is an optional peer: only @properui/ui/providers/router-provider needs it.

Prefer to own the code instead of depending on the package? The CLI copies components straight into your project, shadcn-style:

npx @properui/cli@latest init
npx @properui/cli@latest add button input select

Setup: Next.js (App Router)

1. Transpile the package (it ships TSX, not compiled JS):

// next.config.ts
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
    transpilePackages: ["@properui/ui"],
};

export default nextConfig;

2. Import the styles and let Tailwind scan the package in app/globals.css:

@import "@properui/ui/styles/globals.css";
@source "../node_modules/@properui/ui/src/**/*.{ts,tsx}";

globals.css pulls in Tailwind, the design tokens (theme.css), the typography layer and the plugins the components rely on. Adjust the @source path so it resolves to node_modules from that CSS file (in a monorepo it is usually ../../node_modules/...).

3. Wrap the app in the providers:

// app/layout.tsx
import { ThemeProvider } from "@properui/ui/providers";
import { RouterProvider } from "@properui/ui/providers/router-provider";
import "./globals.css";

export default function RootLayout({ children }: { children: React.ReactNode }) {
    return (
        <html lang="en" suppressHydrationWarning>
            <body>
                <ThemeProvider>
                    <RouterProvider>{children}</RouterProvider>
                </ThemeProvider>
            </body>
        </html>
    );
}

ThemeProvider puts .light-mode / .dark-mode on <html>. Every semantic token keys off those. RouterProvider wires React Aria's navigation to the Next.js router, so any component that takes href does a client-side transition.

Setup: Vite

pnpm add @properui/ui @tailwindcss/vite
// vite.config.ts
import tailwindcss from "@tailwindcss/vite";
import react from "@vitejs/plugin-react";
import { defineConfig } from "vite";

export default defineConfig({
    plugins: [react(), tailwindcss()],
    // Only needed if you render on the server: keeps the TSX source in the
    // build pipeline instead of externalising it.
    ssr: { noExternal: ["@properui/ui"] },
});
/* src/index.css */
@import "@properui/ui/styles/globals.css";
@source "../node_modules/@properui/ui/src/**/*.{ts,tsx}";
// src/main.tsx
import { createRoot } from "react-dom/client";
import { ThemeProvider } from "@properui/ui/providers";
import App from "./App";
import "./index.css";

createRoot(document.getElementById("root")!).render(
    <ThemeProvider>
        <App />
    </ThemeProvider>,
);

RouterProvider is Next.js-only. On Vite, use React Aria's own RouterProvider from react-aria-components with your router's navigate function.

First component

Import from the root barrel, or from a subpath if you want only what you use:

import { Button } from "@properui/ui/components/base/buttons/button";

// or: import { Button } from "@properui/ui";

export function SaveBar() {
    return (
        <div className="flex gap-3">
            <Button color="secondary" size="md">
                Cancel
            </Button>
            <Button color="primary" size="md" onPress={() => console.log("saved")}>
                Save changes
            </Button>
        </div>
    );
}

Interactive components are React Aria based, so use onPress rather than onClick and isDisabled rather than disabled. Keyboard behaviour, focus management, ARIA wiring and RTL come for free, and each component is covered by unit tests plus axe assertions.

Theming

The design tokens live in src/styles/theme.css as a Tailwind v4 @theme block. Re-branding means overriding the eleven --color-brand-* steps in your own CSS after the import. Every semantic token (bg-brand-solid, text-brand-secondary, ...) cascades from them, in light and dark:

@import "@properui/ui/styles/globals.css";

@theme {
    --color-brand-500: rgb(56 189 248);
    --color-brand-600: rgb(2 132 199);
    --color-brand-700: rgb(3 105 161);
    /* ...the remaining brand steps */
}

Dark mode is class-based (.dark-mode on <html>), driven by ThemeProvider (built on next-themes); useTheme is re-exported from @properui/ui/providers for a theme toggle.

License

MIT © Ayman Shabaro. See LICENSE.

Portions of the component library are derived from the MIT-licensed Untitled UI React project; see the NOTICE and LICENSES/ files in the repository root.