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

@echo-shadow/echo-sdk

v0.1.0

Published

ECHO Shadow Traffic SDK — send shadow test results to your ECHO dashboard

Readme


What is ECHO?

ECHO is a shadow traffic testing platform. It mirrors your production API traffic to a shadow (staging) environment, compares the responses, and uses AI to classify every difference as intentional (e.g. a user updated their bio) or regressive (e.g. a rounding error in checkout totals).

This SDK is the official TypeScript client for sending shadow test results to your ECHO dashboard.

Why shadow testing?

| Problem | How ECHO solves it | |---|---| | Regressions slip through staging | ECHO compares real production traffic against your shadow env | | Manual QA can't cover every edge case | 100% of traffic is compared automatically | | Diff noise is overwhelming | AI classifies diffs as intentional vs. regressive | | You find bugs after users report them | ECHO catches mismatches before users notice |

How it works

Your API → ECHO SDK → ingest-traffic Edge Function → Dashboard
     ↓                        ↓
  Live response          Compares live vs. shadow
     ↓                        ↓
  Shadow response        Stores results + AI verdict

Install

npm install echo-shadow
# or
yarn add echo-shadow
# or
pnpm add echo-shadow

Requirements: Node.js 18+, TypeScript 5+ (optional but recommended)


Quick Start

import { createEchoClient } from "echo-shadow";

const echo = createEchoClient({
  apiKey: process.env.ECHO_API_KEY!, // echo_sk_...
});

// In your API middleware or test harness:
const liveResponse = await callProductionAPI(req);
const shadowResponse = await callShadowAPI(req);

const result = await echo.logShadowTest({
  endpoint: "/api/v1/checkout",
  liveResponse,
  shadowResponse,
  latencyMs: 142,
});

console.log(result);
// → { success: true, test_run_id: "tr_abc123", status: "fail" }

Examples

Express Middleware (fire-and-forget)

Shadow comparisons run in the background and never add latency to your live responses:

import { createEchoClient } from "echo-shadow";

const echo = createEchoClient({ apiKey: process.env.ECHO_API_KEY! });

app.use(async (req, res, next) => {
  const start = Date.now();

  const originalJson = res.json.bind(res);
  res.json = (body) => {
    // Fire-and-forget — never blocks the live response
    callShadowAPI(req).then((shadowBody) => {
      echo.logShadowTest({
        endpoint: req.path,
        liveResponse: body,
        shadowResponse: shadowBody,
        latencyMs: Date.now() - start,
      });
    }).catch(() => {});

    return originalJson(body);
  };

  next();
});

Next.js API Route

import { createEchoClient } from "echo-shadow";
import { NextResponse } from "next/server";

const echo = createEchoClient({ apiKey: process.env.ECHO_API_KEY! });

export async function POST(req: Request) {
  const body = await req.json();
  const start = Date.now();

  const liveResult = await processCheckout(body);

  // Non-blocking shadow comparison
  processCheckoutV2(body).then((shadowResult) => {
    echo.logShadowTest({
      endpoint: "/api/checkout",
      liveResponse: liveResult,
      shadowResponse: shadowResult,
      latencyMs: Date.now() - start,
    });
  }).catch(() => {});

  return NextResponse.json(liveResult);
}

Health Check

Verify your setup before sending real data:

const { reachable, authenticated } = await echo.ping();

if (!reachable) console.error("Cannot reach ECHO endpoint");
else if (!authenticated) console.error("API key is invalid");
else console.log("✅ ECHO is ready");

API Reference

createEchoClient(config: EchoConfig)

Create a new ECHO client instance.

| Option | Type | Required | Default | Description | |---|---|---|---|---| | apiKey | string | ✅ | — | Your ECHO API key (echo_sk_...) | | endpoint | string | ❌ | Hosted ECHO URL | Custom ingest endpoint |

echo.logShadowTest(params)

Send a shadow test result to ECHO for comparison.

| Param | Type | Required | Description | |---|---|---|---| | endpoint | string | ✅ | The API endpoint being tested (e.g. /api/checkout) | | liveResponse | Record<string, unknown> | ✅ | The response from your production environment | | shadowResponse | Record<string, unknown> | ✅ | The response from your shadow/staging environment | | latencyMs | number | ❌ | Round-trip latency in milliseconds (default: 0) |

Returns: Promise<ShadowTestResult>

interface ShadowTestResult {
  success: boolean;
  test_run_id?: string;      // Unique ID for this test run
  status?: "pass" | "fail" | "review";
  error?: string;            // Error message if success is false
}

Status meanings:

  • pass — Live and shadow responses are identical
  • fail — Structural or value mismatch detected (different keys or significant value differences)
  • review — Same structure, different values — needs human review

echo.ping()

Verify connectivity and API key validity.

Returns: Promise<{ reachable: boolean; authenticated: boolean }>


Error Handling

The SDK never throws. It always returns a result object:

const result = await echo.logShadowTest({ ... });

if (!result.success) {
  console.error("ECHO error:", result.error);
  // Possible errors:
  // "Invalid API key"
  // "Missing required fields: api_key, endpoint"
  // "HTTP 500" (server error)
}

TypeScript Types

All types are exported for full type safety:

import type { EchoConfig, ShadowTestResult } from "echo-shadow";

Troubleshooting

| Issue | Solution | |---|---| | Invalid API key | Regenerate a key in the ECHO dashboard → Settings | | Cannot reach endpoint | Check your network/firewall allows HTTPS to *.supabase.co | | Missing required fields | Ensure both api_key and endpoint are provided | | Status always review | This means keys match but values differ — check your shadow env data |


Self-Hosting

If you self-host the ECHO backend, pass your custom endpoint:

const echo = createEchoClient({
  apiKey: "echo_sk_...",
  endpoint: "https://your-supabase-project.supabase.co/functions/v1/ingest-traffic",
});

Publishing

cd packages/echo-sdk
npm install
npm run build
npm publish --access public

License

MIT © ECHO