Skip to main content

Introduction

Dynatable is a type-safe, functional TypeScript library for Amazon DynamoDB. Built with modern TypeScript features and functional programming principles, it provides a robust and developer-friendly way to work with DynamoDB.

Why Dynatable?

DynamoDB is powerful but has a steep learning curve. Dynatable simplifies DynamoDB development while maintaining full type safety and leveraging functional programming patterns.

Key Features

Type-Safe by Design

Complete TypeScript type inference from your schema definitions. Get autocomplete and compile-time error detection throughout your entire codebase.

const user = await table.entities.User.get({ username: 'alice' }).execute();
// ^? User | undefined — fully typed from your schema

Functional & Immutable

Immutable builder API that prevents side effects and makes your code more predictable and easier to reason about.

const baseQuery = table.entities.Post.query().where((attr, op) => op.eq(attr.username, 'alice'));

// Create variations without mutating the original
const recentPosts = await baseQuery.limit(10).scanIndexForward(false).execute();
const allPosts = await baseQuery.execute();

Runtime Validation

put() and batchWrite() run automatic Zod validation, enforcing your declared types and required fields at runtime:

await table.entities.User.put({
username: 'alice',
age: '25', // throws ZodError: Expected number, got string
}).execute();

update() relies on TypeScript for type safety and does not run Zod at runtime. For richer rules (email format, length, regex…), validate inputs with your own Zod schemas before calling .put() / .update().

Developer Experience First

  • Automatic timestamps (createdAt, updatedAt)
  • Built-in pagination support
  • Auto-generated IDs (ULID, UUID)
  • Single-table design patterns
  • Comprehensive transaction support
  • Efficient batch operations

Architecture Overview

Dynatable follows a layered architecture:

┌─────────────────────────────────────┐
│ Schema Definition │
(Define your data models)
└─────────────────────────────────────┘

┌─────────────────────────────────────┐
│ Table API
(Main entry point)
└─────────────────────────────────────┘

┌─────────────────────────────────────┐
│ Entity APIs │
(User, Post, Comment, etc.)
└─────────────────────────────────────┘

┌─────────────────────────────────────┐
│ Operation Builders │
(Get, Put, Query, Update, etc.)
└─────────────────────────────────────┘

Core Concepts

Before diving into Dynatable, it's helpful to understand a few core concepts:

Entities

Entities represent your data models (e.g., User, Post, Comment). Each entity has:

  • A unique key structure (partition key and optionally sort key)
  • Defined attributes with types and constraints
  • Optional automatic behaviors (timestamps, ID generation)

Builders

All operations use immutable builders that allow you to chain methods to construct your query or mutation:

const posts = await table.entities.Post.query()
.where((attr, op) => op.eq(attr.username, 'alice'))
.limit(20)
.scanIndexForward(false)
.execute();

Type Inference

Your schema is the source of truth. Types flow automatically from your schema definition to all operations:

const schema = {
format: 'dynatable:1.0.0',
version: '1.0.0',
indexes: {
primary: { hash: 'PK', sort: 'SK' },
},
models: {
User: {
key: {
PK: { type: String, value: 'USER#${username}' },
SK: { type: String, value: 'USER#${username}' },
},
attributes: {
username: { type: String, required: true },
email: { type: String, required: true },
},
},
},
} as const; // ← as const is important for type inference

// TypeScript knows exactly what fields exist
const user = await table.entities.User.get({ username: 'alice' }).execute();
console.log(user?.email); // ✅ Type-safe
console.log(user?.invalid); // ❌ TypeScript error

What's Next?

Ready to get started? Here's your learning path:

  1. Getting Started - Install and set up Dynatable
  2. Data Modeling - Learn how to design your schema
  3. Single Table Design - Master single-table patterns
  4. Queries - Read and filter your data
  5. Mutations - Create, update, and delete operations
  6. Examples - See real-world examples

Community & Support

License

MIT © 2024 Dynatable