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

@aws-blocks/bb-data

v0.1.1

Published

Full PostgreSQL database — provisions Aurora Serverless v2 by default, or connects to an existing PostgreSQL database (Supabase, Neon, etc.) via `fromExisting()`. Full relational modeling with foreign keys, transactions, Row Level Security, and a type-saf

Readme

@aws-blocks/bb-data

Full PostgreSQL database — provisions Aurora Serverless v2 by default, or connects to an existing PostgreSQL database (Supabase, Neon, etc.) via fromExisting(). Full relational modeling with foreign keys, transactions, Row Level Security, and a type-safe Kysely query builder.

When to use: Complex multi-table JOINs, ACID transactions, foreign key constraints, aggregations, Row Level Security, or connecting to an existing PostgreSQL database. Use when you need the full power of PostgreSQL.

When NOT to use: For simple key-value lookups, use KVStore. For NoSQL with secondary indexes, use DistributedTable. For serverless SQL without FK/RLS/triggers (multi-region, instant provisioning), use DistributedDatabase.

Quick Start

import { Database, sql } from '@aws-blocks/bb-data';

const db = new Database(scope, 'main', {
  migrationsPath: './aws-blocks/migrations',
});

// Parameterized queries via sql tagged template (injection-safe)
const users = await db.query<{ id: string; name: string }>(
  sql`SELECT * FROM users WHERE active = ${true}`
);

const user = await db.queryOne<{ id: string; name: string }>(
  sql`SELECT * FROM users WHERE id = ${userId}`
);

const { rowCount } = await db.execute(
  sql`INSERT INTO users (id, name, email) VALUES (${id}, ${name}, ${email})`
);

// Transactions
await db.transaction(async (tx) => {
  await tx.execute(sql`UPDATE accounts SET balance = balance - ${100} WHERE id = ${fromId}`);
  await tx.execute(sql`UPDATE accounts SET balance = balance + ${100} WHERE id = ${toId}`);
});

Migrations

Create numbered .sql files in a migrations directory:

aws-blocks/migrations/
  001_create_users.sql
  002_create_posts.sql
  003_seed_admin.sql
