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

@taruvi/navkit

v0.0.10

Published

A modern, responsive, and highly performant navigation bar component library for the Taruvi ecosystem. Built with React 19, TypeScript, and Material-UI with automatic optimizations via React Compiler.

Readme

Taruvi Navkit

A modern, responsive, and highly performant navigation bar component library for the Taruvi ecosystem. Built with React 19, TypeScript, and Material-UI with automatic optimizations via React Compiler.

React TypeScript Vite Material-UI

Features

Core Components

  • App Launcher: Grid-based application launcher with real-time search and filtering
  • Smart Shortcuts: Quick access shortcuts with responsive desktop/mobile views and hamburger menu on mobile
  • User Profile: Avatar-based profile menu with preferences access and logout functionality
  • Mattermost Chat Integration: Embedded chat modal with JWT authentication and external link option
  • Click-Outside Detection: Intelligent menu closing with mutually exclusive dropdown behavior

Technical Highlights

  • Responsive Design: Mobile-first approach with strategic breakpoints (900px for desktop)
  • Smart Navigation: Context-aware navigation system (desk mode vs external mode)
  • Type-Safe: Full TypeScript support with strict mode enabled
  • Optimized Performance: React Compiler with automatic memoization + manual optimizations
  • Modern React: Leverages React 19 features (startTransition, concurrent rendering)
  • Design System: Centralized design tokens for consistent theming
  • Accessibility: MUI components with built-in ARIA attributes and keyboard navigation

Quick Start

Installation

# Clone or add as dependency
npm install @taruvi/navkit

# Install peer dependencies
npm install @mui/material @emotion/react @emotion/styled
npm install @fortawesome/fontawesome-svg-core @fortawesome/free-solid-svg-icons @fortawesome/free-regular-svg-icons @fortawesome/react-fontawesome

Basic Setup

import Navkit from '@taruvi/navkit'
import { TaruviClient } from '@taruvi-io/sdk'

function App() {
  const client = new TaruviClient({
    apiUrl: 'https://api.taruvi.io',
    // ... other config
  })

  return <Navkit client={client} />
}

export default App

Development

Development Scripts

# Start development server with HMR (Hot Module Replacement)
npm run dev

# Build for production (TypeScript check + Vite build)
npm run build

# Preview production build locally
npm run preview

# Run ESLint for code quality
npm run lint

# Test Mattermost integration in isolation
npm run test:mattermost

Development Workflow

  1. Make changes to source files in src/
  2. See updates instantly with Vite's Fast Refresh (HMR)
  3. Type-check automatically via TypeScript in your IDE
  4. Lint before commit with npm run lint
  5. Build before deploy with npm run build

Usage

Integration Patterns

Standalone App Integration

import Navkit from '@taruvi/navkit'
import { TaruviClient } from '@taruvi-io/sdk'

function App() {
  const client = new TaruviClient({
    apiUrl: process.env.VITE_API_URL,
    tenantId: process.env.VITE_TENANT_ID,
  })

  return (
    <>
      <Navkit client={client} />
      <main>{/* Your app content */}</main>
    </>
  )
}

Taruvi Desk Integration

import Navkit from '@taruvi/navkit'
import { useDesk } from '@taruvi-io/desk-sdk'

function DeskApp() {
  const { client } = useDesk()

  return <Navkit client={client} />
}

Client Object Requirements

The client prop expects an object compatible with @taruvi-io/sdk that provides:

  • User class for user data and apps

    • getApps(): Fetch available applications
    • getData(): Fetch user profile data (fullName, pfp, username, email)
  • Settings class for site configuration

    • get(): Fetch site settings (logo, frontendUrl, mattermostUrl, shortcuts)
  • Auth class for authentication

    • isUserAuthenticated(): Check authentication status
    • JWT token management (future)

Architecture

Component Structure

Navkit (App.tsx)
├── NavkitProvider (NavkitContext) - React Context for global state
│   ├── State: appsList, userData, isUserAuthenticated, jwtToken, isDesk
│   ├── Refs: siteSettings, user, settings (SDK instances)
│   └── Functions: navigateToUrl, getData, authenticateUser
├── NavkitContent - Main UI component
    ├── AppLauncher - App grid with search
    ├── Profile - User avatar and name
    │   └── ProfileMenu - Preferences and logout
    ├── Shortcuts - Quick action icons
    │   └── ShortcutsMenu - Mobile dropdown
    └── MattermostChat - Chat modal

State Management

