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

coco-alert

v1.5.0

Published

Beautiful toast notifications for React & Next.js

Readme

🍫 CocoAlert

CocoAlert Banner

Beautiful, configurable toast notifications for React & Next.js

npm version downloads license bundle size

Independent timers. Hover-to-pause. Light & Dark themes. Zero dependencies.

DemoNPMGitHub


✨ Why CocoAlert?

  • 🎨 Light & Dark Mode - Beautiful built-in themes for any design
  • Independent Timers - Each alert manages its own lifecycle
  • 🎯 Hover to Pause - Progress pauses exactly where it is
  • 📍 7 Position Options - Place alerts anywhere on screen
  • 💬 Confirm Dialogs - Built-in async confirmation with Promise API
  • 🔧 Error Handler - Parse API errors with cocoErr() utility
  • 📦 Tiny Bundle - Only ~3KB gzipped
  • 🛠️ TypeScript Ready - Full type safety with JSDoc comments
  • 🚀 Zero Dependencies - No external packages needed

📦 Installation

npm install coco-alert
yarn add coco-alert
pnpm add coco-alert

🚀 Quick Start

Step 1: Add AlertContainer to your root component

import { AlertContainer, coco_Alert } from 'coco-alert/react';

function App() {
  return (
    <>
      <AlertContainer 
        isLightMode={false}
        position="top-right"
      />
      <YourApp />
    </>
  );
}

Step 2: Use alerts anywhere in your app

import { coco_Alert } from 'coco-alert/react';

function MyComponent() {
  return (
    <button onClick={() => coco_Alert.success('It works! 🎉')}>
      Click Me
    </button>
  );
}

That's it! No providers, no complex setup.


📖 Complete Examples

React (Vite, CRA)

import { AlertContainer, coco_Alert } from 'coco-alert/react';
import { useState } from 'react';

function App() {
  const [isLightMode, setIsLightMode] = useState(false);

  return (
    <>
      <AlertContainer 
        isLightMode={isLightMode}
        position="top-right"
      />
      
      <div>
        <h1>My App</h1>
        <button onClick={() => setIsLightMode(!isLightMode)}>
          Toggle Theme
        </button>
        <button onClick={() => coco_Alert.success('Success!')}>
          Show Alert
        </button>
      </div>
    </>
  );
}

export default App;

Next.js App Router

// app/layout.tsx
'use client'; // Required for App Router!

import { AlertContainer } from 'coco-alert/react';

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <AlertContainer 
          isLightMode={false}
          position="top-right"
        />
        {children}
      </body>
    </html>
  );
}
// app/page.tsx
'use client';

import { coco_Alert } from 'coco-alert/react';

export default function Page() {
  return (
    <div>
      <h1>Next.js App Router</h1>
      <button onClick={() => coco_Alert.info('Hello from Next.js! 👋')}>
        Show Alert
      </button>
    </div>
  );
}

Next.js Pages Router

// pages/_app.tsx
import { AlertContainer } from 'coco-alert/react';
import type { AppProps } from 'next/app';

export default function App({ Component, pageProps }: AppProps) {
  return (
    <>
      <AlertContainer 
        isLightMode={false}
        position="top-right"
      />
      <Component {...pageProps} />
    </>
  );
}
// pages/index.tsx
import { coco_Alert } from 'coco-alert/react';

export default function Home() {
  return (
    <div>
      <h1>Next.js Pages Router</h1>
      <button onClick={() => coco_Alert.success('It works! 🎉')}>
        Show Alert
      </button>
    </div>
  );
}

🎯 Real-World Examples

Form Submission

import { coco_Alert } from 'coco-alert/react';

async function handleSubmit(e) {
  e.preventDefault();
  
  try {
    await submitForm(formData);
    coco_Alert.success('Form submitted successfully! ✅');
  } catch (error) {
    coco_Alert.error('Failed to submit form. Please try again.');
  }
}

API Calls with Error Handler

import { coco_Alert, cocoErr } from 'coco-alert/react';

