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

@everystack/server

v0.4.27

Published

Server runtime primitives for Lambda — event adapters, routing, SSR, image processing

Readme

@everystack/server

Lambda runtime primitives for building serverless applications with SST. Provides event adapters, routing, database connection, SSR, image processing, migrations, and background job handling.

Install

pnpm add @everystack/server

Entry Points

| Export | Purpose | |--------|---------| | @everystack/server | Lambda handler, router, event adapters, logging | | @everystack/server/db | SST Resource-linked database connection | | @everystack/server/ssr | Expo web SSR bundle serving | | @everystack/server/image | On-demand image resizing via Sharp | | @everystack/server/media | Fingerprinted media asset URL resolver | | @everystack/server/migrate | Drizzle migration runner | | @everystack/server/worker | SQS job queue consumer | | @everystack/server/stubs | esbuild bundling helpers for client packages |

Quick Start

import { createLambdaHandler } from '@everystack/server';
import { createDb, getJwtSecret } from '@everystack/server/db';
import { runMigrations } from '@everystack/server/migrate';
import { createWorkerHandler } from '@everystack/server/worker';
import * as schema from '../db/schema';

const { db } = createDb(schema);

// API Lambda
export const handler = createLambdaHandler({
  init: async () => ({
    api: createApiHandler(db),
  }),
  routes: (h) => [
    { path: '/api', handler: h.api },
  ],
  onAction: async (action, payload) => {
    // CLI invocations via IAM-authed Lambda invoke
    if (action === 'migrate') return runMigrations(db, './drizzle');
    if (action === 'seed') return runSeed(db);
  },
});

// Worker Lambda
export const worker = createWorkerHandler(async () => ({
  'email:send': async (payload) => { /* ... */ },
  'image:process': async (payload) => { /* ... */ },
}));

Main Export (@everystack/server)

createLambdaHandler(options)

The primary entry point. Wraps initialization, routing, and error handling into a Lambda handler.

interface LambdaHandlerOptions {
  init: () => Promise<Record<string, Handler>>;
  routes: (handlers: Record<string, Handler>) => Route[];
  fallback?: (handlers: Record<string, Handler>) => Handler;
  onAction?: (action: string, payload: unknown, handlers: Record<string, Handler>) => Promise<unknown>;
}

Behavior:

  • Lazy-initializes handlers once, caches across warm invocations
  • Detects CLI invocations (events with _action field) and dispatches to onAction
  • Sets Cache-Control: private, no-store (authenticated) or public, s-maxage=300 (public GET)
  • Guards response size (5MB max for Function URLs)
  • Adds x-request-id from Lambda trace or UUID

createRouter(routes, fallback?)

Path/method dispatcher.

interface Route {
  path: string;        // URL prefix match
  method?: string;     // HTTP method filter (optional)
  exact?: boolean;     // Exact path match (default: prefix)
  handler: Handler;
}

Routes match by prefix unless exact: true. First match wins.

eventToRequest(event)

Converts AWS API Gateway V2 events to Web Standard Request objects.

responseToResult(response)

Converts Web Standard Response to API Gateway V2 results. Auto-detects and base64-encodes binary content.

log(level, message, meta?)

Structured JSON logging to stdout with ISO timestamp.

Database (@everystack/server/db)

SST Resource-linked database helpers. All credentials come from SST's Resource linking — no env vars needed.

createDb(schema, options?)

Lazy singleton Drizzle connection via postgres.js.

const { db } = createDb(schema, { maxConnections: 1 });

Pool defaults: max 1, idle timeout 60s, connect timeout 5s, max lifetime 5min, SSL required.

getDatabaseUrl()

Returns PostgreSQL connection URL from SST Resources.

getJwtSecret()

Returns JWT secret as Uint8Array from Resource.JwtSecret.value.

Database operations (dbPlugin)

dbPlugin registers the operator actions the CLI invokes over IAM-authed Lambda invoke (no HTTP, no shared secret). Add it to the ops Lambda's plugin list; it runs on the privileged operator connection (ctx.adminDb).

import { dbPlugin } from '@everystack/server/plugin';

dbPlugin({
  migrationsFolder: join(__dirname, 'drizzle'),
  seed: runSeed,                              // optional — registers `seed` (dev only)
  schemas: ['auth', 'public', 'drizzle'],     // db:reset drop set (dev only)
  backupBucket: Resource.Backups.name,        // private bucket for logical backups
  forceRlsCarveouts: ['ops.runs'],            // ENABLE-not-FORCE tables db:doctor shouldn't flag
});

Actions contributed (each is an everystack db:* command):

