Skip to content

Colored Console Output

One of ScriptIt's standout features is its beautiful colored console output that makes debugging and monitoring script execution much more pleasant and efficient.

Overview

ScriptIt automatically intercepts console methods and applies color coding based on the log level:

  • 🤍 White for console.log() - Regular information
  • 🔴 Red for console.error() - Errors and critical issues
  • 🟡 Yellow for console.warn() - Warnings and cautions
  • 🔵 Blue for console.info() - Informational messages
  • Gray for console.debug() - Debug information

Enabling Colored Console

CLI Usage

Colored console output is enabled by default when using ScriptIt CLI commands:

bash
# Colored console is enabled by default
scriptit exec my-script.js

# Interactive TUI mode (also has colored console)
scriptit run

No additional flags are needed - just use context.console in your scripts.

Library Usage

Enable console interception when creating a script runner:

typescript
import { createScriptRunner } from '@glyphtek/scriptit'

const runner = createScriptRunner({
  scriptsDir: './scripts',
  tmpDir: './tmp',
  consoleInterception: {
    enabled: true,
    useColors: true
  }
})

await runner.executeScript('my-script.js')

Using Colored Console in Scripts

For colored console output, use the fallback pattern to access the enhanced console:

javascript
// my-script.js
export async function execute(context) {
  // Use context.console with fallback to global console
  const console = context.console || global.console;
  
  console.log('This will be white');
  console.error('This will be red');
  console.warn('This will be yellow');
  console.info('This will be blue');
  console.debug('This will be gray');
}

Direct Context Console Usage

You can also use context.console directly:

javascript
// direct-context.js
export async function execute(context) {
  // Use context.console directly
  context.console.log('This will be white');
  context.console.error('This will be red');
  context.console.warn('This will be yellow');
  context.console.info('This will be blue');
  context.console.debug('This will be gray');
}

Global Console (No Colors)

Using global console directly will not have colors:

javascript
// no-colors.js
export async function execute(context) {
  // Global console - no colors, goes directly to stdout/stderr
  console.log('This will not be colored');
  console.error('This will not be colored');
}

Note: The global console is not automatically intercepted. You must use context.console or the fallback pattern to get colored output.

Advanced Usage

Object Logging

The colored console handles complex objects safely:

javascript
// object-logging.js
export const description = "Script demonstrating object logging";

export async function execute(context) {
  const console = context.console || global.console;

  const user = {
    id: 1,
    name: 'John Doe',
    email: 'john@example.com',
    preferences: {
      theme: 'dark',
      notifications: true
    }
  };

  console.log('User object:', user);
  console.info('User preferences:', user.preferences);
  
  return { user };
}

Error Objects

Error objects are formatted nicely with stack traces:

javascript
// error-logging.js
export const description = "Script demonstrating error logging";

export async function execute(context) {
  const console = context.console || global.console;

  try {
    throw new Error('Something went wrong!');
  } catch (error) {
    console.error('Caught error:', error);
    console.warn('Error message:', error.message);
  }
  
  return { errorHandled: true };
}

Arrays and Collections

Arrays and other collections are displayed clearly:

javascript
// array-logging.js
export const description = "Script demonstrating array logging";

export async function execute(context) {
  const console = context.console || global.console;

  const items = ['apple', 'banana', 'cherry'];
  const numbers = [1, 2, 3, 4, 5];

  console.log('Fruits:', items);
  console.info('Numbers:', numbers);
  
  return { items, numbers };
}

Mixed Arguments

Multiple arguments are handled gracefully:

javascript
// mixed-args.js
export const description = "Script demonstrating mixed argument logging";

export async function execute(context) {
  const console = context.console || global.console;

  const userId = 123;
  const userName = 'Alice';

  console.log('User login:', userId, userName, new Date());
  console.info('Processing user:', { id: userId, name: userName });
  
  return { userId, userName };
}

Configuration

Default Behavior

By default, colored console is disabled to maintain compatibility. Enable it explicitly when needed.

Runtime Compatibility

Colored console works across all supported runtimes:

  • Bun - Full support with optimal performance
  • Node.js - Full support with chalk integration
  • Deno - Full support with built-in color utilities

Performance Considerations

The colored console implementation is optimized for performance:

  • Minimal overhead when disabled
  • Safe object serialization prevents memory leaks
  • Efficient color rendering using platform-specific methods

Examples

Basic Logging Script