async function fetchData() {
  try {
    const response = await fetch('/api/data');
    if (!response.ok) throw new Error(await response.text());
    
    const data = await response.json();
    coco_Alert.success('Data loaded successfully!');
    return data;
  } catch (error) {
    const err = cocoErr(error);
    coco_Alert.error(err.message);
  }
}

Delete Confirmation

import { coco_Alert } from 'coco-alert/react';

async function handleDelete(id) {
  const confirmed = await coco_Alert.confirm(
    'Delete this item? This cannot be undone.'
  );
  
  if (confirmed) {
    try {
      await deleteItem(id);
      coco_Alert.success('Item deleted successfully!');
    } catch (error) {
      coco_Alert.error('Failed to delete item');
    }
  } else {
    coco_Alert.info('Deletion cancelled');
  }
}

Multiple Alerts

import { coco_Alert } from 'coco-alert/react';

function handleProcess() {
  coco_Alert.info('Processing started...');
  
  setTimeout(() => {
    coco_Alert.success('Step 1 complete');
  }, 1000);
  
  setTimeout(() => {
    coco_Alert.success('Step 2 complete');
  }, 2000);
  
  setTimeout(() => {
    coco_Alert.success('All done! 🎉');
  }, 3000);
}

📚 API Reference

AlertContainer Props

interface AlertContainerProps {
  isLightMode?: boolean;      // Default: false (dark mode)
  position?: AlertPosition;    // Default: "top-right"
}

type AlertPosition = 
  | "top-left" 
  | "top-right"      // Default
  | "top-center"
  | "center"
  | "bottom-left" 
  | "bottom-right" 
  | "bottom-center";

Examples

// Dark mode, top-right (default)
<AlertContainer />

// Light mode, top-right
<AlertContainer isLightMode={true} />

// Dark mode, bottom-center
<AlertContainer position="bottom-center" />

// Light mode, center
<AlertContainer isLightMode={true} position="center" />

Alert Methods

Basic Alerts

coco_Alert.success(message: string, duration?: number, position?: AlertPosition);
coco_Alert.error(message: string, duration?: number, position?: AlertPosition);
coco_Alert.warning(message: string, duration?: number, position?: AlertPosition);
coco_Alert.info(message: string, duration?: number, position?: AlertPosition);

| Parameter | Type | Default | Description | |-----------|------|---------|-------------| | message | string | required | The message to display | | duration | number | 4000 | Duration in milliseconds (4 seconds) | | position | AlertPosition | Container's position | Override container position for this alert |

Examples

// Simple alert (uses container settings)
coco_Alert.success('Saved!');

// Custom duration (10 seconds)
coco_Alert.error('Critical error', 10000);

// Override position for this alert
coco_Alert.info('Loading...', 3000, 'center');

// All options
coco_Alert.warning('Session expiring', 5000, 'bottom-right');

Confirmation Dialog

coco_Alert.confirm(message: string, position?: AlertPosition): Promise<boolean>

Returns a Promise that resolves to:

  • true if user clicks "Confirm"
  • false if user clicks "Cancel"

Examples

// Simple confirmation
const result = await coco_Alert.confirm('Are you sure?');
if (result) {
  console.log('User confirmed!');
}

// With custom position
const result = await coco_Alert.confirm('Delete this?', 'center');

// In async function
async function handleAction() {
  const confirmed = await coco_Alert.confirm('Proceed with this action?');
  
  if (confirmed) {
    await performAction();
    coco_Alert.success('Action completed!');
  } else {
    coco_Alert.info('Action cancelled');
  }
}

Error Handler - cocoErr()

Parse API errors into user-friendly messages.

function cocoErr(error: any): CocoErrorResult

interface CocoErrorResult {
  ok: false;
  status: number | null;
  message: string;
  raw: any;
}

Examples

import { coco_Alert, cocoErr } from 'coco-alert/react';

