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

@ewyn/client

v0.9.0

Published

Official TypeScript SDK for Ewyn email service with full type safety

Readme

@ewyn/client

Official TypeScript SDK for the Ewyn email service with full type safety.

Installation

npm install @ewyn/client
# or
pnpm add @ewyn/client
# or
yarn add @ewyn/client

Requirements

  • Node.js 18+ (uses native fetch)
  • TypeScript 5.0+ (for type-safe features)

Quick Start

Basic Usage

import { Ewyn } from '@ewyn/client';

const client = new Ewyn({
  apiKey: 'your-api-key',
});

// Send an email using template version ID
await client.send({
  to: '[email protected]',
  subject: 'Welcome!',
  templateId: 'template-version-uuid',
  variables: {
    firstName: 'John',
    lastName: 'Doe',
  },
});

Type-Safe Usage with Template Config

Get full TypeScript autocomplete and validation by copying your template config from the dashboard (or using fetch-config). The config exposes all non-deprecated versions per template so you can keep sending an older version even after publishing a new one.

import { Ewyn } from '@ewyn/client';

// 1. Copy template config from dashboard (API Keys page) or generate with fetch-config
const config = {
  welcome: {
    name: 'Welcome Email',
    latest: 1,
    versions: {
      '1': {
        id: 'version-uuid-1',
        vars: {
          firstName: { required: true },
          lastName: { required: true },
          plan: { required: false },
        },
      },
    },
  },
  'password-reset': {
    name: 'Password Reset',
    latest: 1,
    versions: {
      '1': {
        id: 'version-uuid-2',
        vars: { resetUrl: { required: true } },
      },
    },
  },
} as const; // ← Important: use 'as const'

// 2. Initialize with config
const client = new Ewyn({
  apiKey: 'your-api-key',
  templates: config,
});

// 3. Send with full type safety (defaults to latest version)
await client.send({
  to: '[email protected]',
  subject: 'Welcome!',
  template: 'welcome',
  variables: {
    firstName: 'John',
    lastName: 'Doe',
    plan: 'Pro',
  },
});

// 4. Or send a specific version (e.g. keep using v1 after v2 is published)
await client.send({
  to: '[email protected]',
  subject: 'Welcome!',
  template: 'welcome',
  version: 1,
  variables: { firstName: 'John', lastName: 'Doe' },
});

Getting Your Template Configuration

You can get your template config in three ways:

  1. CLI (recommended) – Run npx @ewyn/client fetch-config to download config and generate ewynTemplates.ts (see Fetching template config (CLI)).
  2. Dashboard – Copy JSON from the API Keys page.
  3. API – Call the templates config endpoint with curl or your own code.

Fetching template config (CLI)

The easiest way to keep your template config in sync is to use the built-in CLI. From your project root (where you have an ewyn.config.ts or ewyn.config.js), run:

npx @ewyn/client fetch-config

This fetches your workspace’s template config from the API and writes a TypeScript file (e.g. ewynTemplates.ts) that you can import for type-safe sending.

Config file (ewyn.config.ts in project root):

  • apiKey (required): Your API key (e.g. process.env.EWYN_API_KEY)
  • configurationPath (optional): Where to write the generated file (e.g. ./src/ewynTemplates.ts). If omitted, the file is written as ./ewynTemplates.ts in the current directory.

Example ewyn.config.ts:

import type { EwynFetchConfig } from '@ewyn/client';

const config: EwynFetchConfig = {
  apiKey: process.env.EWYN_API_KEY!,
  configurationPath: './src/ewynTemplates.ts',  // optional
};

export default config;

After running fetch-config, import the generated config and pass it to the client:

import { Ewyn } from '@ewyn/client';
import { ewynTemplates } from './ewynTemplates';  // or from your configurationPath

const client = new Ewyn({
  apiKey: process.env.EWYN_API_KEY!,
  templates: ewynTemplates,
});

Note: Regenerate the config after creating or updating templates (re-run npx @ewyn/client fetch-config). The config includes all non-deprecated versions per template, so regenerating does not force you to the latest version—you can still send with an older version by passing version.