Navkit uses React Context API for centralized state management:

  • NavigationContext - Centralized provider for all app state and navigation logic
  • useNavigation hook - Custom hook for consuming context in child components
  • Separate state variables for granular updates (reduces unnecessary re-renders)
  • useRef for SDK instances and siteSettings to prevent re-renders
  • startTransition for batching multiple state updates on initial load (6+ renders → 1 render)
  • BroadcastChannel for cross-tab synchronization (refreshes on profile updates)
  • React Compiler for automatic memoization and optimization

Performance Optimizations

  • Initial render count reduced from 6+ to 1 via startTransition
  • SDK instances and siteSettings in refs prevent re-renders
  • Separate state variables allow granular component updates
  • React Compiler automatically memoizes components and callbacks
  • BroadcastChannel enables real-time updates across tabs

Navigation Modes

Navkit intelligently handles navigation based on context:

1. Desk Mode (when frontendUrl is set)

  • When: Running inside Taruvi Desk application
  • Behavior: Relative navigation within the app
  • Examples:
    • https://app.taruvi.io/mail → navigates to /mail
    • /preferences → navigates to /preferences
  • Detection: Checks if window.location.href includes frontendUrl
// Site settings with frontendUrl
{
  frontendUrl: 'https://desk.taruvi.io',
  // ... other settings
}

2. External Mode (no frontendUrl)

  • When: Running in standalone app or frontendUrl not set
  • Behavior: Opens URLs in new tab
  • Examples:
    • https://mail.taruvi.io → opens in new tab
    • https://external-app.com → opens in new tab
  • Purpose: Prevents navigating away from host application
// Site settings without frontendUrl
{
  frontendUrl: '', // or null/undefined
  // ... other settings
}

Navigation Hook

import { useNavigation } from './NavkitContext'

// In any child component
function MyComponent() {
  const { navigateToUrl, isDesk, siteSettings } = useNavigation()

  // Automatically detects mode and navigates appropriately
  navigateToUrl('/app-name')
}

Responsive Breakpoints

Navkit uses a mobile-first responsive design strategy:

Mobile (xs): < 900px

  • User name: Hidden (avatar only)
  • Shortcuts: Hamburger menu dropdown
  • App launcher: Full-width (95vw)
  • Touch targets: Minimum 44x44px
  • Optimizations: Reduced clutter for small screens

Desktop (md+): ≥ 900px

  • User name: Visible next to avatar
  • Shortcuts: Inline horizontal layout
  • App launcher: Fixed width (600px)
  • Enhanced UX: More information density

Implementation Example

// Conditional rendering based on breakpoint
<Typography sx={{ display: { xs: 'none', md: 'block' } }}>
  {userData.fullName}
</Typography>

// Responsive dimensions
container: {
  width: { xs: '95vw', sm: '80vw', md: '70vw', lg: '600px' },
  height: { xs: '90vh', md: '80vh' },
}

Testing Breakpoints

Test the following widths for complete coverage:

  • 320px: Minimum mobile (iPhone SE)
  • 768px: Tablet
  • 900px: Breakpoint threshold
  • 1024px: Small desktop
  • 1920px: Large desktop

Configuration

Site Settings

The component expects the following settings from the SDK:

interface SiteSettings {
  logo: string              // Navigation bar logo URL
  frontendUrl: string      // Base URL for desk mode navigation (optional)
  mattermostUrl: string    // Mattermost server URL (optional)
  shortcuts: AppData[]     // Quick action shortcuts
}

// Example
{
  logo: 'https://cdn.taruvi.io/logo.png',
  frontendUrl: 'https://desk.taruvi.io',
  mattermostUrl: 'https://chat.taruvi.io',
  shortcuts: [
    {
      id: '1',
      appname: 'Mail',
      icon: 'envelope',
      url: '/mail'
    },
    {
      id: '2',
      appname: 'Calendar',
      icon: 'calendar',
      url: '/calendar'
    },
    {
      id: '3',
      appname: 'Chat',
      icon: 'comments',
      url: '#' // Special handling for chat
    }
  ]
}

User Data

interface UserData {
  fullName: string         // Full display name
  pfp: string             // Profile picture URL
  username: string        // Username or handle
  email: string          // User email address
}

// Example
{
  fullName: 'John Doe',
  pfp: 'https://cdn.taruvi.io/avatars/johndoe.jpg',
  username: 'johndoe',
  email: '[email protected]'
}

App Data

interface AppData {
  id: string              // Unique app identifier
  appname: string        // Display name
  icon: string           // FontAwesome icon name (without 'fa-' prefix)
  url: string           // App URL or path
}

// Example
{
  id: 'app-mail-001',
  appname: 'Mail',
  icon: 'envelope',        // Renders as fa-envelope
  url: 'https://mail.taruvi.io'
}

FontAwesome Icon Names

Icons use FontAwesome Free icon names without the fa- prefix:

  • envelopefa-envelope
  • calendarfa-calendar
  • homefa-home
  • cogfa-cog

