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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@jmruthers/pace-core

v0.6.2

Published

Clean, modern React component library with Tailwind v4 styling and native utilities

Readme

@jmruthers/pace-core

Clean, modern React component library with Tailwind v4 styling and native utilities.

⚠️ Breaking Changes

Version 0.5.65+ - Mandatory Inactivity Timeouts

The UnifiedAuthProvider now requires mandatory inactivity timeout configuration for security:

// ❌ Before (will cause TypeScript errors)
<UnifiedAuthProvider supabaseClient={supabase} appName="my-app">
  <AppContent />
</UnifiedAuthProvider>

// ✅ After (required configuration)
<UnifiedAuthProvider 
  supabaseClient={supabase} 
  appName="my-app"
  idleTimeoutMs={30 * 60 * 1000}  // Required
  warnBeforeMs={5 * 60 * 1000}    // Required
  onIdleLogout={() => navigate('/login')}  // Required
>
  <AppContent />
</UnifiedAuthProvider>

📖 Migration Guide

🚀 PaceAppLayout Usage

PaceAppLayout uses React Router's nested routing pattern for optimal performance and scalability.

// ✅ Correct usage with React Router
<Router>
  <Routes>
    <Route path="/" element={<PaceAppLayout appName="My App" />}>
      <Route path="dashboard" element={<Dashboard />} />
      <Route path="settings" element={<Settings />} />
    </Route>
  </Routes>
</Router>

📦 Type System

PACE Core uses a domain-driven type organization for better maintainability and discoverability:

// Import from domain-specific modules
import type { Event } from '@jmruthers/pace-core/types/event';
import type { Organisation } from '@jmruthers/pace-core/types/organisation';
import type { User, Session } from '@jmruthers/pace-core/types/auth';
import type { UserId, AppId, PageId } from '@jmruthers/pace-core/types/core';
import type { RBACPermissionCheckParams } from '@jmruthers/pace-core/rbac/types/functions';

See the Types API Reference for complete type documentation.

🚀 Complete Installation Guide

1. Install Dependencies

# Install pace-core and required peer dependencies
npm install @jmruthers/pace-core @tanstack/react-table @radix-ui/react-checkbox @radix-ui/react-dialog @radix-ui/react-dropdown-menu @radix-ui/react-label @radix-ui/react-slot lucide-react class-variance-authority clsx tailwind-merge

# Install Tailwind CSS v4 and Vite plugin
npm install -D @tailwindcss/vite tailwindcss@^4.0.0

2. Import Core Styles

// src/main.tsx (or your app's entry point)
import '@jmruthers/pace-core/src/styles/core.css';
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

// React 19+ with createRoot
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

3. Configure Vite with Tailwind v4

⚠️ CRITICAL: This configuration is required for:

  1. Tailwind CSS scanning - Ensures components are styled
  2. React context consistency - Prevents "useUnifiedAuth must be used within a UnifiedAuthProvider" errors
  3. Router context availability - Prevents "useNavigate() may be used only in the context of a " errors
// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'
import path from 'path'

export default defineConfig({
  plugins: [
    react({
      // React Compiler for automatic optimizations (React 19+)
      babel: {
        plugins: ['babel-plugin-react-compiler'],
      },
    }),
    tailwindcss({
      // Only need to scan your app's source files
      // pace-core source files are automatically scanned via @source directives
      content: [
        './src/**/*.{js,ts,jsx,tsx}'
      ]
    })
  ],
  resolve: {
    alias: {
      "@": path.resolve(__dirname, "./src"),
    },
    // CRITICAL: Dedupe React and React Router to ensure single instances
    // This prevents Router context issues when pace-core uses react-router-dom
    dedupe: ['react', 'react-dom', 'react-router-dom']
  },
  // CRITICAL: Exclude pace-core from pre-bundling to prevent React context mismatches
  // Pre-bundling creates separate React instances, causing context errors
  optimizeDeps: {
    include: [
      'react',
      'react-dom',
      'react/jsx-runtime',
      '@radix-ui/react-slot'
    ],
    // CRITICAL: Exclude pace-core from pre-bundling
    // This ensures pace-core uses the same React instance as your app
    // NOTE: react-router-dom should be INCLUDED, not excluded (excluding causes "module is not defined" errors)
    exclude: ['@jmruthers/pace-core']
  },
  server: {
    port: 3000,
    open: true,
  },
  build: {
    outDir: 'dist',
    sourcemap: true,
  },
})

Fallback Configuration: If the CSS-first approach doesn't work, you can explicitly include pace-core source files:

// vite.config.ts - Fallback configuration
export default defineConfig({
  plugins: [
    react(),
    tailwindcss({
      content: [
        './src/**/*.{js,ts,jsx,tsx}',
        './node_modules/@jmruthers/pace-core/src/**/*.{js,ts,jsx,tsx}'
      ]
    })
  ],
  // ... rest of config
})

4. Verify Installation

Create a test component to ensure everything works:

// src/App.tsx
import { Button, Card, Input } from '@jmruthers/pace-core';

function App() {
  return (
    <div className="p-8 space-y-4">
      <h1 className="text-2xl font-bold text-main-900">PACE Core Test</h1>
      
      <Card className="p-4">
        <h2 className="text-lg font-semibold text-sec-800 mb-2">Components Test</h2>
        <div className="space-y-2">
          <Button variant="primary" className="bg-main-600 text-main-50">
            Primary Button
          </Button>
          <Button variant="secondary" className="bg-sec-500 text-main-50">
            Secondary Button
          </Button>
          <Input placeholder="Test input field" className="border-main-300" />
        </div>
      </Card>
    </div>
  );
}

export default App;

Expected Result: You should see properly styled components with PACE Core's design system colors and typography.