// Basic usage
try {
  const response = await fetch('/api/data');
  if (!response.ok) throw new Error(await response.text());
} catch (error) {
  const err = cocoErr(error);
  coco_Alert.error(err.message);
  console.log('Status:', err.status);
  console.log('Raw error:', err.raw);
}

// With CocoBase API errors
try {
  await cocobaseAPI.call();
} catch (error) {
  const err = cocoErr(error);
  // Automatically extracts: statusCode, error.detail
  coco_Alert.error(err.message);
}

// Generic error handling
try {
  throw new Error('Something went wrong');
} catch (error) {
  const err = cocoErr(error);
  // Returns: { ok: false, status: null, message: "Unexpected error", raw: error }
  coco_Alert.error(err.message);
}

🎨 Light & Dark Themes

CocoAlert includes beautiful built-in themes:

Dark Mode (Default)

  • Deep, rich backgrounds with vibrant accents
  • Perfect for dark interfaces
  • High contrast for readability

Light Mode

  • Clean, bright backgrounds with subtle accents
  • Perfect for light interfaces
  • Optimized for daylight viewing

Theme Examples

// Dark mode (default)
<AlertContainer isLightMode={false} />

// Light mode
<AlertContainer isLightMode={true} />

// Dynamic theme switching
function App() {
  const [isDark, setIsDark] = useState(true);
  
  return (
    <>
      <AlertContainer isLightMode={!isDark} />
      <button onClick={() => setIsDark(!isDark)}>
        Toggle Theme
      </button>
    </>
  );
}

// Sync with system preference
function App() {
  const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
  
  return <AlertContainer isLightMode={!prefersDark} />;
}

🎯 Features

🎨 Themes

  • Dark mode (default)
  • Light mode
  • Dynamic switching
  • System preference sync

📍 Positions

  • 7 position options
  • Set globally or per-alert
  • Auto-stacking
  • Responsive spacing

Performance

  • Independent timers
  • Hover-to-pause
  • No re-renders on new alerts
  • Smooth animations

🎭 Alert Types

  • Success (green)
  • Error (red)
  • Warning (yellow)
  • Info (blue)
  • Confirm (interactive)

📦 Lightweight

  • ~3KB gzipped
  • Zero dependencies
  • Pure inline styles
  • No CSS imports needed

🔧 Developer Experience

  • ✅ TypeScript ready
  • ✅ JSDoc comments
  • ✅ React 16.8+
  • ✅ Next.js compatible

💡 Pro Tips

1. Hover to Pause

All alerts automatically pause when you hover over them! The progress bar stops and resumes exactly where it left off.

coco_Alert.success('Hover over me to pause!');

2. Multiple Alerts Stack Automatically

// Show multiple alerts - they stack automatically!
coco_Alert.info('Loading...');
coco_Alert.success('Step 1 complete');
coco_Alert.success('Step 2 complete');
coco_Alert.success('All done! 🎉');

3. Quick Notifications

// 1 second quick notification
coco_Alert.success('Copied!', 1000);

4. Center Important Alerts

// Use center position for critical messages
coco_Alert.error('Your session has expired', 5000, 'center');

5. Position Override

// Container uses top-right by default
<AlertContainer position="top-right" />

// But you can override for specific alerts
coco_Alert.error('Critical error!', 5000, 'center');
coco_Alert.info('New notification', 3000, 'bottom-right');

6. Error Handler Integration

// Wrap all API calls with cocoErr for consistent error handling
import { coco_Alert, cocoErr } from 'coco-alert/react';

async function apiCall() {
  try {
    const res = await fetch('/api/endpoint');
    if (!res.ok) throw new Error(await res.text());
    return await res.json();
  } catch (error) {
    const err = cocoErr(error);
    coco_Alert.error(err.message);
    throw error;
  }
}

🎨 Alert Types & Colors

| Type | Dark Mode | Light Mode | Use Case | Icon | |------|-----------|------------|----------|------| | Success | Green glow | Green tint | Successful operations | ✓ | | Error | Red glow | Red tint | Errors, failures | ✕ | | Warning | Yellow glow | Yellow tint | Warnings, cautions | ⚠ | | Info | Blue glow | Blue tint | General information | ℹ | | Confirm | Yellow glow | Yellow tint | User confirmations | ? |


