dyno-table
v2.3.3
Published
A TypeScript library to simplify working with DynamoDB
Downloads
200
Maintainers
Readme
dyno-table
A powerful, type-safe DynamoDB library for TypeScript that simplifies working with DynamoDB through intuitive APIs and comprehensive type safety.
Why dyno-table?
- Type Safety First - Full TypeScript support with compile-time error checking
- Schema Validation - Built-in support for Zod, ArkType, Valibot, and other validation libraries
- Semantic Queries - Write meaningful method names like
getDinosaurBySpecies()instead of crypticgsi1references - Single-Table Design - Optimized for modern DynamoDB best practices
- Repository Pattern - Clean, maintainable code architecture
Quick Start
npm install dyno-table @aws-sdk/client-dynamodb @aws-sdk/lib-dynamodbimport { z } from "zod";
import { defineEntity, createIndex, createQueries } from "dyno-table/entity";
const createQuery = createQueries<typeof dinosaurSchema._type>();
// 🦕 Define your dinosaur schema
const dinosaurSchema = z.object({
id: z.string(),
species: z.string(),
period: z.enum(["triassic", "jurassic", "cretaceous"]),
diet: z.enum(["herbivore", "carnivore", "omnivore"]),
discoveryYear: z.number(),
weight: z.number(),
});
// Create your entity with indexes for efficient queries
const DinosaurEntity = defineEntity({
name: "Dinosaur",
schema: dinosaurSchema,
primaryKey: createIndex()
.input(z.object({ id: z.string() }))
.partitionKey(({ id }) => `DINO#${id}`)
.sortKey(() => "PROFILE"),
indexes: {
byDiet: createIndex()
.input(dinosaurSchema)
.partitionKey(({ diet }) => `DIET#${diet}`)
.sortKey(({ species }) => species),
},
queries: {
getDinosaursByDiet: createQuery
.input(z.object({ diet: z.enum(["herbivore", "carnivore", "omnivore"]) }))
.query(({ input, entity }) =>
entity.query({ pk: `DIET#${input.diet}` }).useIndex("byDiet")
),
},
});
// Start using it!
const dinoRepo = DinosaurEntity.createRepository(table);
// Create a T-Rex
const tRex = await dinoRepo.create({
id: "t-rex-1",
species: "Tyrannosaurus Rex",
period: "cretaceous",
diet: "carnivore",
discoveryYear: 1905,
weight: 8000,
}).execute();
// Find all carnivores (efficient query using index!)
const carnivores = await dinoRepo.query
.getDinosaursByDiet({ diet: "carnivore" })
.execute();That's it! You now have a fully type-safe, validated database with semantic queries.
Feature Overview
Entity Pattern (Recommended)
Schema-validated, semantic queries with business logic
// Get specific dinosaur
const tRex = await dinoRepo.get({ id: "t-rex-1" });
// Semantic queries
const cretaceousDinos = await dinoRepo.query
.getDinosaursByPeriod({ period: "cretaceous" })
.execute();Direct Table Operations
Low-level control for advanced use cases
// Direct DynamoDB access with query
const carnivoresInCretaceous = await table
.query({ pk: "PERIOD#cretaceous" })
.filter(op => op.eq("diet", "carnivore"))
.execute();Advanced Querying & Filtering
Complex business logic with AND/OR operations
// Find large herbivores from Jurassic period using query + filter
const conditions = await dinoRepo.query
.getDinosaursByDiet({ diet: "herbivore" })
.filter(op => op.and(
op.eq("period", "jurassic"),
op.gt("weight", 3000)
))
.execute();Batch Operations
Efficient bulk operations
// Get multiple dinosaurs at once
const dinos = await dinoRepo.batchGet([
{ id: "t-rex-1" },
{ id: "triceratops-1" },
{ id: "stegosaurus-1" }
]).execute();
// Bulk create carnivores
const batch = table.batchBuilder();
carnivores.forEach(dino =>
dinoRepo.create(dino).withBatch(batch)
);
await batch.execute();Transactions
ACID transactions for data consistency
// Atomic dinosaur discovery
await table.transaction(tx => [
dinoRepo.create(newDinosaur).withTransaction(tx),
researchRepo.update(
{ id: "paleontologist-1" },
{ discoveriesCount: val => val.add(1) }
).withTransaction(tx),
]);Pagination & Memory Management
Handle large datasets efficiently
// Stream large datasets (memory efficient)
const allCarnivores = await dinoRepo.query
.getDinosaursByDiet({ diet: "carnivore" })
.execute();
for await (const dino of allCarnivores) {
await processDiscovery(dino); // Process one at a time
}
// Paginated results
const paginator = dinoRepo.query
.getDinosaursByDiet({ diet: "herbivore" })
.paginate(50);
while (paginator.hasNextPage()) {
const page = await paginator.getNextPage();
console.log(`Processing ${page.items.length} herbivores...`);
}Schema Validation
Works with any Standard Schema library
// Zod (included)
const dinoSchema = z.object({
species: z.string().min(3),
weight: z.number().positive(),
});
// ArkType
const dinoSchema = type({
species: "string>2",
weight: "number>0",
});
// Valibot
const dinoSchema = v.object({
species: v.pipe(v.string(), v.minLength(3)),
weight: v.pipe(v.number(), v.minValue(1)),
});Performance Optimization
Built for scale
// Use indexes for fast lookups
const jurassicCarnivores = await dinoRepo.query
.getDinosaursByPeriodAndDiet({
period: "jurassic",
diet: "carnivore"
})
.useIndex("period-diet-index")
.execute();
// Efficient filtering with batchGet for known species
const largeDinos = await dinoRepo.batchGet([
{ id: "t-rex-1" },
{ id: "triceratops-1" },
{ id: "brontosaurus-1" }
]).execute();Documentation
Getting Started
- Quick Start Tutorial → - Get up and running quickly
- Installation Guide → - Setup and configuration
- Your First Entity → - Create your first entity
Core Concepts
- Entity vs Table → - Choose your approach
- Single Table Design → - DynamoDB best practices
- Key Design Patterns → - Partition and sort keys
Features
- Query Building → - Complex queries and filtering
- Schema Validation → - Type safety and validation
- Transactions → - ACID operations
- Batch Operations → - Bulk operations
- Pagination → - Handle large datasets
- Type Safety → - TypeScript integration
Advanced Topics
- Performance → - Optimization strategies
- Error Handling → - Robust error management
- Migration → - Evolving your schema
Examples
- E-commerce Store → - Product catalog and orders
- User Management → - Authentication and profiles
- Content Management → - Blog posts and comments
- Analytics → - Event tracking and reporting
Links
- Documentation - Complete guides and references
- Issues - Report bugs or request features
- Discussions - Ask questions and share ideas
- NPM - Package information
