stackscope
v2.3.0
Published
π Zero-config browser SDK for automatic log capture - console, network requests, user interactions, performance metrics, Core Web Vitals. Sends to your own Cloudflare Worker. Full TypeScript support.
Maintainers
Readme
StackScope Browser SDK
π Zero-config browser SDK for automatic log capture - console, network requests, user interactions, performance metrics, Core Web Vitals. Requires StackScope Worker (separate package) for log collection. Full TypeScript support.
π¨ Important: Known CLI Issues
If you encounter CLI issues (ERR_USE_AFTER_CLOSE, interactive prompts failing):
- β Use non-interactive setup - Complete worker setup without prompts (see Step 1 below)
- β React developers: Jump to React Quick Start
- β Troubleshooting: See Worker Setup Troubleshooting
π Requirements
β οΈ BOTH packages are required:
- π
stackscope(this package) - Browser SDK for log capture - βοΈ
stackscope-worker(separate package) - Cloudflare Worker for log processing
Without the worker, logs are only visible in browser console and NOT collected centrally. The worker is required for both development and production environments.
β¨ Key Improvements in v2.0
- π― Simplified API -
createStackScope()with auto environment detection - π Pre-built Logger - Ready-to-use
loggerobject - β‘ Utility Functions -
trackUserAction(),trackPerformance(),trackApiCall() - βοΈ React Integration - Components, hooks, and error boundaries
- π§ Environment Variables - Auto-detection for Vite, Next.js, CRA
- π¦ Better Types - Complete TypeScript definitions
- π‘οΈ Zero Vulnerabilities - Secure dependencies
Quick Start
Step 1: Deploy Your Worker Infrastructure
π Recommended: Non-Interactive Setup
# Works in CI/CD, Claude Code, and automated environments
node node_modules/stackscope/scripts/create-worker-noninteractive.cjs my-app-logs
cd my-app-logs
npm install
node deploy.js # Deploys to Cloudflare automaticallyποΈ Alternative: StackScope Worker CLI
# Install StackScope Worker CLI globally
npm install -g stackscope-worker
# Create and deploy your worker (requires interactive terminal)
stackscope-worker init my-app-logs
cd my-app-logs
stackscope-worker deployβ οΈ CLI Limitation: The
stackscope-worker initcommand requires an interactive terminal and fails in CI/CD, Claude Code, and automated environments. Use the non-interactive setup script above for these environments.
ποΈ Worker is Required: The StackScope worker is required for both development and production to receive and process logs from your application. Without it, logs are only shown in the browser console and not collected centrally.
Step 2: Install Browser SDK
npm install stackscopeStep 3: Environment Setup
Copy the environment template:
cp node_modules/stackscope/templates/.env.example .envSet your worker URL:
# .env
VITE_STACKSCOPE_WORKER_URL=https://my-app-logs.your-username.workers.devStep 4: Initialize StackScope
π New Simple API:
import { createStackScope } from 'stackscope';
// Auto-detects VITE_STACKSCOPE_WORKER_URL from environment
const stackscope = createStackScope();Traditional API:
import { init } from 'stackscope';
const stackscope = init({
workerUrl: 'https://my-app-logs.your-username.workers.dev'
});That's it! Your application now automatically captures and sends logs to your worker.
βοΈ React Quick Start
Skip the worker complexity - get started with React components immediately:
1. Install SDK
npm install stackscope2. Add React Components
import { StackScopeProvider, StackScopeErrorBoundary } from 'stackscope/react';
function App() {
return (
<StackScopeProvider config={{ debug: true }}>
<StackScopeErrorBoundary>
<YourApp />
</StackScopeErrorBoundary>
</StackScopeProvider>
);
}3. Use React Hooks
import { useStackScopeLogger } from 'stackscope/react';
function MyComponent() {
const logger = useStackScopeLogger();
const handleClick = () => {
logger.info('Button clicked', { component: 'MyComponent' });
};
return <button onClick={handleClick}>Click me</button>;
}β Complete setup required - Both SDK and Worker needed for full functionality!
π API Log Streaming (New!)
Automatically capture logs from your Cloudflare Worker APIs and stream them to StackScope for complete full-stack observability.
Quick Setup
# 1. Deploy your StackScope worker (if not done already)
npm install stackscope
node node_modules/stackscope/scripts/create-worker-noninteractive.cjs my-app-logs
cd my-app-logs && npm install && node deploy.js
# 2. Stream API logs in real-time
./stream-api-logs.sh ../my-api-worker productionWhat Gets Captured
π HTTP Requests & Responses:
{
"request": {
"url": "https://api.myapp.com/users/123",
"method": "GET",
"headers": {"authorization": "Bearer ***"},
"cf": {"country": "US", "colo": "LAX"}
},
"response": {"status": 200}
}π Worker Console Logs:
// In your API worker:
console.log('Processing user request', {userId: 123});
console.error('Database connection failed', error);
// β
Automatically captured and sent to StackScopeβ οΈ Exceptions & Errors:
{
"exceptions": [{
"name": "TypeError",
"message": "Cannot read property 'id' of undefined",
"stack": "at handler (worker.js:42:15)"
}]
}π Performance & Edge Data:
- Request timing and diagnostics
- Cloudflare edge location (colo)
- Geographic data (country, region)
- Cache status and performance metrics
Advanced Usage
Multiple Environments:
# Development environment
./stream-api-logs.sh ../my-api-worker development
# Production with custom StackScope URL
STACKSCOPE_URL="https://my-logs.workers.dev" ./stream-api-logs.sh ../my-api-workerManual Streaming:
# If you prefer direct control
cd ../my-api-worker
wrangler tail --env production --format json | \
while read -r line; do
echo "$line" | curl -X POST https://my-app-logs.workers.dev/webhook/api \
-H "Content-Type: application/json" \
-H "X-Source: api-manual" \
-d @-
doneIntegration with CI/CD:
# Background streaming in production
nohup ./stream-api-logs.sh ../my-api-worker production > api-stream.log 2>&1 &Complete Full-Stack Observability
β
Browser Logs (StackScope SDK) β Console, network, interactions, performance
β
API Logs (Wrangler tail) β Requests, responses, worker console, exceptions
Result: Single dashboard showing your entire application stack!
Features
- π Zero Configuration - Works out of the box with sensible defaults
- π Automatic Capture - Console, network, interactions, performance, navigation
- π API Log Streaming - Stream Cloudflare Worker API logs via Wrangler tail
- π Private Infrastructure - Your own Cloudflare Worker, not shared
- π± TypeScript Support - Full type definitions included
- π Global Edge - Low latency via Cloudflare's global network
- π― Customizable - Configure what to capture and how
Automatic Capture
The SDK automatically captures:
Console Logs
console.log('User action'); // β
Captured
console.error('API failed'); // β
Captured
console.warn('Deprecated'); // β
CapturedNetwork Requests
fetch('/api/users'); // β
Captured (method, URL, status, duration)
XMLHttpRequest calls; // β
CapturedUser Interactions
button.click(); // β
Captured (element, event type)
form.submit(); // β
Captured (form data summary)
input.onChange(); // β
Captured (field changes)Performance Metrics
// Core Web Vitals automatically captured:
// - Largest Contentful Paint (LCP)
// - First Input Delay (FID)
// - Cumulative Layout Shift (CLS)
// - Long tasks (>50ms)Navigation Events
window.location.href = '/new'; // β
Captured (route changes)
history.pushState(); // β
Captured (SPA navigation)
page load/reload; // β
CapturedVisibility Changes
// Page focus/blur, tab switching, page unload
window.blur(); // β
Captured
window.beforeunload(); // β
Capturedπ― New v2.0 APIs
Pre-built Logger
Import and use immediately:
import { logger } from 'stackscope';
logger.info('User logged in', { userId: 123 });
logger.error('API failed', { endpoint: '/users' });
logger.debug('Cache hit', { key: 'user:123' });Utility Functions
Ready-to-use tracking functions:
import { trackUserAction, trackPerformance, trackApiCall } from 'stackscope';
// Track user interactions
trackUserAction('button_click', { buttonId: 'signup', page: '/home' });
trackUserAction('form_submit', { formType: 'contact', fields: 5 });
// Track performance metrics
trackPerformance('api_response_time', 245, 'ms');
trackPerformance('bundle_size', 1.2, 'MB');
// Track API calls with automatic error levels
trackApiCall('/api/users', 'GET', 200, 150); // Info level
trackApiCall('/api/users', 'POST', 500, 300); // Error levelEnvironment Variables
Auto-detection for popular frameworks:
# Vite
VITE_STACKSCOPE_WORKER_URL=https://your-worker.workers.dev
VITE_STACKSCOPE_API_KEY=optional-api-key
VITE_STACKSCOPE_DEBUG=true
# Next.js
NEXT_PUBLIC_STACKSCOPE_WORKER_URL=https://your-worker.workers.dev
NEXT_PUBLIC_STACKSCOPE_API_KEY=optional-api-key
# Create React App
REACT_APP_STACKSCOPE_WORKER_URL=https://your-worker.workers.dev
REACT_APP_STACKSCOPE_API_KEY=optional-api-keyβοΈ React Integration
Error Boundary Component
Automatically catch and log React errors:
import { StackScopeErrorBoundary } from 'stackscope/react';
function App() {
return (
<StackScopeErrorBoundary>
<YourApp />
</StackScopeErrorBoundary>
);
}React Hooks
import {
useStackScopeLogger,
useUserActionTracking,
usePerformanceTracking
} from 'stackscope/react';
function MyComponent() {
const logger = useStackScopeLogger();
const { trackClick, trackFormSubmit } = useUserActionTracking();
const { trackRenderTime } = usePerformanceTracking();
useEffect(() => {
const start = performance.now();
// Component logic...
trackRenderTime('MyComponent', performance.now() - start);
}, [trackRenderTime]);
return (
<button onClick={() => trackClick('signup')}>
Sign Up
</button>
);
}Context Provider (Optional)
Wrap your app for centralized configuration:
import { StackScopeProvider } from 'stackscope/react';
function App() {
return (
<StackScopeProvider config={{ debug: true }}>
<StackScopeErrorBoundary>
<YourApp />
</StackScopeErrorBoundary>
</StackScopeProvider>
);
}Configuration
Basic Configuration
import { createStackScope } from 'stackscope';
// Auto-detects environment variables
const stackscope = createStackScope({
// Optional overrides
logLevel: 'error', // Only capture errors and above
debug: true // Verbose logging to browser console
});Advanced Configuration
import { init } from 'stackscope';
const stackscope = init({
workerUrl: 'https://your-worker.workers.dev',
apiKey: 'optional-auth-key',
// Capture controls
captureConsole: true, // Console logs
captureNetwork: true, // HTTP requests
captureInteractions: true, // User interactions
captureNavigation: true, // Page navigation
capturePerformance: true, // Performance metrics
captureVisibility: true, // Visibility events
captureResources: true, // Resource loading errors
// Transport settings
batchInterval: 2000, // ms between batch sends
maxBatchSize: 50, // max logs per batch
maxRetries: 3, // retry failed requests
retryBaseDelay: 1000, // ms delay between retries
// Filtering
logLevel: 'debug' // 'debug' | 'info' | 'warn' | 'error'
});Authentication (Optional)
If your worker requires API key authentication:
const stackscope = new StackScope({
workerUrl: 'https://your-worker.workers.dev',
apiKey: 'your-secret-key' // Set in worker via wrangler secret
});
stackscope.start();Manual Logging
In addition to automatic capture, you can log manually:
// Manual logging with metadata
stackscope.log('info', 'User completed purchase', {
userId: 12345,
amount: 99.99,
currency: 'USD'
});
stackscope.log('error', 'Payment processing failed', {
error: 'card_declined',
attemptId: 'pay_123'
});Script Tag Usage
For non-module environments:
<script src="https://unpkg.com/stackscope@latest/dist/stackscope-sdk.min.js"></script>
<script>
const stackscope = new window.stackscope.StackScope({
workerUrl: 'https://your-worker.workers.dev'
});
stackscope.start();
</script>Log Format
All logs are sent as NDJSON to your worker:
{
"level": "info",
"msg": "User login successful",
"ts": "2024-01-15T10:30:00.000Z",
"source": "browser",
"meta": {
"type": "console",
"sessionId": "sess_abc123",
"url": "https://app.example.com/login",
"userId": 12345
}
}Log Sources
browser- Frontend application logsworker- Your Cloudflare Worker logsgithub- Repository webhook events (if configured)
Log Types
console- Console outputnetwork- HTTP requestsinteraction- User interactionsnavigation- Page navigationperformance- Performance metricsvisibility- Page visibility changes
Viewing Logs
Real-time Streaming
# Stream logs from your worker
wrangler tail
# Filter with jq
wrangler tail --format json | jq 'select(.level == "error")'
wrangler tail --format json | jq 'select(.meta.type == "performance")'Worker Health Check
# Check worker deployment status
wrangler deployments list
# Test specific worker URL
curl https://your-worker.workers.dev/healthError Handling
The SDK handles errors gracefully:
const stackscope = new StackScope({
workerUrl: 'https://your-worker.workers.dev',
debug: true // Enable to see error details in console
});
// SDK will retry failed requests automatically
// and degrade gracefully if worker is unavailable
stackscope.start();Browser Compatibility
- Modern Browsers: Chrome 60+, Firefox 55+, Safari 12+, Edge 79+
- ES6 Features: Uses modern JavaScript (async/await, fetch, etc.)
- Polyfills: Not included - add if targeting older browsers
TypeScript Support
Full TypeScript definitions included:
import StackScope, { SdkConfig, LogLevel } from 'stackscope';
const config: SdkConfig = {
workerUrl: 'https://your-worker.workers.dev',
logLevel: 'error' as LogLevel,
debug: true
};
const stackscope = new StackScope(config);
stackscope.start();
// Type-safe manual logging
stackscope.log('info', 'User action', { userId: 123 });Performance
- Minimal Overhead: < 30KB minified + gzipped
- Async Operations: Non-blocking log capture and transmission
- Batched Sending: Efficient network usage
- Error Resilience: Continues working if worker is temporarily unavailable
Troubleshooting
SDK Not Capturing Logs
Check worker URL:
curl https://your-worker.workers.dev/health # Should return: {"status": "ok"}Enable debug mode:
const stackscope = new StackScope({ workerUrl: 'https://your-worker.workers.dev', debug: true // Shows detailed logs in browser console });Check browser console for CORS or network errors
Verify worker deployment:
wrangler deployments list
CORS Errors
If you see CORS errors and are using API key authentication:
# Set allowed origins in your worker
wrangler secret put CORS_ORIGINS
# Enter: https://yourdomain.com,https://localhost:3000No Logs Appearing
- Generate test activity - click buttons, navigate, trigger console logs
- Check worker logs:
wrangler tail - Verify network tab shows requests to your worker URL
- Test worker endpoints with curl (see troubleshooting above)
π¦ Two-Package Architecture
StackScope uses a two-package architecture:
1. stackscope (This Package)
- π Browser SDK - Captures logs in your web application
- π¦ Zero dependencies - Lightweight and secure
- βοΈ React integration - Components, hooks, error boundaries
- π§ Auto-configuration - Environment variable detection
2. stackscope-worker (Separate Package)
- βοΈ Cloudflare Worker - Receives and processes logs
- ποΈ Infrastructure CLI - Deployment and management tools
- π GitHub integration - Repository webhook support
- π Log processing - Enrichment and structured output
How They Work Together
Browser App (stackscope) β Network β Cloudflare Worker (stackscope-worker)
β β
Automatic capture Structured logging
Manual logging GitHub webhooks
React components Health monitoringWorker Infrastructure
Install the worker infrastructure separately:
npm install -g stackscope-worker
stackscope-worker init my-app-logs
# Follow setup instructionsThe worker:
- Receives logs from this browser SDK
- Processes and enriches log data with metadata
- Outputs structured logs to worker console
- Supports GitHub webhooks for repository events
- Provides health checks and monitoring endpoints
π§ Worker Setup Troubleshooting
CLI Issues (ERR_USE_AFTER_CLOSE, TTY Errors)
The stackscope-worker init command fails in non-interactive environments with errors like:
ERR_USE_AFTER_CLOSE: readline was closedERR_TTY_INIT_FAILED- Interactive prompts hanging in CI/CD
π Solution 1: Non-Interactive Setup Script (Recommended)
# Complete worker setup without any interactive prompts
node node_modules/stackscope/scripts/create-worker-noninteractive.cjs my-worker
# Follow the generated instructions to deploy
cd my-worker
npm install
node deploy.jsπ οΈ Solution 2: Manual Setup
# 1. Install worker package
npm install -g stackscope-worker
# 2. Find template directory
npm list -g stackscope-worker
# 3. Copy template manually
cp -r /path/to/global/node_modules/stackscope-worker/templates/worker my-app-logs
cd my-app-logs
# 4. Configure manually
# Edit wrangler.toml with your account ID
# Edit package.json name fieldOption 2: Non-Interactive Mode
# Set environment variables first
export CF_ACCOUNT_ID="your-account-id"
export CF_API_TOKEN="your-api-token"
# Try with --yes flag (may still fail)
stackscope-worker init my-app-logs --yesCommon Integration Issues
React Import Errors
# Ensure you're using the correct import path
import { StackScopeProvider } from 'stackscope/react'; // β
Correct
import { StackScopeProvider } from 'stackscope'; // β WrongEnvironment Variables Not Working
# Check your build tool's env prefix:
VITE_STACKSCOPE_WORKER_URL=... # β
Vite
NEXT_PUBLIC_STACKSCOPE_WORKER_URL=... # β
Next.js
REACT_APP_STACKSCOPE_WORKER_URL=... # β
Create React AppTypeScript Errors
# Clear TypeScript cache and reinstall
rm -rf node_modules package-lock.json
npm installNeed Help?
- π Check GitHub Issues: Known Issues
- π Report Problems: Create New Issue
- π Workers Docs: Cloudflare Workers Guide
Support
- Worker Infrastructure: Install
stackscope-workerpackage for deployment tools - Issues: GitHub Issues
- Documentation: This README for SDK usage
License
MIT License - see LICENSE for details.
