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

slack-live

v0.3.0

Published

Real-time updating Slack messages with progress tracking

Downloads

510

Readme

slack-live

Real-time updating Slack messages with progress tracking.

npm version TypeScript License: MIT

Features

  • Real-time message updates - Create and update Slack messages programmatically
  • Progress bars - 6 customizable ASCII progress bar styles
  • State management - Track message states (pending, running, completed, failed, cancelled)
  • Presets - Ready-to-use templates for status, progress, pipelines, and encoding jobs
  • Block Kit support - Fluent builder for rich Slack layouts
  • Rate limiting - Automatic retry with exponential backoff
  • TypeScript - Full type safety with strict mode

Installation

npm install slack-live
# or
pnpm add slack-live
# or
yarn add slack-live

Quick Start

import { SlackLive } from 'slack-live';

const slackLive = new SlackLive({
  token: process.env.SLACK_BOT_TOKEN!,
  defaultChannel: '#builds',
});

// Create a live message
const message = await slackLive.create('#builds', { text: 'Starting deployment...' });

// Update with progress
await message.setProgress(25);
await message.setText('Building Docker image...');

await message.setProgress(50);
await message.setText('Pushing to registry...');

await message.setProgress(75);
await message.setText('Deploying to production...');

// Complete the message
await message.complete('Deployment successful!');

API Reference

SlackLive Client

const client = new SlackLive({
  token: string;                      // Slack Bot Token (required)
  defaultChannel?: string;            // Default channel for messages
  defaultProgressStyle?: ProgressBarStyle; // Default progress bar style
  retryOptions?: {
    maxRetries?: number;              // Max retry attempts (default: 3)
    initialDelay?: number;            // Initial delay in ms (default: 1000)
    maxDelay?: number;                // Max delay in ms (default: 30000)
    backoffMultiplier?: number;       // Backoff multiplier (default: 2)
  };
});

Methods

  • create(channel, options, callbacks?) - Create a new live message
  • task(label, options?) - Create a task for workflow tracking
  • sync(channel, state) - Sync multiple tasks declaratively
  • getMessage(ts) - Get a message by timestamp
  • getActiveMessages() - Get all non-finished messages
  • getAllMessages() - Get all tracked messages

LiveMessage

const message = await client.create('#builds', { text: 'Hello' });

// Update content
await message.setText('New text');
await message.setBlocks(blocks);
await message.update({ text: 'Updated', blocks: [...] });

// Progress tracking
await message.setProgress(50); // Shows: [████████░░░░░░░░] 50%

// State transitions
await message.complete('Done!');   // completed state
await message.fail('Error');       // failed state
await message.cancel('Stopped');   // cancelled state

Task API

Higher-level abstraction for workflow steps:

const task = client.task('Processing files', { channel: '#builds' });

await task.start();
await task.update({ progress: 25, status: 'Reading files...' });
await task.log('Processed file1.txt');
await task.log('Processed file2.txt');
await task.update({ progress: 75, status: 'Writing output...' });
await task.succeed('All files processed!');

Sync API

Declarative task synchronization:

// Separate messages (one per task)
await client.sync('#builds', {
  layout: 'separate',
  tasks: [
    { id: 'build', label: 'Build', status: 'completed', progress: 100 },
    { id: 'test', label: 'Test', status: 'running', progress: 60 },
    { id: 'deploy', label: 'Deploy', status: 'pending' },
  ],
});

// Combined message (all tasks in one)
await client.sync('#builds', {
  layout: 'combined',
  tasks: [...],
});

Presets

Ready-to-use message templates:

Status Preset

await client.presets.status('#builds', {
  title: 'Deployment',
  status: 'running',
  subtitle: 'Building Docker image...',
});
// Renders:
// 🔄 *Deployment*
// Building Docker image...

Progress Preset

await client.presets.progress('#builds', {
  title: 'Video Encoding',
  progress: 45,
  details: [
    { label: 'Format', value: 'H.264' },
    { label: 'ETA', value: '2m 30s' },
  ],
});
// Renders:
// 🔄 *Video Encoding*
// [███████░░░░░░░░░] 45%
//
// *Format:* H.264
// *ETA:* 2m 30s

Pipeline Preset

await client.presets.pipeline('#builds', {
  title: 'CI/CD Pipeline',
  steps: [
    { name: 'Build', status: 'completed' },
    { name: 'Test', status: 'running', progress: 60 },
    { name: 'Deploy', status: 'pending' },
  ],
});
// Renders:
// *CI/CD Pipeline*
// ────────────────────
// ✅ Build
// 🔄 Test [██████░░░░] 60%
// ⏳ Deploy

