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.
npm install @taruvi/navkitA 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.




- 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
- 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
``bashClone or add as dependency
npm install @taruvi/navkit
$3
`tsx
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
}
export default App
`Development
$3
`bash
Start development server with HMR (Hot Module Replacement)
npm run devBuild for production (TypeScript check + Vite build)
npm run buildPreview production build locally
npm run previewRun ESLint for code quality
npm run lintTest Mattermost integration in isolation
npm run test:mattermost
`$3
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 buildUsage
$3
#### Standalone App Integration
`tsx
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 (
<>
{/ Your app content /}
>
)
}
`#### Taruvi Desk Integration
`tsx
import Navkit from '@taruvi/navkit'
import { useDesk } from '@taruvi-io/desk-sdk'function DeskApp() {
const { client } = useDesk()
return
}
`$3
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
$3
`
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
`$3
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$3
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`typescript
// 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`typescript
// Site settings without frontendUrl
{
frontendUrl: '', // or null/undefined
// ... other settings
}
`#### Navigation Hook
`typescript
import { useNavigation } from './NavkitContext'// In any child component
function MyComponent() {
const { navigateToUrl, isDesk, siteSettings } = useNavigation()
// Automatically detects mode and navigates appropriately
navigateToUrl('/app-name')
}
`$3
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
`typescript
// Conditional rendering based on breakpoint
{userData.fullName}
// 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
$3
The component expects the following settings from the SDK:
`typescript
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
}
]
}
`$3
`typescript
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: 'john.doe@taruvi.io'
}
`$3
`typescript
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:
- envelope → fa-envelope
- calendar → fa-calendar
- home → fa-home
- cog → fa-cogSee FontAwesome Free Icons for available icons.
Styling
$3
Navkit uses a centralized design system with design tokens in src/styles/variables.ts:
#### Color Palette
`typescript
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
`typescript
spacing = {
xs: '10px', // Extra small
sm: 1.5, // Small (12px with MUI 8px base)
md: 2, // Medium (16px)
lg: 3, // Large (24px)
}
`#### Typography
`typescript
typography = {
sizes: {
xs: '0.8125rem', // 13px
sm: '0.875rem', // 14px
md: '1.125rem', // 18px
},
weights: {
regular: 400,
semibold: 600,
},
}
`#### Dimensions
`typescript
dimensions = {
navHeight: '60px',
avatarSize: 40,
iconSize: {
sm: '18px',
md: '24px',
lg: '1.25rem',
},
}
`$3
#### 1. Component-Specific Styles
Each component has a
.styles.ts file:`typescript
// 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:`typescript
// 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:
`tsx
import { createTheme, ThemeProvider } from '@mui/material/styles'const theme = createTheme({
palette: {
primary: {
main: '#1976d2',
},
},
})
function App() {
return (
)
}
`Tech Stack
$3
| 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 |
$3
| 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 |
$3
| 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 |
$3
- 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
$3
#### 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
$3
#### State Management
`typescript
// 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(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 |
$3
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 optimizationBrowser 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
$3
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
$3
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
$3
#### 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`typescript
// 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`bash
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`typescript
// 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)`typescript
// Debug icon
// Correct
// Wrong
``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
Internal Taruvi project - All rights reserved
- Comprehensive ADR - Complete architectural decisions and rationale
- ADR 001: Navkit Architecture - Detailed component architecture
- Future Considerations - Planned enhancements
| 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 |
- React 19 Documentation
- Material-UI Documentation
- Vite Documentation
- TypeScript Handbook
- FontAwesome Icons
For issues, questions, or feature requests, contact the Taruvi development team.