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

@soaal/rag-reactjs-sdk

v0.0.2

Published

Beautiful, customizable chat widget SDK for React and Next.js with RAG integration, RTL support, and 13+ themes

Readme

Light RAG React/Next.js SDK

A TypeScript SDK for integrating Light RAG API into React and Next.js applications. This SDK provides a simple interface for creating chat conversations, sending messages, and managing chat history using session-based authentication.

Installation

npm install @soaal/rag-reactjs-sdk
# or
yarn add @soaal/rag-reactjs-sdk
# or
pnpm add @soaal/rag-reactjs-sdk

Quick Start

Using the Pre-built Widget (Recommended)

The easiest way to get started is using the pre-built ChatWidget component:

'use client';

import { ChatWidget } from '@soaal/rag-reactjs-sdk';

export default function ChatPage() {
  return (
    <div style={{ width: '500px', height: '700px' }}>
      <ChatWidget
        apiKey={process.env.NEXT_PUBLIC_RAG_API_KEY!}
        title="Customer Support"
      />
    </div>
  );
}

Customizing the Widget

The widget is highly customizable:

<ChatWidget
  apiKey="your-api-key"
  title="Support Chat"
  theme={{
    primaryColor: '#6366f1',
    userMessageColor: '#6366f1',
    assistantMessageColor: '#f3f4f6',
    borderRadius: '12px',
  }}
  showAvatar={true}
  showTimestamp={true}
  placeholder="Ask me anything..."
  onMessageSent={(message) => console.log('Sent:', message)}
  onMessageReceived={(response) => console.log('Received:', response)}
/>

Basic Usage with React Hook

'use client';

import { useLightRAG } from '@soaal/rag-reactjs-sdk';

function ChatWidget() {
  const { messages, sendMessage, sending, error } = useLightRAG({
    apiKey: 'your-public-api-key',
    baseUrl: 'https://your-api-domain.com/api/v1', // Optional
    autoCreateChat: true, // Automatically create a chat on mount
  });

  const [input, setInput] = useState('');

  return (
    <div className="chat-widget">
      {error && (
        <div className="error">
          Error: {error.message}
        </div>
      )}
      
      <div className="messages">
        {messages.map((msg) => (
          <div key={msg.id} className={`message ${msg.role}`}>
            {msg.content}
          </div>
        ))}
      </div>

      <form
        onSubmit={(e) => {
          e.preventDefault();
          sendMessage(input);
          setInput('');
        }}
      >
        <input
          value={input}
          onChange={(e) => setInput(e.target.value)}
          placeholder="Type your message..."
          disabled={sending}
        />
        <button type="submit" disabled={sending}>
          {sending ? 'Sending...' : 'Send'}
        </button>
      </form>
    </div>
  );
}

Usage with SDK Class

import { LightRAGSDK } from '@soaal/rag-reactjs-sdk';

const sdk = new LightRAGSDK({
  apiKey: 'your-public-api-key',
  baseUrl: 'https://your-api-domain.com/api/v1', // Optional
});

// Create a chat
const chatId = await sdk.createChat('Customer Support');

// Send a message
const response = await sdk.sendMessage(chatId, 'What are your business hours?');
console.log('AI Response:', response);

// Get chat history
const messages = await sdk.getChatMessages(chatId);
console.log('Chat History:', messages);

API Reference

ChatWidget

A fully customizable, ready-to-use chat widget component.

Props

interface ChatWidgetProps {
  // Required
  apiKey: string;
  
  // Display options
  title?: string;                    // Widget title
  placeholder?: string;              // Input placeholder
  showHeader?: boolean;              // Show header (default: true)
  showFooter?: boolean;              // Show footer (default: false)
  showErrorBanner?: boolean;         // Show error banner (default: true)
  showTimestamp?: boolean;           // Show message timestamps (default: false)
  showAvatar?: boolean;              // Show avatars (default: false)
  userAvatar?: string | ReactNode;   // Custom user avatar
  assistantAvatar?: string | ReactNode; // Custom assistant avatar
  
  // Behavior
  autoScroll?: boolean;              // Auto-scroll to bottom (default: true)
  scrollBehavior?: 'smooth' | 'auto';
  maxHeight?: string;                // Max height of messages area
  minHeight?: string;                // Min height of messages area
  
  // Styling
  className?: string;                // Root container class
  containerClassName?: string;       // Input container class
  messagesClassName?: string;        // Messages container class
  inputClassName?: string;          // Input field class
  buttonClassName?: string;          // Send button class
  headerClassName?: string;         // Header class
  footerClassName?: string;         // Footer class
  messageClassName?: string;        // Message wrapper class
  userMessageClassName?: string;    // User message class
  assistantMessageClassName?: string; // Assistant message class
  
