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

@holler2660/console-text

v0.1.0

Published

Send SMS alerts from your code with console.text()

Readme

@console-text/sdk

Get alerted when critical code paths execute. As simple as console.text('Error!') and you'll receive an SMS.

Why console.text()?

You're fast asleep. Your checkout flow breaks. You're losing thousands of dollars per hour.

Traditional approach:

  1. Set up DataDog (enterprise complexity)
  2. Configure PagerDuty (more complexity)
  3. Hope your alerts work

console.text() approach:

try {
  await processPayment(order);
} catch (error) {
  console.text('Payment failed!', { orderId: order.id });
  // You get an SMS within 5 seconds
}

That's it. One line of code. No enterprise complexity.

Installation

npm install @console-text/sdk

Quick Start

1. Initialize (once in your app)

import { init } from '@console-text/sdk';

init({
  apiKey: 'ct_live_xxxxxxxxxxxxx' // Get from dashboard
});

2. Use anywhere in your code

// In critical error handlers
try {
  await chargeCustomer(amount);
} catch (error) {
  console.text('Payment failed!', {
    customerId: customer.id,
    amount,
    error: error.message
  });
}

// In monitoring checks
if (queueDepth > 10000) {
  console.text('Queue backing up!', { depth: queueDepth });
}

// In cron jobs
if (dailyRevenue < yesterdayRevenue * 0.5) {
  console.text('Revenue drop detected!', {
    today: dailyRevenue,
    yesterday: yesterdayRevenue
  });
}

API Reference

init(options)

Initializes the SDK and adds console.text() to the global console object.

Parameters:

| Name | Type | Required | Description | |------|------|----------|-------------| | apiKey | string | Yes | Your API key (ct_live_* or ct_test_*) | | endpoint | string | No | API endpoint (default: https://api.consoletext.dev) | | debug | boolean | No | Enable debug logging (default: false) |

Example:

import { init } from '@console-text/sdk';

init({
  apiKey: process.env.CONSOLE_TEXT_API_KEY,
  debug: process.env.NODE_ENV === 'development'
});

console.text(message, metadata?, options?)

Sends an alert to your phone via SMS.

Parameters:

| Name | Type | Required | Description | |------|------|----------|-------------| | message | string | Yes | Alert message (max 500 chars, auto-truncated) | | metadata | object | No | Additional context (logged in dashboard) | | options.severity | string | No | 'info', 'warning', or 'critical' (default: 'info') |

Example:

// Simple message
console.text('Deployment complete!');

// With metadata
console.text('Database connection lost', {
  host: 'db.example.com',
  retryCount: 3
});

// With severity
console.text('Critical: Server out of memory!', {
  memUsage: '98%',
  severity: 'critical'
});

Features

✅ Never Crashes Your App

The #1 rule: Alerting failures should never break your application.

console.text('Test'); // If this fails, your app keeps running

All errors are caught and logged (if debug mode enabled). Your app never knows if the alert succeeded or failed.

✅ Smart Rate Limiting

Same message won't spam you:

// Only sends ONE SMS within 5 minutes
for (let i = 0; i < 100; i++) {
  console.text('Error in loop!');
}

Rate limiting is per-message, so different errors still get through:

console.text('Payment failed');  // ✅ Sends SMS
console.text('Database error');   // ✅ Sends SMS (different message)
console.text('Payment failed');   // ❌ Rate limited (same as first)

Pro tip: Add dynamic data to bypass rate limiting when needed:

console.text(`Payment failed at ${new Date().toISOString()}`);
// Each timestamp creates a unique message

✅ Tiny Bundle Size

  • 4.71 KB minified
  • Zero dependencies
  • Tree-shakeable ESM

✅ TypeScript Support

Full type definitions included:

import { init, AlertOptions } from '@console-text/sdk';

init({ apiKey: 'ct_live_xxx' });

const metadata: Record<string, any> = {
  userId: '123',
  timestamp: new Date()
};

const options: AlertOptions = {
  severity: 'critical'
};

console.text('Error!', metadata, options);

Environment-Specific Keys

Use test keys in development to avoid SMS costs:

// .env.development
CONSOLE_TEXT_API_KEY=ct_test_xxxxx

// .env.production
CONSOLE_TEXT_API_KEY=ct_live_xxxxx

Test keys (ct_test_*):

  • Don't send real SMS
  • Log to API console instead
  • Perfect for development/staging

Live keys (ct_live_*):

  • Send real SMS via Twilio
  • Count against your quota
  • Use in production only

Real-World Examples

Example 1: E-commerce Checkout

import { init } from '@console-text/sdk';

init({ apiKey: process.env.CONSOLE_TEXT_API_KEY });

export async function processOrder(order) {
  try {
    const payment = await stripe.charges.create({
      amount: order.total,
      source: order.paymentToken
    });

    await db.orders.create({ ...order, paymentId: payment.id });

    return { success: true };
  } catch (error) {
    // Get alerted immediately
    console.text('Checkout failed!', {
      orderId: order.id,
      amount: order.total,
      error: error.message,
      customer: order.customerId
    });

    throw error;
  }
}

Example 2: Cron Job Monitoring

import { init } from '@console-text/sdk';

init({ apiKey: process.env.CONSOLE_TEXT_API_KEY });

// Daily report generation
export async function generateDailyReport() {
  const startTime = Date.now();

  try {
    const report = await buildReport();
    await uploadToS3(report);

    const duration = Date.now() - startTime;

    // Alert if too slow
    if (duration > 300000) { // 5 minutes
      console.text('Daily report slow!', {
        duration: `${duration / 1000}s`,
        date: new Date().toISOString()
      });
    }
  } catch (error) {
    console.text('Daily report failed!', {
      error: error.message,
      date: new Date().toISOString()
    });

    throw error;
  }
}

Example 3: Health Check Monitoring

import { init } from '@console-text/sdk';

init({ apiKey: process.env.CONSOLE_TEXT_API_KEY });

// Check critical services every minute
setInterval(async () => {
  // Check database
  try {
    await db.raw('SELECT 1');
  } catch (error) {
    console.text('Database health check failed!', {
      service: 'postgresql',
      error: error.message
    });
  }

  // Check Redis
  try {
    await redis.ping();
  } catch (error) {
    console.text('Redis health check failed!', {
      service: 'redis',
      error: error.message
    });
  }

  // Check external API
  try {
    const response = await fetch('https://api.stripe.com/v1/charges');
    if (!response.ok) throw new Error(`HTTP ${response.status}`);
  } catch (error) {
    console.text('Stripe API unreachable!', {
      service: 'stripe',
      error: error.message
    });
  }
}, 60000);

Example 4: Express.js Error Handler

import express from 'express';
import { init } from '@console-text/sdk';

init({ apiKey: process.env.CONSOLE_TEXT_API_KEY });

const app = express();

// Global error handler
app.use((err, req, res, next) => {
  console.error(err);

  // Alert on 500 errors
  if (err.status === 500 || !err.status) {
    console.text('Server error!', {
      error: err.message,
      path: req.path,
      method: req.method,
      stack: err.stack?.split('\n')[0]
    });
  }

  res.status(err.status || 500).json({
    error: 'Internal server error'
  });
});

Configuration Best Practices

Use Environment Variables

// config.js
import { init } from '@console-text/sdk';

const apiKey = process.env.CONSOLE_TEXT_API_KEY;

if (!apiKey) {
  throw new Error('CONSOLE_TEXT_API_KEY environment variable required');
}

init({ apiKey });

Initialize Once

// ✅ Good - initialize in entry file
// index.js or app.js
import './config/console-text'; // Initializes SDK
import express from 'express';

const app = express();
// ... rest of app

// ❌ Bad - initializing multiple times
import { init } from '@console-text/sdk';

function handler() {
  init({ apiKey: 'xxx' }); // Don't do this
  console.text('Error');
}

Don't Log Secrets

// ❌ Bad - exposes secrets
console.text('Auth failed', {
  password: user.password,      // Never log passwords
  apiKey: config.stripeKey,     // Never log API keys
  token: session.token          // Never log tokens
});

// ✅ Good - safe logging
console.text('Auth failed', {
  userId: user.id,
  email: user.email.replace(/(.{2}).*(@.*)/, '$1***$2'), // Redact email
  reason: 'invalid_credentials'
});

Troubleshooting

Not receiving SMS?

  1. Check your API key format:

    • Live keys: ct_live_xxxxx
    • Test keys: ct_test_xxxxx (don't send SMS)
  2. Check rate limiting:

    • Same message only sends once per 5 minutes
    • Add timestamps to bypass: `Error ${Date.now()}`
  3. Check the dashboard:

    • Log in to https://consoletext.dev
    • View all alert attempts (even rate-limited ones)

Debug mode

Enable debug logging to see what's happening:

init({
  apiKey: 'ct_test_xxx',
  debug: true
});

console.text('Test');
// Logs: [console.text] Sending alert: "Test"
// Logs: [console.text] Alert sent successfully

TypeScript errors?

Make sure you're importing types correctly:

import { init, AlertOptions } from '@console-text/sdk';

// Add to global console type
declare global {
  interface Console {
    text(message: string, metadata?: Record<string, any>, options?: AlertOptions): void;
  }
}

FAQ

Q: What happens if the API is down? A: The SDK fails silently. Your app continues running. Alerts are queued and sent when the API recovers.

Q: Can I send to multiple phone numbers? A: Yes! Each API key maps to one phone number in your account settings. Create multiple API keys for team members.

Q: Does this work in browsers? A: No, console.text() is for Node.js servers only. Browsers would expose your API key.

Q: How much does it cost? A: First 100 alerts/month free. Then $0.01/alert. See pricing.

Q: Can I customize the SMS format? A: Not yet, but it's on our roadmap! Vote for features at github.com/yourorg/console-text/discussions.

Support

  • Documentation: https://docs.consoletext.dev
  • Dashboard: https://consoletext.dev
  • Issues: https://github.com/yourorg/console-text/issues
  • Email: [email protected]

License

MIT


Made with ☕ by developers tired of DataDog complexity