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

@eggai-sdk/core

v0.1.1

Published

EGGai — four SDKs, one behaviour model. Offer optimization, lead generation, survey response and assortment optimization over EGGai-v1.

Readme

eggai — the EGGai Node.js SDK

Four SDKs, one behaviour model. This package is the official Node.js client for api.eggai.tech: offer optimization, lead generation, survey response and assortment optimization over EGGai-v1, a Large Behavior Model grounded in real till history.

Zero runtime dependencies — written in TypeScript, compiled to ESM on the global fetch, declarations included. Node 18+.

npm install @eggai-sdk/core

Requirements

| | Floor | Why | |---|---|---| | Node | 18.0+ | global fetch (18.0) and AbortSignal.timeout (17.3) — no HTTP dependency, no polyfill | | TypeScript | 4.7+ | declarations resolve through the exports map, so moduleResolution must be node16, nodenext or bundler |

This package is ESM-only — "type": "module", no CommonJS build:

import { EggAI } from '@eggai-sdk/core';            // any supported Node
const { EggAI } = await import('@eggai-sdk/core');  // from CommonJS

require('@eggai-sdk/core') resolves only on Node 22.12+ / 20.19+, where require() of ESM landed; on earlier 18.x and 20.x it throws ERR_REQUIRE_ESM — use the dynamic import() above.

Authenticate

Every client takes a workspace API key (issued in the EGGai app under Settings → API keys). Pass it directly, or set EGGAI_API_KEY once:

export EGGAI_API_KEY="pk_live_..."

Practice keys work everywhere live keys do, but are capped per job so you can integrate without spending real volume. EGGAI_BASE_URL overrides the endpoint when you are pointed at staging.

The four products

import { EggAI } from '@eggai-sdk/core';

const client = new EggAI();          // reads EGGAI_API_KEY

// 1 · Offer Optimization — what is the least this customer would accept?
const terms = await client.offers.cheapestAccepted({
  customer:   'c_8813',
  profile:    'shops fortnightly, small baskets, coupon-led',
  offer:      'Fresh Picks Weekend — 15% off produce, min spend 500',
  guidelines: 'discount caps at 12%, min spend above 300.',
});
terms.text;       // "8% off produce, min spend 349"
terms.tagline;    // "Weekend Picks"
terms.changed;    // ["discount", "min_spend", "tagline"]
terms.objection;  // "threshold above my usual basket"

// 2 · Lead Generation — which of these people is worth the call?
const ranked = await client.leads.rank(
  { c_8813: 'fortnightly, coupon-led', c_2291: 'weekly family shop' },
  {
    offer:       'Fresh Picks Weekend — 15% off produce',
    guidelines:  'hold the 15%, the aisle may change',
    tailorOffer: true,
  },
);
ranked.at(0).score;   // 0.71
ranked.at(0).reason;  // "buys dairy most weeks, produce rarely"
ranked.above(0.5);    // the slice worth calling

// 3 · Survey Response (preview) — what would a panel of your customers say?
const result = await client.surveys.ask(
  'Would you switch to our own-brand line?',
  {
    options: ['Definitely', 'Maybe', 'No'],
    panel:   'shoppers aged 18-55 who buy fresh produce most weeks',
    n:       150,
  },
);
result.distribution;         // { Definitely: 0.21, Maybe: 0.44, No: 0.35 }
result.crosstab('segment');  // the same spread, split by trait

// 4 · Assortment Optimization — who follows the shelf, and who walks?
const impact = await client.assortment.impact(customers, {
  scenario: {
    kind:      'delist',
    category:  'chilled juice',
    change:    'Tropicana Orange 1L 119',
    remaining: 'own-label 1L 79 · Malee 1L 95',
  },
});
impact.retained;            // 0.91 of category spend kept
impact.counts;              // { switches: 214, leaves_store: 6 }
impact.watchlist;           // who walks, and the basket at stake
impact.rows[0].substitute;  // where the demand lands

Or import a product directly, as the product pages show:

import { OfferOptimizer } from '@eggai-sdk/core';
const terms = await new OfferOptimizer(apiKey).cheapestAccepted({ ... });

Jobs, streaming, results

Every batch call is a job on EGGai's servers. wait: false hands you the job instead of the result:

const job = await client.leads.rank(customers, { offer, wait: false });
for await (const ev of job.stream()) {      // progress / live / twin events
  console.log(ev.stage ?? ev.text);
}
const ranked = new RankedLeads(await job.resultRows());

client.assortment.preview(panel, { scenario }) answers sampled what-ifs synchronously (≤64 rows, nothing persisted). client.score(rows) returns bare probabilities for up to 64 rows. client.usage('2026-08') is the same metering rollup billing reads.

Errors

Everything thrown on purpose subclasses EggAIError and carries the server's own message: AuthenticationError, InvalidRequestError, RateLimitError, FeatureNotEnabledError (Survey Response is preview, enabled per workspace), JobFailedError (with .job), APIError.

Docs

Full documentation: docs.eggai.tech — concepts, CSV schemas, the REST reference underneath this client, and the studies behind each product.