⚠️ Critical Configuration Notes

Why Source File Scanning is Required

Pace-core v0.4.15+ includes source files in the published package because:

  • Tailwind v4 needs to scan original TypeScript/JSX files to detect utility classes
  • Compiled JavaScript files don't contain the class names Tailwind needs
  • Without proper scanning, only ~292 CSS rules are generated instead of 800+ needed

Alternative Configuration (if source files don't work)

If you're still having issues with component scanning:

// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'

export default defineConfig({
  plugins: [
    react(),
    tailwindcss({
      content: [
        './src/**/*.{js,ts,jsx,tsx}',
        // Try source files first
        './node_modules/@jmruthers/pace-core/src/**/*.{js,ts,jsx,tsx}',
        // Fallback: also scan dist files
        './node_modules/@jmruthers/pace-core/dist/**/*.{js,ts,jsx,tsx}'
      ]
    })
  ],
})

Legacy Configuration (v0.4.14 and below)

For older versions, use this configuration:

// vite.config.ts
export default defineConfig({
  plugins: [
    react(),
    tailwindcss({
      content: [
        './src/**/*.{js,ts,jsx,tsx}',
        './node_modules/@jmruthers/pace-core/**/*.{js,ts,jsx,tsx}'
      ]
    })
  ],
})

🔍 Troubleshooting

Issue: "useUnifiedAuth must be used within a UnifiedAuthProvider"

Cause: Vite is pre-bundling @jmruthers/pace-core, creating separate React instances

Solution:

  1. Add to vite.config.ts:
    optimizeDeps: {
      exclude: ['@jmruthers/pace-core', 'react-router-dom']
    }
  2. Clear Vite cache: rm -rf node_modules/.vite
  3. Restart dev server

Issue: "useNavigate() may be used only in the context of a component"

Cause: Incorrect provider nesting - BrowserRouter should wrap UnifiedAuthProvider

Solution:

  1. Ensure correct nesting order in main.tsx:
    <QueryClientProvider>
      <BrowserRouter>
        <UnifiedAuthProvider>
          <OrganisationProvider>
            <App />
          </OrganisationProvider>
        </UnifiedAuthProvider>
      </BrowserRouter>
    </QueryClientProvider>
  2. Do NOT put BrowserRouter inside UnifiedAuthProvider
  3. Add to vite.config.ts:
    resolve: {
      dedupe: ['react', 'react-dom', 'react-router-dom']
    }

Issue: Only 292 CSS rules instead of 800+

Solution:

  1. Update to pace-core v0.4.15+
  2. Use source file paths: ./node_modules/@jmruthers/pace-core/src/**/*.{js,ts,jsx,tsx}
  3. Clear build cache: rm -rf dist .vite node_modules && npm install

Issue: Components appear unstyled

Solution:

  1. Check your Vite configuration includes pace-core source files
  2. Ensure CSS file is imported: import '@jmruthers/pace-core/src/styles/core.css'
  3. Restart dev server after configuration changes

Issue: Build errors with source files

Solution: Add TypeScript configuration for node_modules:

// tsconfig.json
{
  "compilerOptions": {
    "skipLibCheck": true
  }
}

Issue: "Access Denied" errors with valid permissions

Problem: Users with valid permissions see "Access Denied" when loading pages with DataTable components.

Root Cause: Race condition in permission checking - useCan hook was being called with invalid scopes before scope resolution completed.

Solution: Fixed in v0.5.7+ - the useCan hook now properly handles invalid scopes and shows loading state until valid scope is available.

What was fixed:

  • useCan hook skips API calls when organisationId is empty
  • PagePermissionGuard shows loading state during scope resolution
  • Eliminates race condition between scope resolution and permission checking

No action needed - this is automatically fixed in v0.5.7+

Features

  • 🎨 Complete Design System - Colors, typography, spacing, shadows
  • 🧩 React Components - Buttons, inputs, cards, data tables, and more
  • 🔐 RBAC System - Role-based access control with Supabase
  • 🎨 Tailwind v4 - CSS-first approach with design tokens
  • 📱 Responsive - Mobile-first design patterns
  • Accessible - WCAG compliant components
  • 🚀 Performance - Tree-shakeable, optimized bundle

Documentation

Import Strategy

PACE Core provides two import paths to optimize for different use cases:

Main Export (Recommended for Common Components)

Use the main export for frequently used components and utilities:

import { 
  Button, 
  Card, 
  Input, 
  DropdownMenu, 
  Select, 
  Dialog,
  useUnifiedAuth 
} from '@jmruthers/pace-core';

Available from main export:

  • Basic UI: Button, Card, Input, Textarea, Label, Alert, Avatar, Checkbox, Progress
  • Advanced UI: Dialog (with HTML content), DropdownMenu, Select, Toast, Tooltip, Tabs, Calendar
  • Data Display: DataTable (with hierarchical actions & expand/collapse all), Table
  • Forms: Form, LoginForm
  • Layout: PaceAppLayout, Header, Footer, NavigationMenu
  • Providers: UnifiedAuthProvider, OrganisationProvider, EventProvider
  • Hooks: useUnifiedAuth, useOrganisations, useEvents

Component Documentation

  • DataTable Component - Enterprise-grade data table with hierarchical rows, expand/collapse all, actions, sorting, filtering, and performance optimization
  • Dialog Component - Comprehensive dialog system with smart height management, scrolling, HTML content rendering, and accessibility features
  • Storage System - File storage utilities with organization-scoped access control

Complete Components Export (For Specialized Components)

Use the complete export for specialized or advanced components:

import { 
  DataTable, 
  NavigationMenu,
  FormField
} from '@jmruthers/pace-core/components';

License

MIT License - see LICENSE for details.