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

@bernierllc/in-app-chat

v2.2.0

Published

A generic, role-based in-app chat system for Next.js applications

Readme

@bernierllc/in-app-chat

A comprehensive, role-based in-app chat suite for Next.js applications with external platform integrations and slash command routing. This package provides a complete messaging solution that can be easily integrated into any Next.js application with support for Slack, Discord, Teams, and dynamic slash commands via NeverHub service discovery.

Note: Roles are fully configurable. You can use any string for roles (e.g., 'user', 'admin', 'moderator', 'customer', etc.) and configure permissions as needed. No roles are hardcoded.

Features

  • 🎯 Role-based messaging - Different interfaces and features for different user types
  • 🔒 Secure communication - Encrypted message IDs and access validation
  • Real-time updates - Live message delivery and status updates
  • 📎 File attachments - Support for documents and media sharing
  • 📝 Message templates - Role-specific pre-written messages
  • 📨 Bulk messaging - Send messages to multiple recipients
  • 🔍 Search and filtering - Advanced conversation management
  • 📱 Responsive design - Works on desktop and mobile
  • Accessibility - WCAG 2.1 AA compliant
  • 🎨 Customizable - Easy to theme and extend
  • 🚀 External Integrations - Slack, Discord, Teams bridging with user mapping
  • Slash Commands - Dynamic command routing via NeverHub service discovery
  • 🔧 Live Configuration - Admin UI toggles for features and integrations
  • 🌐 Service Discovery - Auto-register commands when packages come online

Quick Start

1. Install the package

npm install @bernierllc/in-app-chat

2. Add to your Next.js app

// app/layout.tsx
import { MessagingProvider } from '@bernierllc/in-app-chat';

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <MessagingProvider
          config={{
            roles: ['user', 'admin', 'moderator'],
            permissions: {
              user: ['send_message', 'view_conversations'],
              admin: ['send_message', 'view_conversations', 'bulk_message', 'delete_messages'],
              moderator: ['send_message', 'view_conversations', 'moderate_messages'],
            },
          }}
        >
          {children}
        </MessagingProvider>
      </body>
    </html>
  );
}

3. Add messaging components to your navigation

// components/Navigation.tsx
import { MessagesIcon, MessagesDropdown } from '@bernierllc/in-app-chat';

export function Navigation() {
  return (
    <nav>
      <MessagesIcon />
      <MessagesDropdown />
    </nav>
  );
}

4. Create a Messaging Page

// app/messages/page.tsx
import { MessagesPage } from '@bernierllc/in-app-chat';

export default function Messages() {
  return <MessagesPage />;
}

Configuration

Basic Configuration

interface InAppChatConfig {
  roles: string[];
  permissions: Record<string, string[]>;
  features?: {
    realTime?: boolean;
    fileAttachments?: boolean;
    templates?: boolean;
    bulkMessaging?: boolean;
    search?: boolean;
  };
  styling?: {
    theme?: 'light' | 'dark' | 'auto';
    primaryColor?: string;
    borderRadius?: string;
  };
  database?: {
    type: 'sqlite' | 'postgresql' | 'mysql';
    connectionString?: string;
  };
  // NEW: External platform integrations
  integrations?: {
    slack?: {
      enabled: boolean;
      userMapping: 'external' | 'internal' | 'mixed';
      bidirectional: boolean;
      slashCommands: boolean;
    };
    discord?: { enabled: boolean; };
    teams?: { enabled: boolean; };
  };
  // NEW: Slash command routing
  slashCommands?: Record<string, {
    enabled: boolean;
    package: string;
    description: string;
    requiresAuth?: boolean;
    platforms?: string[];
  }>;
}

Advanced Configuration with Integrations