| Action | Does | |---|---| | migrate / seed / db:reset | run migrations, seed (dev), drop+remigrate (dev) | | db:psql / db:query | connection info / read-only SQL via Lambda | | db:doctor | audit: is the API connection least-privilege + RLS-subject? Flags BYPASSRLS, un-FORCEd RLS, and app-reachable tables without RLS | | db:provision | create the least-privilege role chain on an existing DB (idempotent; roles only) | | db:backup | dispatched to the Fargate Task lane: pg_dump -Fc → gzip → S3 (streamed), fingerprint-stamped; awaits the child exit code, deletes the partial on failure | | db:backups | list a stage's backups | | db:restore | S3 → gunzip → pg_restore --clean --if-exists (requires confirm:true) | | db:authz:probe | run the CLI-built authorization red-team SQL in a rolled-back transaction | | console / console:meta | the operator REPL (db, schema, models, auth in scope) |

Backup options

| Option | Type | Description | |---|---|---| | backupBucket | string | Private S3 bucket for logical backups. Pass Resource.Backups.name. Unset → db:backup/db:backups/db:restore return "backup storage not configured"; the rest of the plugin is unaffected. | | backupRegion | string | Region for the backups bucket. Defaults to the Lambda's AWS_REGION. | | forceRlsCarveouts | string[] | App-owned tables intentionally ENABLE-not-FORCE RLS (owner must write them), so db:doctor doesn't flag them. auth.users is always carved out. |

Logical backups need the pg_dump Lambda layer — see docs/backups.md. Credentials reach pg_dump/pg_restore as PG* env vars, never on argv.

Web SSR (@everystack/server/ssr)

Serves Expo web builds deployed via @everystack/cli.

getWebHandler(db, storage)

Returns a Request→Response handler for the latest web release.

  • Queries database for latest platform='web' release
  • Downloads and extracts brotli-compressed tar archive to /tmp/web-build/
  • Caches handler with 60s TTL (re-queries for new releases)
  • Returns null if no web release exists

downloadAndExtract(storage, storagePrefix)

Downloads {prefix}/bundle.tar.br from storage, decompresses with brotli, extracts to /tmp/web-build/.

extractTar(data, destDir)

Pure JavaScript POSIX tar extractor. Required because Lambda doesn't include the tar binary.

Image Processing (@everystack/server/image)

On-demand image resizing via Sharp (provided as Lambda layer).

createImageHandler(config)

interface ImageHandlerConfig {
  bucket: string;          // S3 bucket name
  region?: string;         // AWS region (default: AWS_REGION env)
  pathPrefix?: string;     // URL prefix (default: '/media/')
  cacheControl?: string;   // Cache-Control header (default: 'public, max-age=86400, s-maxage=31536000, stale-while-revalidate=60')
  validateKey?: (key: string) => boolean | Promise<boolean>;  // Optional key validator
  s3Cache?: {              // Persist rendered images to S3 (skip Sharp on repeat requests)
    enabled: boolean;
    prefix?: string;       // S3 key prefix (default: 'cache/')
  };
  observability?: boolean; // Emit cache-state + timing headers (default: true)
}

URL format: /media/{key}?w=400&h=300&fit=cover&fm=webp&q=80&dpr=2

Behavior:

  • Fetches original from S3, processes with Sharp, returns with cache headers
  • All images get EXIF auto-rotation and format conversion (default: webp q80)
  • With s3Cache enabled: checks S3 for a cached render before processing, writes result to S3 after first render. Subsequent requests from any CloudFront region skip Sharp entirely.

Observability headers

When observability is enabled (default), image responses carry additive, non-sensitive headers that double as production render-time monitoring. They do not change Cache-Control, Vary, status, or body.

| Header | Set on | Meaning | | ---------------- | ----------------- | ------------------------------------------------ | | x-image-cache | both image paths | hit = served from S3 render cache (no Sharp); render = freshly rendered | | x-render-ms | render path only | ms spent in Sharp | | x-image-ms | both image paths | total handler wall time (entry → response) | | x-fetch-ms | both image paths | ms to GET the original/cached object from S3 | | Server-Timing | both image paths | devtools mirror: cache;desc=…, s3;dur=…, render;dur=…, total;dur=… |

Telling the three pipeline states apart — CloudFront edge hit vs. S3 render-cache hit vs. fresh render. Read CloudFront's x-cache first:

| x-cache (CloudFront) | x-image-cache (Lambda) | meaning | | ---------------------- | ------------------------ | ------------------------------------ | | Hit from cloudfront | (ignore — stale) | EDGE HIT, Lambda not invoked | | Miss from cloudfront | hit | S3 RENDER-CACHE HIT, no Sharp | | Miss from cloudfront | render | FRESH RENDER (x-render-ms = Sharp time) |

Caveat: CloudFront caches the response including these headers and replays them on edge hits, so on an edge hit x-image-cache reflects the original render, not this request. The x-image-* headers are authoritative only when x-cache is a Miss. Always read x-cache first.

Set observability: false to suppress all of the above.

deleteImageCache(bucket, key, options?)

Deletes all cached renders for an image key. Call when the original is deleted or replaced.

import { deleteImageCache } from '@everystack/server/image';