See FontAwesome Free Icons for available icons.

Styling

Design System

Navkit uses a centralized design system with design tokens in src/styles/variables.ts:

Color Palette

colours = {
  text: {
    primary: '#333333',    // Main text
    secondary: '#424242',  // Secondary text
    tertiary: '#9e9e9e',  // Disabled/subtle text
  },
  bg: {
    white: '#fff',        // White background
    light: '#f5f5f5',    // Light grey background
    avatar: '#E0E0E0',   // Avatar placeholder
  },
  border: {
    light: '#e0e0e0',    // Border color
  },
}

Spacing Scale

spacing = {
  xs: '10px',  // Extra small
  sm: 1.5,     // Small (12px with MUI 8px base)
  md: 2,       // Medium (16px)
  lg: 3,       // Large (24px)
}

Typography

typography = {
  sizes: {
    xs: '0.8125rem',  // 13px
    sm: '0.875rem',   // 14px
    md: '1.125rem',   // 18px
  },
  weights: {
    regular: 400,
    semibold: 600,
  },
}

Dimensions

dimensions = {
  navHeight: '60px',
  avatarSize: 40,
  iconSize: {
    sm: '18px',
    md: '24px',
    lg: '1.25rem',
  },
}

Customization Options

1. Component-Specific Styles

Each component has a .styles.ts file:

// Profile.styles.ts
import { colours, spacing, typography } from '../../styles/variables'

export const profileStyles = {
  userName: {
    fontSize: typography.sizes.sm,
    color: colours.text.primary,
    padding: spacing.xs,
  }
}

2. Design Tokens

Modify src/styles/variables.ts for global changes:

// Change primary text color globally
export const colours = {
  text: {
    primary: '#000000',  // Darker text
    // ...
  }
}

3. MUI Theme Provider

Wrap Navkit with MUI ThemeProvider for advanced theming:

import { createTheme, ThemeProvider } from '@mui/material/styles'

const theme = createTheme({
  palette: {
    primary: {
      main: '#1976d2',
    },
  },
})

function App() {
  return (
    <ThemeProvider theme={theme}>
      <Navkit client={client} />
    </ThemeProvider>
  )
}

Tech Stack

Core Dependencies

| Package | Version | Purpose | |---------|---------|---------| | React | 19.1.1 | UI framework with concurrent features | | React DOM | 19.1.1 | DOM rendering | | TypeScript | ~5.9.3 | Type safety and developer experience |

Peer Dependencies

| Package | Version | Purpose | |---------|---------|---------| | @mui/material | ^5.0.0 | UI component library | | @emotion/react | ^11.0.0 | CSS-in-JS (MUI dependency) | | @emotion/styled | ^11.0.0 | Styled components (MUI dependency) | | @fortawesome/fontawesome-svg-core | ^6.0.0 | Icon library core | | @fortawesome/free-solid-svg-icons | ^6.0.0 | Solid icons | | @fortawesome/free-regular-svg-icons | ^6.0.0 | Regular icons | | @fortawesome/react-fontawesome | ^0.2.0 | React icon components | | @taruvi-io/sdk | latest | Taruvi SDK for API integration |

Development Dependencies

| Package | Version | Purpose | |---------|---------|---------| | Vite | 7.1.7 | Build tool and dev server | | @vitejs/plugin-react | ^5.0.4 | Vite React plugin | | babel-plugin-react-compiler | ^19.1.0-rc.3 | Automatic optimizations | | ESLint | ^9.36.0 | Code linting | | typescript-eslint | ^8.45.0 | TypeScript ESLint support |

Why These Choices?

  • React 19: Latest features (startTransition, concurrent rendering)
  • Vite: Fast HMR (< 100ms), optimized builds
  • MUI: Accessible, responsive, well-maintained
  • TypeScript: Catch errors at compile time
  • React Compiler: Automatic performance optimizations

Performance Optimizations

Automatic Optimizations

React Compiler

  • Automatic memoization of components and values
  • Callback stabilization without manual useCallback
  • Reduced re-renders through intelligent optimization
  • No boilerplate (no manual useMemo, React.memo)

Vite Build Pipeline

  • Code splitting: Automatic chunking for optimal loading
  • Tree shaking: Removes unused code in production
  • Minification: Terser for JavaScript, CSS minification
  • Fast Refresh: Sub-second HMR during development

Manual Optimizations

State Management

// Separate state variables for granular updates
const [showAppLauncher, setShowAppLauncher] = useState(false)
const [showProfileMenu, setShowProfileMenu] = useState(false)

// useRef for SDK instances (no re-renders)
const settings = useRef<any>(null)