Encoding Job Preset

await client.presets.encodingJob('#builds', {
  title: 'video.mp4',
  jobId: '12345',
  source: { duration: '1:30', resolution: '4K', size: '500MB' },
  formats: [
    { name: '1080p', status: 'completed', size: '100MB', duration: '30s' },
    { name: '720p', status: 'running', progress: 65 },
    { name: '480p', status: 'pending' },
  ],
  links: { manifest: 'https://example.com/manifest.json' },
});

Updating Presets

Each preset returns a specialized message class that preserves the config state and provides typed update methods:

// Create an encoding job
const job = await client.presets.encodingJob('#builds', {
  title: 'video.mp4',
  formats: [
    { name: '1080p', status: 'pending' },
    { name: '720p', status: 'pending' },
  ],
});

// Update a specific format by name
await job.updateFormatByName('1080p', { status: 'running', progress: 25 });

// Update progress
await job.updateFormatByName('1080p', { progress: 75 });

// Complete the format
await job.updateFormatByName('1080p', {
  status: 'completed',
  size: '100MB',
  duration: '30s',
});

// Complete job with links
await job.completeWithLinks({
  manifest: 'https://cdn.example.com/manifest.m3u8',
});

Available preset message classes:

| Preset | Class | Key Methods | | ------------- | -------------------- | --------------------------------------------------------------------------------- | | status | StatusMessage | updatePreset(), complete(), fail() | | progress | ProgressMessage | updatePreset(), setProgressValue(), complete() | | pipeline | PipelineMessage | updatePreset(), updateStep(), updateStepByName() | | encodingJob | EncodingJobMessage | updatePreset(), updateFormat(), updateFormatByName(), completeWithLinks() |

BlockBuilder

Fluent builder for Slack Block Kit:

import { BlockBuilder } from 'slack-live';

const blocks = new BlockBuilder()
  .header('Deployment Status')
  .divider()
  .progressSection({ title: 'Building', progress: 75, status: 'running' })
  .sectionWithFields([
    { label: 'Environment', value: 'Production' },
    { label: 'Version', value: 'v2.1.0' },
  ])
  .context(['Last updated: just now'])
  .build();

await message.setBlocks(blocks);

Progress Bar Styles

Six built-in styles:

| Style | Example | | --------- | -------------------------- | | blocks | [████████░░░░░░░░] 50% | | equals | [========........] 50% | | arrows | [>>>>>>>>--------] 50% | | braille | ⣿⣿⣿⣿⣿⣿⣿⣿⣀⣀⣀⣀⣀⣀⣀⣀ 50% | | minimal | 50% ━━━━━━━━━━────────── | | emoji | 🟩🟩🟩🟩🟩⬜⬜⬜⬜⬜ 50% |

await message.setProgress(50, { style: 'emoji', width: 10 });

Status Emojis

| State | Emoji | | ----------- | ----- | | pending | ⏳ | | running | 🔄 | | completed | ✅ | | failed | ❌ | | cancelled | ⚪ |

Lifecycle Callbacks

await client.create(
  '#builds',
  { text: 'Hello' },
  {
    onSent: (snapshot) => console.log('Message sent:', snapshot.ts),
    onUpdated: (snapshot) => console.log('Message updated'),
    onCompleted: (snapshot) => console.log('Message completed'),
    onFailed: (snapshot, error) => console.log('Message failed:', error),
    onCancelled: (snapshot) => console.log('Message cancelled'),
  }
);

Slack App Setup

  1. Create a new Slack App at api.slack.com/apps
  2. Add the following Bot Token Scopes:
    • chat:write - Send messages
    • chat:write.public - Send to public channels without joining
  3. Install the app to your workspace
  4. Copy the Bot User OAuth Token (starts with xoxb-)

App Manifest

{
  "display_information": {
    "name": "Live Updates Bot",
    "description": "Real-time progress updates"
  },
  "features": {
    "bot_user": {
      "display_name": "Live Updates",
      "always_online": true
    }
  },
  "oauth_config": {
    "scopes": {
      "bot": ["chat:write", "chat:write.public"]
    }
  }
}

Contributing

See CONTRIBUTING.md for guidelines.

License

MIT - see LICENSE for details.


This library was built with the assistance of AI.