const deleted = await deleteImageCache('my-bucket', 'uploads/photo.jpg');
// deleted = number of cached objects removed

Options: { region?: string; prefix?: string } (prefix defaults to 'cache/').

purgeImage(bucket, key, options?)

Delete all S3 cached renders and invalidate CloudFront cache for an image. Combines deleteImageCache with KVS path invalidation.

import { purgeImage } from '@everystack/server/image';

const { deleted, invalidated } = await purgeImage('my-bucket', 'uploads/photo.jpg', {
  kvsArn: process.env.KVS_ARN,
});

Options: { region?: string; prefix?: string; kvsArn?: string; pathPrefix?: string }. KVS invalidation is skipped when kvsArn is omitted.

parseParams(query)

Validates URL query params into transform options:

| Param | Range | Description | |-------|-------|-------------| | w | 1–4096 | Width | | h | 1–4096 | Height | | fit | cover, contain, fill, inside, outside | Resize fit | | fm | webp, jpeg, png, avif | Output format | | q | 1–100 | Quality | | dpr | 1–3 | Device pixel ratio (multiplies w/h) |

Media Assets (@everystack/server/media)

Resolves logical media asset paths to fingerprinted CDN URLs. During everystack update, media assets are uploaded with content-hash suffixes (e.g., logo-a1b2c3d4.png) and a media-manifest.json is written to the media bucket. This module loads that manifest and resolves URLs at runtime.

createMediaResolver(config)

import { createMediaResolver } from '@everystack/server/media';

const media = createMediaResolver({
  bucket: Resource.Media.name,  // S3 bucket with media-manifest.json
  cdnUrl: process.env.CDN_URL,  // CDN base URL (no trailing slash)
  ttlMs: 60_000,                // Manifest cache TTL (default: 1 minute)
});

resolve(logicalPath)

Async. Returns the fingerprinted CDN URL. Falls back to the logical path if the manifest is unavailable or the path isn't mapped.

const logoUrl = await media.resolve('email/logo.png');
// → "https://cdn.example.com/email/logo-a1b2c3d4.png"

resolveSync(logicalPath)

Sync. Uses the cached manifest only. Returns null if no manifest has been loaded yet.

const url = media.resolveSync('og/default.png');
// → "https://cdn.example.com/og/default-f6e5d4c3.png" or null

preload()

Loads the manifest during Lambda init. Call this in createLambdaHandler's init to amortize the S3 call across all requests.

export const handler = createLambdaHandler({
  init: async () => {
    await media.preload();
    return { api };
  },
  // ...
});

Caching behavior:

  • Manifest cached in module scope across warm Lambda invocations
  • After TTL expires, revalidates via HeadObject ETag comparison (one cheap HEAD call)
  • Full re-fetch only when the manifest content changes
  • S3 errors return stale cache gracefully

Migrations (@everystack/server/migrate)

runMigrations(db, migrationsFolder)

Runs Drizzle migrations from the specified folder. Called via onAction handler (CLI → IAM → Lambda invoke).

  • Returns { success: true, message: 'Migrations applied' }
  • Throws on error (caller handles response)

Worker (@everystack/server/worker)

createWorkerHandler(init)

SQS Lambda handler with type-based job dispatch.

type JobHandler = (payload: any, job: { id: string; type: string }) => Promise<void>;

const worker = createWorkerHandler(async () => ({
  'email:send': async (payload) => { /* ... */ },
  'image:process': async (payload) => { /* ... */ },
}));
  • Lazy-initializes handlers, caches across warm invocations
  • Parses SQS message body as { jobId, type, payload }
  • Returns batchItemFailures for partial failure handling (failed messages retry)

Stubs (@everystack/server/stubs)

clientStubs

Array of client-side package names to exclude from Lambda bundles via esbuild external.

stubsDir

Path to no-op module stubs. Used with SST copyFiles to prevent "module not found" errors when server code transitively imports client packages.

// sst.config.ts
import { clientStubs, stubsDir } from '@everystack/server/stubs';

new sst.aws.Function('Api', {
  handler: 'server/api.handler',
  nodejs: {
    esbuild: { external: clientStubs },
  },
  copyFiles: [{ from: stubsDir, to: 'stubs' }],
});

Peer Dependencies

  • sst — Resource linking for credentials
  • drizzle-orm — Database ORM
  • postgres — PostgreSQL driver
  • sharp — Image processing (optional, Lambda layer)
  • @aws-sdk/client-s3 — S3 operations (image handler)
  • @aws-sdk/s3-request-presigner — Presigned URLs (image handler)
  • @everystack/cli — Storage adapter (SSR handler)

Part of everystack — a self-hosted application stack for Expo apps on AWS.

License

AGPL-3.0-only © Scalable Technology, Inc.

A commercial license is available for organizations that cannot or do not wish to comply with the AGPL-3.0 terms. For commercial licensing, contact [email protected].