From Dashboard

  1. Go to your dashboard → API Keys page
  2. Scroll to Template Configuration section
  3. Click Copy JSON or Download
  4. Paste into your code with as const:
const config = {
  // ... paste here
} as const;

const client = new Ewyn({
  apiKey: 'your-api-key',
  templates: config, // Now fully type-safe!
});

Via API

Alternatively, fetch the config programmatically:

curl -X GET https://www.ewyn.ai/api/v1/templates/config \
  -H "Authorization: Bearer YOUR_API_KEY"

API Reference

Ewyn Class

Constructor

new Ewyn(options: EwynOptions)

Options:

  • apiKey (string, required): Your API key secret
  • templates (TemplateConfig, optional): Template configuration for name-based sending
  • maxRetries (number, optional): Maximum retries for retryable errors (default: 3)
  • timeout (number, optional): Request timeout in milliseconds (default: 30000)
  • debug (boolean, optional): Log request/retry details to stderr. Also enabled when env DEBUG contains ewyn.

Methods

send(options: SendEmailOptions): Promise<SendEmailResponse>

Send an email using a template.

Options:

  • to (string, required): Recipient email address
  • subject (string, required): Email subject line. May contain {{variable}} placeholders.
  • preheader (string, optional): Preview text. May contain {{variable}} placeholders.
  • templateId (string, optional): Template version UUID (required if template not provided)
  • template (string, optional): Template name (requires templates config)
  • version (number, optional): Major version number when using template (defaults to latest). Use this to keep sending an older version after publishing a new one.
  • variables (Record<string, string>, optional): Variables to substitute in template
  • metadata (Record<string, unknown>, optional): Additional metadata to attach
  • idempotencyKey (string, optional): Key to prevent duplicate sends (valid for 24 hours)

Returns:

{
  messageId: string;
  status: 'queued';
  queuedAt: string;
}

Throws:

  • EwynApiError: If the API request fails
  • Error: If validation fails (missing template, missing variables, etc.)

Debug logging

To see which step is running (useful when something fails):

  • CLI: The fetch-config command logs progress to stdout (Using config: ..., Fetching template config from API..., Wrote ...). For extra detail (config paths, timing), set DEBUG=ewyn before running. On errors, use DEBUG=ewyn to print the full stack.
  • SDK: Pass debug: true in the client options, or set DEBUG=ewyn in the environment. Requests, retries, and timeouts are then logged to stderr.

Error Handling

The SDK throws EwynApiError for API errors:

import { Ewyn, EwynApiError } from '@ewyn/client';

try {
  await client.send({ /* ... */ });
} catch (error) {
  if (error instanceof EwynApiError) {
    console.error('API Error:', error.status, error.message);
    console.error('Details:', error.details);
    
    if (error.isRetryable()) {
      // Handle retryable error
    }
  }
}

Error Properties:

  • status (number): HTTP status code
  • code (string, optional): Error code
  • details (unknown, optional): Additional error details
  • message (string): Error message

Error Methods:

  • isClientError(): Returns true for 4xx errors
  • isServerError(): Returns true for 5xx errors
  • isRetryable(): Returns true for 429 or 5xx errors

Idempotency

To prevent duplicate email sends, provide an idempotencyKey:

await client.send({
  to: '[email protected]',
  subject: 'Your subject',
  templateId: 'template-uuid',
  idempotencyKey: 'unique-request-id-123',
  variables: { /* ... */ },
});

If the same idempotencyKey is used within 24 hours, the API will return the original response instead of sending a duplicate email.

Retry Logic

The SDK automatically retries on:

  • 429 (Too Many Requests)
  • 5xx (Server Errors)
  • Network errors

Retries use exponential backoff (1s, 2s, 4s) up to maxRetries (default: 3).

Examples

Check out the examples directory for comprehensive examples:

Testing

# Run tests
pnpm test

# Run tests in watch mode
pnpm test:watch

Development

# Build the SDK
pnpm build

# Watch mode for development
pnpm dev

# Lint
pnpm lint

License

MIT