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

@sa-project/client

v0.3.2

Published

React-based chat widget library for e-commerce websites

Readme

🤖 Mudda AI Chat Widget

Version License React TypeScript

Add AI-powered chat to your website in just 2 minutes!

DemoQuick StartDocumentationExamples


✨ Features

  • 🚀 2-Minute Setup - Add AI chat with just one script tag
  • 🎨 Beautiful Apple-Style UI - Modern, clean design inspired by Apple's design language
  • 🌓 Dark Mode Support - Automatic or manual dark/light mode
  • 🎯 Customizable Button - Transparent, black, white, or gradient styles
  • 📱 Fully Responsive - Perfect on mobile, tablet, and desktop
  • 💬 Real-Time Chat - Instant message sending and receiving
  • 🔍 Search Integration - Display product search results in chat
  • 🎭 Session Management - Maintains user sessions automatically
  • Zero Dependencies - No React setup required for basic usage
  • 🌐 Universal Compatibility - Works on any website
  • 🔧 TypeScript Support - Full type definitions included

📦 Installation

Option 1: CDN (Recommended for Most Users)

Simply add these two lines to your HTML:

<!-- Load Mudda Chat Widget -->
<script src="https://unpkg.com/@sa-project/client@latest/dist/sa-client.standalone.js"></script>
<link
  rel="stylesheet"
  href="https://unpkg.com/@sa-project/client@latest/dist/sa-client.standalone.css"
/>

Option 2: NPM (For React/Vue/Angular Projects)

npm install @sa-project/client

🚀 Quick Start

Basic Setup (2 Steps)

Step 1: Add the script to your HTML

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>My Website</title>

    <!-- Load Mudda Chat Widget -->
    <script src="https://unpkg.com/@sa-project/client@latest/dist/sa-client.standalone.js"></script>
    <link
      rel="stylesheet"
      href="https://unpkg.com/@sa-project/client@latest/dist/sa-client.standalone.css"
    />
  </head>
  <body>
    <h1>Welcome to My Website</h1>

    <!-- Step 2: Initialize -->
    <script>
      initSAClient({
        apiKey: "your-api-key",
        serverUrl: "https://your-server.com",
      });
    </script>
  </body>
</html>

Done! 🎉 The chat widget will appear in the bottom-right corner.

⚙️ Configuration

Configuration Options

| Option | Type | Description | Required | Default | | ------------- | ----------------------------------------- | ------------------------------------------------ | -------- | ----------- | | apiKey | string | Your API key for authentication | Yes | - | | serverUrl | string | Server URL for API endpoints | Yes | - | | dark | boolean | Dark mode setting (true: dark, false: light) | No | System pref | | buttonColor | "transparent" | "black" | "white" | Floating button background color | No | Gradient |

Configuration Examples

Basic Configuration

initSAClient({
  apiKey: "your-api-key",
  serverUrl: "https://your-server.com",
});

With Dark Mode

// Force dark mode
initSAClient({
  apiKey: "your-api-key",
  serverUrl: "https://your-server.com",
  dark: true,
});

// Force light mode
initSAClient({
  apiKey: "your-api-key",
  serverUrl: "https://your-server.com",
  dark: false,
});

// Automatic (follows system preference) - default
initSAClient({
  apiKey: "your-api-key",
  serverUrl: "https://your-server.com",
  // dark option omitted
});

With Custom Button Color

// Transparent button with blur effect (glassmorphism)
initSAClient({
  apiKey: "your-api-key",
  serverUrl: "https://your-server.com",
  buttonColor: "transparent",
});

// Black button (minimal, professional)
initSAClient({
  apiKey: "your-api-key",
  serverUrl: "https://your-server.com",
  buttonColor: "black",
});

// White button (clean, bright)
initSAClient({
  apiKey: "your-api-key",
  serverUrl: "https://your-server.com",
  buttonColor: "white",
});

Full Configuration

initSAClient({
  apiKey: "your-api-key",
  serverUrl: "https://your-server.com",
  dark: false, // Force light mode
  buttonColor: "transparent", // Transparent button
});

Button Color Options

| Option | Preview | Description | Best For | | ------------- | ------- | ------------------------------------------ | -------------------- | | Default | 🟣 | Purple-pink gradient with blue glow | General use | | transparent | ◻️ | Transparent with blur effect, white border | Colorful backgrounds | | black | ⬛ | Pure black background | Light backgrounds | | white | ⬜ | Pure white background with gray border | Dark backgrounds |

📱 Usage Examples

Example 1: E-commerce Store

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>My E-commerce Store</title>

    <script src="https://unpkg.com/@sa-project/client@latest/dist/sa-client.standalone.js"></script>
    <link
      rel="stylesheet"
      href="https://unpkg.com/@sa-project/client@latest/dist/sa-client.standalone.css"
    />
  </head>
  <body>
    <h1>Welcome to Our Store</h1>
    <p>AI shopping assistant is here to help!</p>

    <script>
      initSAClient({
        apiKey: "sk-1234567890abcdef",
        serverUrl: "https://api.myshop.com",
        buttonColor: "black", // Professional black button
      });
    </script>
  </body>