const advancedConfig = {
  roles: ['user', 'admin', 'moderator', 'support'],
  permissions: {
    user: ['send_message', 'view_conversations', 'edit_own_messages'],
    admin: ['send_message', 'view_conversations', 'bulk_message', 'delete_messages', 'view_analytics'],
    moderator: ['send_message', 'view_conversations', 'moderate_messages', 'pin_messages'],
    support: ['send_message', 'view_conversations', 'view_support_tickets'],
  },
  features: {
    realTime: true,
    fileAttachments: true,
    templates: true,
    bulkMessaging: true,
    search: true,
    messageReactions: true,
    messageThreading: true,
  },
  styling: {
    theme: 'auto',
    primaryColor: '#3b82f6',
    borderRadius: '0.5rem',
  },
  database: {
    type: 'postgresql',
    connectionString: process.env.DATABASE_URL,
  },
  // External platform integrations
  integrations: {
    slack: {
      enabled: true,
      userMapping: 'external',
      bidirectional: true,
      slashCommands: true,
      socketMode: true,
      channelWhitelist: ['#general', '#support']
    },
    discord: { enabled: false },
    teams: { enabled: false }
  },
  // Slash command routing via NeverHub
  slashCommands: {
    '/task': {
      enabled: true,
      package: '@bernierllc/slash-commands-tasks',
      description: 'Create and manage tasks',
      requiresAuth: true,
      platforms: ['in-app', 'slack', 'discord']
    },
    '/schedule': {
      enabled: true,
      package: '@bernierllc/slash-commands-calendar',
      description: 'Schedule meetings and events',
      adminOnly: false
    }
  },
  // NeverHub service discovery
  neverhub: {
    enabled: true,
    serviceName: 'in-app-chat-suite',
    autoRegisterCommands: true
  }
};

External Platform Integrations

Slack Integration

Enable bidirectional messaging with Slack workspaces:

// in-app-chat.config.js
module.exports = {
  integrations: {
    slack: {
      enabled: true,
      userMapping: 'external',    // Show Slack users as "external" in browser
      bidirectional: true,        // Messages flow both ways
      slashCommands: true,        // Enable slash commands in Slack
      socketMode: true,           // Use Socket Mode for real-time
      channelWhitelist: ['#general', '#support']
    }
  }
};

Required Environment Variables:

SLACK_BOT_TOKEN=xoxb-your-bot-token
SLACK_SIGNING_SECRET=your-signing-secret

Install Integration Package:

npm install @bernierllc/chat-integration-slack

Discord Integration

npm install @bernierllc/chat-integration-discord

Microsoft Teams Integration

npm install @bernierllc/chat-integration-teams

Slash Commands via NeverHub

Dynamic Command Registration

Commands are automatically discovered and registered when their packages come online:

// in-app-chat.config.js
module.exports = {
  slashCommands: {
    '/task': {
      enabled: true,
      package: '@bernierllc/slash-commands-tasks',
      description: 'Create and manage tasks',
      requiresAuth: true,
      platforms: ['in-app', 'slack', 'discord'],
      aliases: ['/tasks', '/todo']
    },
    '/schedule': {
      enabled: true,
      package: '@bernierllc/slash-commands-calendar',
      description: 'Schedule meetings and events'
    }
  }
};

Available Slash Command Packages

Install the command packages you need:

# Task management
npm install @bernierllc/slash-commands-tasks

# Calendar/scheduling
npm install @bernierllc/slash-commands-calendar

# Authentication commands (admin only)
npm install @bernierllc/slash-commands-auth

Service Discovery Flow

  1. in-app-chat registers with NeverHub as command router
  2. Command packages register their capabilities with NeverHub
  3. in-app-chat automatically discovers and registers commands
  4. Commands work across all enabled platforms (in-app, Slack, Discord, Teams)
  5. When packages go offline, commands are automatically deregistered

Admin UI Integration

Toggle commands and integrations live:

  • Enable/disable individual slash commands
  • Toggle integrations (Slack, Discord, Teams) on/off
  • Manage permissions for role-based command access
  • View integration status and health monitoring

Database Schema

The package includes a complete database schema that can be automatically generated:

-- Users table (extends your existing users)
CREATE TABLE messaging_users (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
  role VARCHAR(50) NOT NULL,
  display_name VARCHAR(255) NOT NULL,
  avatar_url TEXT,
  is_online BOOLEAN DEFAULT false,
  last_seen TIMESTAMP DEFAULT NOW(),
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);

-- Conversations table
CREATE TABLE messaging_conversations (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  title VARCHAR(255),
  type VARCHAR(50) NOT NULL DEFAULT 'direct',
  metadata JSONB,
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);

-- Conversation participants
CREATE TABLE messaging_conversation_participants (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  conversation_id UUID NOT NULL REFERENCES messaging_conversations(id) ON DELETE CASCADE,
  user_id UUID NOT NULL REFERENCES messaging_users(id) ON DELETE CASCADE,
  role VARCHAR(50) NOT NULL,
  joined_at TIMESTAMP DEFAULT NOW(),
  left_at TIMESTAMP,
  UNIQUE(conversation_id, user_id)
);

-- Messages table
CREATE TABLE messaging_messages (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  conversation_id UUID NOT NULL REFERENCES messaging_conversations(id) ON DELETE CASCADE,
  sender_id UUID NOT NULL REFERENCES messaging_users(id) ON DELETE CASCADE,
  content TEXT NOT NULL,
  message_type VARCHAR(50) DEFAULT 'text',
  metadata JSONB,
  reply_to_id UUID REFERENCES messaging_messages(id),
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);

-- Message attachments
CREATE TABLE messaging_message_attachments (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  message_id UUID NOT NULL REFERENCES messaging_messages(id) ON DELETE CASCADE,
  file_name VARCHAR(255) NOT NULL,
  file_url TEXT NOT NULL,
  file_size INTEGER NOT NULL,
  mime_type VARCHAR(100) NOT NULL,
  created_at TIMESTAMP DEFAULT NOW()
);

-- Message templates
CREATE TABLE messaging_message_templates (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  name VARCHAR(255) NOT NULL,
  content TEXT NOT NULL,
  category VARCHAR(100),
  role VARCHAR(50) NOT NULL,
  variables JSONB,
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);

-- Message reactions
CREATE TABLE messaging_message_reactions (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  message_id UUID NOT NULL REFERENCES messaging_messages(id) ON DELETE CASCADE,
  user_id UUID NOT NULL REFERENCES messaging_users(id) ON DELETE CASCADE,
  reaction_type VARCHAR(50) NOT NULL,
  created_at TIMESTAMP DEFAULT NOW(),
  UNIQUE(message_id, user_id, reaction_type)
);

-- Message read receipts
CREATE TABLE messaging_message_read_receipts (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  message_id UUID NOT NULL REFERENCES messaging_messages(id) ON DELETE CASCADE,
  user_id UUID NOT NULL REFERENCES messaging_users(id) ON DELETE CASCADE,
  read_at TIMESTAMP DEFAULT NOW(),
  UNIQUE(message_id, user_id)
);

API Routes

The package provides a complete set of API routes:

  • GET /api/messaging/conversations - Get user conversations
  • GET /api/messaging/conversations/[id] - Get specific conversation
  • POST /api/messaging/conversations - Create new conversation
  • GET /api/messaging/conversations/[id]/messages - Get conversation messages
  • POST /api/messaging/conversations/[id]/messages - Send message
  • PUT /api/messaging/messages/[id] - Edit message
  • DELETE /api/messaging/messages/[id] - Delete message
  • POST /api/messaging/messages/[id]/reactions - Add reaction
  • GET /api/messaging/templates - Get message templates
  • POST /api/messaging/bulk - Send bulk messages

Components

Core Components

  • MessagingProvider - Main provider component
  • MessagesIcon - Navigation icon with unread count
  • MessagesDropdown - Quick access dropdown
  • MessagesPage - Full messaging interface
  • ConversationList - List of conversations
  • MessageThread - Message thread view
  • MessageInput - Message input component
  • MessageBubble - Individual message display

Role-Specific Components

  • RoleBasedFilters - Role-specific filtering
  • BulkMessageModal - Bulk messaging interface
  • TemplateSelector - Message template selector
  • FileUpload - File attachment component
  • MessageSearch - Search functionality