  // Theme
  theme?: ChatWidgetTheme;          // Theme configuration
  
  // Custom renderers
  renderers?: ChatWidgetRenderers;   // Custom render functions
  
  // Callbacks
  onMessageSent?: (message: string) => void;
  onMessageReceived?: (response: string) => void;
  onChatCreated?: (chatId: string) => void;
  
  // Input options
  inputMaxLength?: number;           // Max input length
  inputRows?: number;                // Rows for multiline (default: 1)
  multiline?: boolean;               // Enable multiline input (default: false)
  sendOnEnter?: boolean;             // Send on Enter (default: true)
  sendOnShiftEnter?: boolean;        // Send on Shift+Enter (default: false)
  
  // Icons
  sendIcon?: ReactNode;              // Custom send icon
  loadingIcon?: ReactNode;           // Custom loading icon
  
  // SDK config (passed to useLightRAG)
  baseUrl?: string;
  autoCreateChat?: boolean;
  chatId?: string;
  onError?: (error: LightRAGError) => void;
}

Theme Configuration

interface ChatWidgetTheme {
  // Colors
  primaryColor?: string;
  secondaryColor?: string;
  backgroundColor?: string;
  textColor?: string;
  userMessageColor?: string;
  assistantMessageColor?: string;
  userMessageTextColor?: string;
  assistantMessageTextColor?: string;
  borderColor?: string;
  errorColor?: string;
  
  // Spacing
  borderRadius?: string;
  padding?: string;
  gap?: string;
  
  // Typography
  fontSize?: string;
  fontFamily?: string;
  
  // Shadows
  boxShadow?: string;
}

Custom Renderers

You can completely customize how elements are rendered:

interface ChatWidgetRenderers {
  renderMessage?: (message: Message, index: number) => ReactNode;
  renderUserMessage?: (message: Message, index: number) => ReactNode;
  renderAssistantMessage?: (message: Message, index: number) => ReactNode;
  renderError?: (error: LightRAGError, onDismiss: () => void) => ReactNode;
  renderInput?: (props: ChatWidgetInputProps) => ReactNode;
  renderSendButton?: (props: ChatWidgetButtonProps) => ReactNode;
  renderHeader?: () => ReactNode;
  renderFooter?: () => ReactNode;
  renderEmptyState?: () => ReactNode;
  renderLoading?: () => ReactNode;
}

useLightRAG(config)

React hook for managing chat state and interactions.