// startTransition for batched updates
startTransition(() => {
  setAppsList(apps)
  setUserData(userData)
  setSiteSettings(settings)
})

Performance Metrics

| Metric | Value | Target | |--------|-------|--------| | Initial renders | 1 | < 3 | | Bundle size (gzipped) | ~150KB | < 200KB | | Time to Interactive | < 1s | < 2s | | First Contentful Paint | < 500ms | < 1s |

Best Practices

  1. Avoid unnecessary renders: Separate state variables
  2. Batch updates: Use startTransition for multiple state changes
  3. Stable references: Use useRef for non-rendering data
  4. Trust the compiler: Let React Compiler handle optimization

Browser Support

Modern browsers with ES2020+ support:

  • Chrome/Edge 88+
  • Firefox 78+
  • Safari 14+

Project Structure

taruvi-navkit/
├── docs/
│   └── adr/                    # Architecture Decision Records
│       └── 001-navkit-architecture.md
├── src/
│   ├── components/
│   │   ├── AppLauncher/
│   │   ├── Profile/
│   │   ├── Shortucts/
│   │   ├── Search/
│   │   └── MattermostChat/
│   ├── styles/
│   │   └── variables.ts        # Design tokens
│   ├── NavkitContext.tsx       # React Context provider & hook
│   ├── App.tsx                 # Main Navkit component
│   ├── App.styles.ts
│   └── types.ts                # TypeScript interfaces
├── package.json
├── tsconfig.json
├── vite.config.ts
└── README.md

Build Configuration

Vite

The project uses Vite 7 with:

  • @vitejs/plugin-react for Fast Refresh
  • babel-plugin-react-compiler for automatic optimizations
  • HMR (Hot Module Replacement) enabled
  • TypeScript support out of the box

TypeScript

Strict mode enabled with:

  • noImplicitAny: Require explicit types
  • strictNullChecks: Catch null/undefined errors
  • esModuleInterop: Better module compatibility

Contributing

  1. Follow the existing code style
  2. Use TypeScript for all new files
  3. Add/update ADRs for architectural decisions
  4. Test responsive behavior on mobile and desktop
  5. Ensure no console errors or warnings

Troubleshooting

Common Issues

Navigation not working

Symptoms: Clicks don't navigate, URLs incorrect

Solutions:

  • Ensure frontendUrl is set in site settings for desk mode
  • Check that URLs are valid (full URLs or relative paths starting with /)
  • Verify SDK settings instance is being passed correctly
  • Check console for navigation errors
// Debug navigation
console.log('Settings:', await settings.get())
console.log('Is Desk?', await isDesk(settings))

Styles not applying

Symptoms: Components look unstyled or broken

Solutions:

  • Check that MUI is installed as a peer dependency: npm list @mui/material
  • Verify design tokens are imported in component styles
  • Ensure sx prop is used (not style)
  • Check for CSS conflicts from parent app
# Verify MUI installation
npm list @mui/material @emotion/react @emotion/styled

Click-outside not working

Symptoms: Menus don't close when clicking outside

Solutions:

  • Check that menus have proper refs assigned
  • Verify useEffect dependencies include all show* states
  • Ensure no other click handlers are interfering with event propagation
  • Check that menuRef is attached to menu container

App launcher empty

Symptoms: No apps showing in launcher

Solutions:

  • Verify user.getApps() returns data
  • Check console for API errors
  • Ensure apps have required fields: id, appname, icon, url
  • Test with mock data to isolate issue
// Debug apps data
console.log('Apps:', await user.current.getApps())

Icons not showing

Symptoms: Icons appear as boxes or missing

Solutions:

  • Verify FontAwesome packages installed
  • Check icon names match FontAwesome free icons
  • Ensure library.add(fas, far) is called
  • Use correct icon name format (without fa- prefix)
// Debug icon
<FontAwesomeIcon icon={["fas", "envelope"]} />  // Correct
<FontAwesomeIcon icon={["fas", "fa-envelope"]} />  // Wrong

Getting Help

  1. Check the ADR documentation for architecture details
  2. Review existing ADRs for design decisions
  3. Enable verbose logging in development
  4. Contact the Taruvi development team for support

License

Internal Taruvi project - All rights reserved

Documentation

Architecture Decision Records (ADRs)

Key Documentation Sections

| Topic | Location | |-------|----------| | Technology stack decisions | adr.md - Tech Stack | | State management strategy | adr.md - State Management | | Navigation system | adr.md - Navigation System | | Responsive design | adr.md - Responsive Design | | Performance optimizations | adr.md - Performance | | Component architecture | docs/adr/001 |

External Resources

Support

For issues, questions, or feature requests, contact the Taruvi development team.