Customization

Styling

// tailwind.config.js
module.exports = {
  content: [
    './src/**/*.{js,ts,jsx,tsx}',
    './node_modules/@bernierllc/in-app-chat/dist/**/*.{js,ts,jsx,tsx}',
  ],
  theme: {
    extend: {
      colors: {
        messaging: {
          primary: '#3b82f6',
          secondary: '#64748b',
          success: '#10b981',
          warning: '#f59e0b',
          error: '#ef4444',
        },
      },
    },
  },
};

Custom Components

// components/CustomMessageBubble.tsx
import { MessageBubble, MessageBubbleProps } from '@bernierllc/in-app-chat';

export function CustomMessageBubble(props: MessageBubbleProps) {
  return (
    <div className="custom-message-bubble">
      <MessageBubble {...props} />
    </div>
  );
}

Extending for Your App

1. Define Your User Types

// types/messaging.ts
export interface AppUser {
  id: string;
  name: string;
  email: string;
  role: 'student' | 'teacher' | 'admin';
  avatar?: string;
}

export interface AppMessagingConfig {
  roles: ['student', 'teacher', 'admin'];
  permissions: {
    student: ['send_message', 'view_conversations'];
    teacher: ['send_message', 'view_conversations', 'bulk_message'];
    admin: ['send_message', 'view_conversations', 'bulk_message', 'delete_messages'];
  };
}

2. Create Custom Hooks

// hooks/useAppMessaging.ts
import { useMessaging } from '@bernierllc/in-app-chat';
import { AppUser } from '../types/messaging';

export function useAppMessaging() {
  const messaging = useMessaging();
  
  // Add app-specific logic
  const sendStudentMessage = (studentId: string, message: string) => {
    return messaging.sendMessage({
      recipientId: studentId,
      recipientType: 'student',
      message,
      metadata: { appType: 'education' },
    });
  };
  
  return {
    ...messaging,
    sendStudentMessage,
  };
}

3. Add App-Specific Features

// components/StudentMessaging.tsx
import { MessagesPage, useMessaging } from '@bernierllc/in-app-chat';

export function StudentMessaging() {
  const { conversations, sendMessage } = useMessaging();
  
  const studentConversations = conversations.filter(
    conv => conv.participants.some(p => p.role === 'student')
  );
  
  return (
    <MessagesPage
      conversations={studentConversations}
      onSendMessage={sendMessage}
      customFilters={[
        { label: 'Teachers', value: 'teacher' },
        { label: 'Classmates', value: 'student' },
      ]}
    />
  );
}

Testing

// __tests__/in-app-chat.test.tsx
import { render, screen } from '@testing-library/react';
import { MessagingProvider } from '@bernierllc/in-app-chat';

test('renders messaging interface', () => {
  render(
    <MessagingProvider config={{ roles: ['user'], permissions: { user: ['send_message'] } }}>
      <MessagesPage />
    </MessagingProvider>
  );
  
  expect(screen.getByText('Messages')).toBeInTheDocument();
});

Performance

The package is optimized for performance:

  • Code splitting - Only loads components when needed
  • Virtual scrolling - Handles large message lists efficiently
  • Optimistic updates - Immediate UI feedback
  • Efficient caching - Reduces API calls
  • Bundle optimization - Minimal impact on app size

Security

Built-in security features:

  • Message encryption - Secure message IDs
  • Access validation - Role-based permissions
  • Input sanitization - XSS protection
  • Rate limiting - Prevents abuse
  • Audit logging - Track all activities

Support

License

MIT License - see LICENSE for details.

Monorepo Workspaces & Dependency Management

This package is part of a monorepo using npm workspaces. All dependencies are hoisted to the root. Always run npm install from the root directory.

React 19 and Testing Library Compatibility

This package uses React 19.1.0. If you see peer dependency warnings with Testing Library, use:

npm install --legacy-peer-deps

This is a temporary workaround until official support is released.