</html>

Example 2: React Project

import { useEffect } from "react";
import { SAClient } from "@sa-project/client";

function App() {
  useEffect(() => {
    const saClient = SAClient.getInstance();
    saClient.init({
      apiKey: process.env.REACT_APP_API_KEY,
      serverUrl: process.env.REACT_APP_SERVER_URL,
      dark: false, // Force light mode
      buttonColor: "transparent",
    });

    // Cleanup on unmount
    return () => {
      saClient.destroy();
    };
  }, []);

  return (
    <div className="App">
      <h1>My React App</h1>
      {/* Your app content */}
    </div>
  );
}

export default App;

Example 3: Dark Theme Website

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Dark Theme Website</title>

    <script src="https://unpkg.com/@sa-project/client@latest/dist/sa-client.standalone.js"></script>
    <link
      rel="stylesheet"
      href="https://unpkg.com/@sa-project/client@latest/dist/sa-client.standalone.css"
    />

    <style>
      body {
        background: #1d1d1f;
        color: #f5f5f7;
        font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
      }
    </style>
  </head>
  <body>
    <h1>Dark Theme Website</h1>

    <script>
      initSAClient({
        apiKey: "your-api-key",
        serverUrl: "https://your-server.com",
        dark: true, // Match dark theme
        buttonColor: "white", // White button stands out on dark background
      });
    </script>
  </body>
</html>

Example 4: Colorful Landing Page

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Colorful Landing Page</title>

    <script src="https://unpkg.com/@sa-project/client@latest/dist/sa-client.standalone.js"></script>
    <link
      rel="stylesheet"
      href="https://unpkg.com/@sa-project/client@latest/dist/sa-client.standalone.css"
    />

    <style>
      body {
        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        min-height: 100vh;
        color: white;
      }
    </style>
  </head>
  <body>
    <h1>Welcome to Our Service</h1>

    <script>
      initSAClient({
        apiKey: "your-api-key",
        serverUrl: "https://your-server.com",
        buttonColor: "transparent", // Blends beautifully with gradient
      });
    </script>
  </body>
</html>

🛠️ API Reference

initSAClient(config)

Initializes the chat widget on your page.

Parameters:

  • config (object): Configuration options

Returns: void

Example:

initSAClient({
  apiKey: "your-api-key",
  serverUrl: "https://your-server.com",
  dark: false,
  buttonColor: "black",
});

SAClient.getInstance()

Gets the singleton instance of the SAClient.

Returns: SAClient instance

Example:

const saClient = SAClient.getInstance();

saClient.destroy()

Removes the chat widget from the page and cleans up resources.

Returns: void

Example:

const saClient = SAClient.getInstance();
saClient.destroy();

saClient.init(config)

Initializes the chat widget (alternative to initSAClient).

Parameters:

  • config (object): Configuration options

Returns: void

Example:

const saClient = SAClient.getInstance();
saClient.init({
  apiKey: "your-api-key",
  serverUrl: "https://your-server.com",
});

🔧 Server API Requirements

Your server must provide the following endpoint:

POST /api/chat

Request Body:

{
  "message": "user message",
  "sessionId": "optional-session-id",
  "userId": "optional-user-id"
}

Response Format:

{
  "success": true,
  "data": "AI response message",
  "sessionId": "session-123",
  "timestamp": "2024-01-01T00:00:00.000Z",
  "searchResults": [
    {
      "name": "Product Name",
      "category": "Category",
      "price": 99.99,
      "image": "https://example.com/image.jpg",
      "url": "https://example.com/product"
    }
  ]
}

Response Fields:

  • success (boolean): Whether the request was successful
  • data (string): AI response message
  • sessionId (string): Session ID for maintaining conversation
  • timestamp (string): ISO 8601 timestamp
  • searchResults (array, optional): Product search results to display

🎨 Design System

Typography

  • Font Family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif
  • Font Smoothing: -webkit-font-smoothing: antialiased
  • Letter Spacing: Precise Apple-style tracking

Colors

Light Mode

  • Background: #f5f5f7
  • Text: #1d1d1f
  • Secondary Text: #6e6e73
  • Border: #d2d2d7
  • User Message: #0071e3
  • Bot Message: #e5e5ea

Dark Mode

  • Background: #1d1d1f
  • Text: #f5f5f7
  • Secondary Text: #a1a1a6
  • Border: #424245
  • User Message: #0071e3
  • Bot Message: #2d2d2d

Shadows

  • Chat Window: 0 25px 50px -12px rgba(0, 0, 0, 0.25)
  • Floating Button: 0 8px 32px rgba(0, 113, 227, 0.4), 0 2px 8px rgba(0, 113, 227, 0.2)