javascript
// basic-logging.js
export const description = "Basic logging script with colored console";

export async function execute(context) {
  context.console.log('Starting application...');
  context.console.info('Loading configuration');

  try {
    context.console.log('Processing data...');
    // Simulate some work
    const result = { processed: 100, errors: 0 };
    context.console.info('Processing complete:', result);
  } catch (error) {
    context.console.error('Processing failed:', error);
  }

  context.console.warn('Remember to check the logs');
  context.console.debug('Debug info: memory usage', process.memoryUsage());
  
  return { status: 'completed' };
}

Run with colors:

bash
scriptit exec basic-logging.js

Error Handling Script

javascript
// error-handling.js
export const description = "Error handling script with colored output";

function riskyOperation() {
  if (Math.random() > 0.5) {
    throw new Error('Random failure occurred');
  }
  return 'Success!';
}

export async function execute(context) {
  const console = context.console || global.console;

  console.log('Starting risky operations...');

  const results = [];

  for (let i = 1; i <= 5; i++) {
    try {
      console.info(`Attempt ${i}:`);
      const result = riskyOperation();
      console.log(`✅ ${result}`);
      results.push({ attempt: i, success: true, result });
    } catch (error) {
      console.error(`❌ Attempt ${i} failed:`, error.message);
      console.warn('Retrying...');
      results.push({ attempt: i, success: false, error: error.message });
    }
  }

  console.debug('Operation summary complete');
  return { results };
}

API Response Logging

javascript
// api-logging.js
export const description = "API response logging with colored console";

async function fetchUserData(userId) {
  const console = context.console || global.console;
  
  console.info(`Fetching data for user ${userId}`);
  
  try {
    // Simulate API call
    const response = {
      id: userId,
      name: 'John Doe',
      status: 'active'
    };
    
    console.log('API Response:', response);
    return response;
  } catch (error) {
    console.error('API Error:', error);
    throw error;
  }
}

export async function execute(context) {
  const console = context.console || global.console;

  console.log('Starting API demo...');
  
  try {
    const user = await fetchUserData(123);
    console.info('User data retrieved successfully');
    console.debug('User object keys:', Object.keys(user));
    return { user, success: true };
  } catch (error) {
    console.error('Failed to fetch user data');
    console.warn('Using fallback data');
    return { user: null, success: false, error: error.message };
  }
}

Best Practices

1. Use Appropriate Log Levels

Choose the right console method for your message:

javascript
// ✅ Good
export async function execute(context) {
  const console = context.console || global.console;
  
  console.log('User logged in');           // General information
  console.info('Cache updated');           // System information
  console.warn('API rate limit reached');  // Warnings
  console.error('Database connection failed'); // Errors
  console.debug('Variable state:', vars);  // Debug info
}

// ❌ Avoid
export async function execute(context) {
  console.error('User logged in');         // Wrong level
  console.log('Critical system failure'); // Wrong level
}

2. Provide Context

Include relevant context in your log messages:

javascript
// ✅ Good
export async function execute(context) {
  const console = context.console || global.console;
  const orderId = context.env.ORDER_ID;
  const userId = context.env.USER_ID;
  
  console.log('Processing order:', orderId, 'for user:', userId);
  console.error('Payment failed for order:', orderId, 'error:', error.message);
}

// ❌ Less helpful
export async function execute(context) {
  console.log('Processing...');
  console.error('Payment failed');
}

3. Use Structured Logging

For complex data, use objects:

javascript
// ✅ Good
export async function execute(context) {
  const console = context.console || global.console;
  
  console.info('Request processed', {
    method: 'POST',
    url: '/api/users',
    status: 201,
    duration: '45ms'
  });
}

// ❌ Less structured
export async function execute(context) {
  console.info('POST /api/users 201 45ms');
}

Troubleshooting

Colors Not Showing

If colors aren't appearing:

  1. Check the flag: Ensure --console-colors is used
  2. Terminal support: Verify your terminal supports colors
  3. Context usage: Use context.console in your scripts

Performance Issues

If you experience performance issues:

  1. Disable in production: Use colors only during development
  2. Limit object size: Avoid logging very large objects
  3. Use debug level: Use console.debug() for verbose logging

Memory Concerns

The colored console is designed to be memory-safe:

  • Objects are safely serialized to prevent circular references
  • No global console replacement to avoid memory leaks
  • Efficient color rendering with minimal overhead

Released under the MIT License.