🐛 Troubleshooting

Alerts not showing?

Make sure you've added the AlertContainer to your root component:

// ✅ Correct
function App() {
  return (
    <>
      <AlertContainer />
      <YourApp />
    </>
  );
}

// ❌ Wrong - no container
function App() {
  return <YourApp />; // Won't work!
}

TypeScript errors?

Install React types:

npm install --save-dev @types/react @types/react-dom

Next.js App Router issues?

Add 'use client'; at the top of files that use alerts:

'use client';

import { coco_Alert } from 'coco-alert/react';

Theme not updating?

Make sure you're using state to control isLightMode:

// ✅ Correct - dynamic
const [isDark, setIsDark] = useState(false);
<AlertContainer isLightMode={!isDark} />

// ❌ Wrong - static
<AlertContainer isLightMode={false} />

Alerts overlapping?

Only use one AlertContainer per application. Multiple containers will cause issues.

// ✅ Correct - one container
function App() {
  return (
    <>
      <AlertContainer />
      <Router />
    </>
  );
}

// ❌ Wrong - multiple containers
function App() {
  return (
    <>
      <AlertContainer />
      <SomeComponent>
        <AlertContainer /> {/* Don't do this! */}
      </SomeComponent>
    </>
  );
}

📊 Comparison with Other Libraries

| Feature | CocoAlert | react-toastify | react-hot-toast | sonner | |---------|-----------|----------------|-----------------|--------| | Setup | Container only | Container + Provider | Container | Provider | | Light/Dark Themes | ✅ Built-in | ⚠️ Manual CSS | ⚠️ Manual CSS | ✅ Yes | | Hover to Pause | ✅ Built-in | ✅ Yes | ❌ No | ⚠️ Limited | | Independent Timers | ✅ Yes | ⚠️ Limited | ⚠️ Limited | ✅ Yes | | Confirm Dialog | ✅ Built-in | ❌ No | ❌ No | ❌ No | | Error Handler | ✅ Built-in (cocoErr) | ❌ No | ❌ No | ❌ No | | Bundle Size | 3KB | 8KB | 4KB | 6KB | | Dependencies | 0 | 2 | 1 | 3 | | TypeScript | ✅ Built-in | ✅ Yes | ✅ Yes | ✅ Yes | | Position Control | ✅ Global + Override | ✅ Yes | ✅ Yes | ⚠️ Limited |


🤝 Contributing

We welcome contributions! Here's how:

  1. Fork the repo
  2. Create a branch: git checkout -b feature/amazing-feature
  3. Make changes and test thoroughly
  4. Commit: git commit -m 'Add amazing feature'
  5. Push: git push origin feature/amazing-feature
  6. Open a Pull Request

Development Setup

# Clone the repo
git clone https://github.com/cocobase-team/coco-alert.git
cd coco-alert

# Install dependencies
npm install

# Run development server
npm run dev

# Build
npm run build

# Test
npm test

📄 License

MIT © Cocobase Team

See LICENSE for details.


🔗 Links


❤️ Support

If you find CocoAlert helpful:

  • ⭐ Star us on GitHub
  • 📦 Try our other tools at Cocobase
  • 🐦 Share on social media
  • 💬 Join our community

📝 Changelog

v1.0.0 (Latest)

  • ✨ Initial release
  • 🎨 Light & Dark themes
  • ⚡ Independent timers
  • 🎯 Hover-to-pause
  • 📍 7 position options
  • 💬 Confirm dialogs
  • 🔧 Error handler (cocoErr)
  • 📦 Zero dependencies
  • 🛠️ Full TypeScript support

Made with 💙 by Dycoder

Beautiful alerts. Full control. Zero hassle.

⭐ Star on GitHub📦 View on NPM🐛 Report Bug