Border Radius

  • Chat Window: 28px
  • Message Bubbles: 18px
  • Input Field: 9999px (fully rounded)
  • Floating Button: 50% (circle)

🌐 Browser Support

| Browser | Minimum Version | | ------- | --------------- | | Chrome | 60+ | | Firefox | 60+ | | Safari | 12+ | | Edge | 79+ |

🎯 Features in Detail

🌓 Dark Mode

The widget supports three dark mode options:

  1. Automatic (Default): Follows system preference using prefers-color-scheme
  2. Force Light: Set dark: false to always use light mode
  3. Force Dark: Set dark: true to always use dark mode

🎨 Floating Button Customization

Choose the perfect button style for your website:

  • Default Gradient: Eye-catching purple-pink gradient
  • Transparent: Glassmorphism effect, blends with any background
  • Black: Professional and minimal
  • White: Clean and bright for dark backgrounds

💬 Message Features

  • Text Messages: Send and receive text messages
  • Search Results: Display product cards in chat
  • Timestamps: Show message times
  • Typing Indicator: Shows when AI is typing
  • Loading State: Visual feedback during processing

📱 Responsive Design

  • Desktop: Fixed position in bottom-right corner
  • Mobile: Full-screen overlay for better UX
  • Tablet: Optimized for medium screens
  • Touch-Friendly: Large tap targets for mobile

🆘 Troubleshooting

Widget doesn't appear

  1. Check browser console for errors
  2. Verify script and CSS are loaded:
    console.log(window.initSAClient); // Should be defined
  3. Ensure you called initSAClient() after page load

API calls failing

  1. Check apiKey and serverUrl are correct
  2. Verify your server endpoint is accessible
  3. Check CORS settings on your server
  4. Look for network errors in DevTools > Network tab

Dark mode not working

  1. Ensure your browser supports prefers-color-scheme
  2. Check system dark mode settings
  3. Try forcing dark mode: dark: true

Button color not changing

  1. Clear browser cache
  2. Verify buttonColor value is one of: "transparent", "black", "white"
  3. Check for CSS conflicts

TypeScript errors

  1. Ensure @types/react and @types/react-dom are installed
  2. Check TypeScript version (5.0+)
  3. Verify dist/index.d.ts exists

📊 Performance

  • Bundle Size: ~50KB (minified)
  • CSS Size: ~5KB (minified)
  • Initial Load: < 100ms
  • Memory Usage: < 5MB
  • React Version: 18.3.1 (peer dependency)

🔒 Security

  • ✅ No data collection
  • ✅ Secure HTTPS endpoints only
  • ✅ API key authentication
  • ✅ Session management
  • ✅ XSS protection
  • ✅ CORS-ready

🚀 Deployment Guides

Netlify

  1. Add script tags to index.html
  2. Deploy your site
  3. Done! ✅

Vercel

  1. Add script tags to your HTML/JSX
  2. Deploy with vercel
  3. Done! ✅

GitHub Pages

  1. Add script tags to index.html
  2. Push to gh-pages branch
  3. Done! ✅

WordPress

  1. Add script to theme footer (footer.php)
  2. Or use "Insert Headers and Footers" plugin
  3. Done! ✅

📚 Advanced Usage

Custom Styling

Override default styles with CSS variables:

:root {
  --sa-primary-color: #0071e3;
  --sa-border-radius: 28px;
  --sa-font-family: -apple-system, BlinkMacSystemFont, sans-serif;
}

Multiple Instances

Each page should have only one chat widget instance. If you need to reinitialize:

// Destroy old instance
SAClient.getInstance().destroy();

// Create new instance
initSAClient({
  apiKey: "new-api-key",
  serverUrl: "https://new-server.com",
});

Event Handling

// Listen for messages (custom implementation)
const saClient = SAClient.getInstance();

// Your custom event handling here

🤝 Contributing

We welcome contributions! Please see our contributing guidelines.

📄 License

MIT License - see LICENSE file for details

🔗 Links

  • NPM Package: https://www.npmjs.com/package/@sa-project/client
  • GitHub: https://github.com/mudda/SA-Client
  • Issues: https://github.com/mudda/SA-Client/issues
  • Documentation: https://github.com/mudda/SA-Client#readme

💡 Support

Need help? We're here for you:

🎉 What's New in v0.3.1

New Features

  • Dark Mode Support: Automatic, light, or dark mode options
  • 🎨 Custom Button Colors: Transparent, black, white, or gradient
  • 🍎 Apple-Style UI: Redesigned with Apple's design language
  • 📱 Improved Mobile UX: Better responsive design

Improvements

  • 🚀 Performance optimizations
  • 🎯 Better TypeScript support
  • 📦 Smaller bundle size
  • 🔧 Enhanced configuration options

Bug Fixes

  • Fixed dark mode flickering
  • Improved mobile scroll behavior
  • Better error handling

Made with ❤️ by the Mudda Team

⭐ Star us on GitHub🐛 Report a Bug💡 Request a Feature