-- 001_create_users.sql
CREATE TABLE users (
  id TEXT PRIMARY KEY,
  email TEXT UNIQUE NOT NULL,
  name TEXT NOT NULL,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Migrations run automatically:

  • Local dev: On first query (PGlite, persists in .bb-data/)
  • AWS deploy: Via a CustomResource Lambda during cdk deploy

Applied migrations are tracked in a _migrations table. Each file runs once.

Kysely Query Builder

For type-safe queries without raw SQL:

import { createKyselyAdapter } from '@aws-blocks/bb-data';

interface Schema {
  users: { id: string; email: string; name: string };
  posts: { id: string; user_id: string; title: string };
}

const kysely = createKyselyAdapter<Schema>(db);

// Type-safe SELECT
const users = await kysely
  .selectFrom('users')
  .where('email', '=', '[email protected]')
  .selectAll()
  .execute();

// JOINs
const posts = await kysely
  .selectFrom('posts')
  .innerJoin('users', 'users.id', 'posts.user_id')
  .select(['posts.title', 'users.name'])
  .execute();

// Transactions
await kysely.transaction().execute(async (trx) => {
  await trx.insertInto('users').values({ id: '1', email: '[email protected]', name: 'A' }).execute();
  await trx.insertInto('posts').values({ id: '1', user_id: '1', title: 'Hello' }).execute();
});

See Kysely documentation for the full query builder API.

Row Level Security (RLS)

Scope queries to a user context with Supabase-compatible session variables:

const scoped = db.withRLS({ userId: 'user-123', role: 'authenticated' });

// All queries on `scoped` run inside a transaction with SET LOCAL ROLE
// and request.jwt.claims set — PostgreSQL RLS policies are enforced.
const myPosts = await scoped.query<Post>(sql`SELECT * FROM posts`);

Local (PGlite) prerequisite: withRLS issues SET LOCAL ROLE <role> (default authenticated). PGlite has no such role by default, so a migration must create it or local queries fail with role "authenticated" does not exist. Add to your migrations:

CREATE ROLE authenticated;
CREATE ROLE anon;
-- grant table privileges to these roles as needed, then define RLS policies

CRUD Handlers

Generate typed CRUD methods from a schema definition:

const crud = db.crud({
  tables: ['users', 'posts'],
  // `auth` takes no arguments — close over your request context to resolve the user.
  auth: async () => {
    const user = await auth.requireAuth(context);
    return { userId: user.userId };
  },
});

// Auto-generated flat method names per table:
//   crud.listUsers(), crud.getUser(id), crud.createUser(data),
//   crud.updateUser(id, data), crud.deleteUser(id)
//   crud.listPosts(), crud.getPost(id), ...

Connecting to an Existing Database

import { Database, fromExisting } from '@aws-blocks/bb-data';

// Supabase, Neon, or any PostgreSQL-compatible database
const db = new Database(scope, 'external', {
  connection: fromExisting({ connectionString: process.env.DATABASE_URL! }),
});

Migrating from Supabase

Already have a Supabase app? bb-data pull connects to your existing Supabase database and generates a complete, type-safe backend — keeping your tables, data, and RLS policies exactly as they are.

npx bb-data pull

What it does:

  • Introspects your public-schema tables (read-only — your database is not modified)
  • Generates typed definitions, CRUD operations, and a personalized migration guide
  • Stores your connection string locally (encrypted in SSM on deploy)

What it does NOT migrate: Supabase Auth, Storage, Realtime, or Edge Functions. If you use a third-party OIDC provider (Auth0, Clerk, Google, Cognito), you can wire it into Blocks — see the generated MIGRATION_GUIDE.md#auth.

After pulling, run npm run dev to start developing locally against your real database.

Once pulled, manage schema changes with version-controlled SQL migrations in ./migrations/ — applied automatically on npm run dev and npm run deploy. See the generated MIGRATION_GUIDE.md#evolving-your-schema.

Error Handling

import { DatabaseErrors } from '@aws-blocks/bb-data';
import { isBlocksError } from '@aws-blocks/core';

try {
  await db.execute(sql`INSERT INTO users (id, email) VALUES (${id}, ${email})`);
} catch (e: unknown) {
  if (isBlocksError(e, DatabaseErrors.UniqueConstraintViolation)) {
    // Duplicate key — email already exists
  }
  if (isBlocksError(e, DatabaseErrors.QueryFailed)) {
    // General query failure (syntax error, missing table, etc.)
  }
  if (isBlocksError(e, DatabaseErrors.TransactionFailed)) {
    // Transaction could not commit
  }
  if (isBlocksError(e, DatabaseErrors.SerializationFailure)) {
    // Serializable-isolation conflict with a concurrent transaction — safe to retry
  }
  if (isBlocksError(e, DatabaseErrors.ConnectionFailed)) {
    // Cannot reach the database
  }
}

What It Provisions (AWS)

  • Aurora Serverless v2 — PostgreSQL-compatible, scales 0.5-128 ACUs
  • VPC — Private subnets (isolated, no NAT)
  • RDS Proxy — Connection pooling
  • Secrets Manager — Auto-generated credentials, auto-rotated
  • Migration Lambda — Runs .sql files on deploy via CustomResource
  • IAMrds-data:* and secretsmanager:GetSecretValue granted to the app Lambda

Local Development

  • Engine: PGlite (WASM PostgreSQL) — full Postgres compatibility
  • Storage: .bb-data/{fullId}/ — persists across restarts, wipe with rm -rf .bb-data
  • Migrations: Run automatically on first query

Configuration

interface DatabaseOptions {
  /** Path to directory containing numbered .sql migration files. */
  migrationsPath?: string;
  /** Connect to an existing database instead of provisioning one. */
  connection?: ExternalDatabaseRef;
  /** Schema metadata for crud() support. */
  schema?: TableSchema;
}

Package Export Conditions

{
  "exports": {
    ".": {
      "cdk": "./dist/index.cdk.js",
      "aws-runtime": "./dist/index.aws.js",
      "default": "./dist/index.mock.js"
    }
  }
}

Performance

  • Query latency: 10-50ms (warm), ~500ms cold start from 0 ACUs
  • Throughput: Thousands of concurrent connections via RDS Proxy
  • Storage: Up to 128 TiB, auto-scales in 10 GiB increments
  • Cost: ~$0.12/ACU-hour + ~$0.10/GB-month storage
  • Durability: 6 copies across 3 AZs, 99.99% availability