Parameters

  • config.apiKey (string, required): Your public API key
  • config.baseUrl (string, optional): API base URL (default: https://your-api-domain.com/api/v1)
  • config.autoCreateChat (boolean, optional): Automatically create a chat on mount (default: true)
  • config.chatId (string, optional): Initial chat ID to load
  • config.onError (function, optional): Error callback function

Returns

{
  // State
  messages: Message[];           // Array of chat messages
  chats: Chat[];                 // Array of all chats
  currentChatId: string | null;  // Current active chat ID
  loading: boolean;              // Loading state (initial load)
  sending: boolean;             // Sending message state
  error: LightRAGError | null;  // Error state

  // Actions
  sendMessage: (message: string) => Promise<void>;
  createChat: (title?: string) => Promise<string>;
  loadChat: (chatId: string) => Promise<void>;
  refreshChats: () => Promise<void>;
  clearError: () => void;
}

LightRAGSDK

Main SDK class for API interactions.

Constructor

new LightRAGSDK(config: LightRAGConfig)

Methods

createChat(title?: string): Promise<string>

Create a new chat conversation.

listChats(): Promise<Chat[]>

List all chats for the current session.

sendMessage(chatId: string, message: string): Promise<string>

Send a message to the chatbot and get a response.

getChatMessages(chatId: string): Promise<Message[]>

Get all messages in a chat conversation.

listPendingQuestions(params?): Promise<ListPendingQuestionsResponse>

List pending questions (optional feature).

submitAnswer(pendingQuestionId: string, answer: string, isFAQ?: boolean): Promise<boolean>

Submit an answer to a pending question (optional feature).

getUsage(): Promise<UsageStats>

Get usage statistics (optional feature).

Next.js Integration

App Router (Next.js 13+)

// app/chat/page.tsx
'use client';

import { useLightRAG } from '@soaal/rag-reactjs-sdk';

export default function ChatPage() {
  const { messages, sendMessage, sending } = useLightRAG({
    apiKey: process.env.NEXT_PUBLIC_RAG_API_KEY!,
  });

  // ... rest of component
}

Pages Router

// pages/chat.tsx
import { useLightRAG } from '@soaal/rag-reactjs-sdk';

export default function ChatPage() {
  const { messages, sendMessage, sending } = useLightRAG({
    apiKey: process.env.NEXT_PUBLIC_RAG_API_KEY!,
  });

  // ... rest of component
}

TypeScript Support

This SDK is written in TypeScript and includes full type definitions. All types are exported for your convenience:

import type {
  Chat,
  Message,
  PendingQuestion,
  UsageStats,
  LightRAGError,
} from '@soaal/rag-reactjs-sdk';

Error Handling

The SDK provides comprehensive error handling:

import { useLightRAG } from '@soaal/rag-reactjs-sdk';

function ChatComponent() {
  const { error, sendMessage, clearError } = useLightRAG({
    apiKey: 'your-key',
    onError: (error) => {
      console.error('Chat error:', error);
      // Custom error handling
    },
  });

  if (error) {
    return (
      <div>
        <p>Error: {error.message}</p>
        <button onClick={clearError}>Dismiss</button>
      </div>
    );
  }

  // ... rest of component
}

Session Management

The SDK automatically handles session management via HTTP cookies. Sessions are:

  • Created automatically on first request
  • Maintained across page refreshes
  • Isolated per tenant
  • Managed server-side (no manual cookie handling needed)

Best Practices

  1. Store API keys securely: Use environment variables (NEXT_PUBLIC_* for client-side)
  2. Handle errors gracefully: Always check the error state and provide user feedback
  3. Show loading states: Use loading and sending states to provide UI feedback
  4. Validate input: Check message length before sending
  5. Debounce rapid requests: Avoid sending multiple messages in quick succession

Widget Examples

Basic Widget

<ChatWidget
  apiKey="your-api-key"
  title="Support Chat"
/>

Themed Widget

<ChatWidget
  apiKey="your-api-key"
  title="Support Chat"
  theme={{
    primaryColor: '#6366f1',
    userMessageColor: '#6366f1',
    assistantMessageColor: '#f3f4f6',
    borderRadius: '12px',
  }}
/>

Dark Theme

<ChatWidget
  apiKey="your-api-key"
  theme={{
    backgroundColor: '#1f2937',
    textColor: '#f9fafb',
    userMessageColor: '#8b5cf6',
    assistantMessageColor: '#374151',
    borderColor: '#4b5563',
  }}
/>

With Avatars and Timestamps

<ChatWidget
  apiKey="your-api-key"
  showAvatar={true}
  showTimestamp={true}
  userAvatar="👤"
  assistantAvatar="🤖"
/>

Custom Renderers

<ChatWidget
  apiKey="your-api-key"
  renderers={{
    renderUserMessage: (message) => (
      <div className="custom-user-message">
        {message.content}
      </div>
    ),
    renderAssistantMessage: (message) => (
      <div className="custom-assistant-message">
        {message.content}
      </div>
    ),
  }}
/>

Multiline Input

<ChatWidget
  apiKey="your-api-key"
  multiline={true}
  inputRows={3}
  sendOnShiftEnter={true}
  placeholder="Type your message... (Shift+Enter to send)"
/>

Examples

Multi-Chat Interface

function ChatManager() {
  const { chats, currentChatId, loadChat, createChat } = useLightRAG({
    apiKey: 'your-key',
    autoCreateChat: false,
  });

  return (
    <div>
      <div className="chat-list">
        <button onClick={() => createChat()}>New Chat</button>
        {chats.map((chat) => (
          <button
            key={chat.id}
            onClick={() => loadChat(chat.id)}
            className={currentChatId === chat.id ? 'active' : ''}
          >
            {chat.title || 'Untitled Chat'}
          </button>
        ))}
      </div>
      {/* Chat interface */}
    </div>
  );
}

Custom Error Boundary

function ChatWithErrorBoundary() {
  const { error, clearError, sendMessage } = useLightRAG({
    apiKey: 'your-key',
  });

  if (error?.status === 401) {
    return <div>Invalid API key. Please check your configuration.</div>;
  }

  if (error?.status === 429) {
    return <div>Rate limit exceeded. Please try again later.</div>;
  }

  // ... rest of component
}

License

MIT

Support

For issues, questions, or feature requests, refer to the SDK Flow Documentation or contact your tenant administrator.