Elixir 1.16+

Elegant DynamoDB DSL for Elixir

Transform your DynamoDB experience with type-safe schemas, familiar Ecto-inspired syntax, and powerful features that make NoSQL development a joy.

Type-Safe Schema Definition
Ecto-Inspired Familiar Syntax
Production Ready
user.ex
defmodule MyApp.User do
  use Dynamo.Schema

  item do
    table_name "users"
    
    field :id, partition_key: true
    field :email, sort_key: true
    field :name
    field :role, default: "user"
    field :created_at, default: &DateTime.utc_now/0
    field :active, default: true
    
    # Validation
    validates :email, format: ~r/@/
    validates :name, presence: true
  end
end

# Create user with validation
user = %MyApp.User{
  id: UUID.uuid4(),
  email: "alice@example.com",
  name: "Alice Johnson",
  role: "admin"
}

{:ok, saved_user} = MyApp.User.put_item(user)

Why Choose Dynamo?

Built for modern Elixir developers who want the power of DynamoDB with the safety and elegance of structured schemas.

🛡️

Type Safety

Define schemas that enforce data consistency and catch errors at compile time.

Familiar Syntax

Ecto-inspired DSL that feels natural to Elixir developers.

🚀

Performance

Built-in support for batch operations and parallel scans.

🔧

Flexible Config

Multiple configuration levels to suit your application needs.

📊

Transactions

Full support for DynamoDB transactions with clean syntax.

🛠️

CLI Tools

Mix tasks for table management and schema generation.

See It In Action

From simple CRUD operations to complex transactions, Dynamo makes it elegant.

Define Your Schema
defmodule MyApp.Product do
  use Dynamo.Schema

  item do
    table_name "products"
    
    field :category_id, partition_key: true
    field :product_id, sort_key: true
    field :name
    field :price
    field :stock, default: 0
    field :active, default: true
  end
end
CRUD Operations
# Create
product = %MyApp.Product{
  category_id: "electronics",
  product_id: "smartphone-123",
  name: "iPhone 15",
  price: 999.99
}
{:ok, saved} = MyApp.Product.put_item(product)

# Read
{:ok, product} = MyApp.Product.get_item(%MyApp.Product{
  category_id: "electronics",
  product_id: "smartphone-123"
})

# List all products in category
{:ok, products} = MyApp.Product.list_items(
  %MyApp.Product{category_id: "electronics"}
)
Advanced Queries
# Query with conditions
{:ok, products} = MyApp.Product.list_items(
  %MyApp.Product{category_id: "electronics"},
  [
    sort_key: "smartphone",
    sk_operator: :begins_with,
    filter_expression: "price > :min_price",
    expression_attribute_values: %{
      ":min_price" => %{"N" => "500"}
    },
    scan_index_forward: false
  ]
)

# Parallel scan for large datasets
{:ok, all_products} = Dynamo.Table.parallel_scan(
  MyApp.Product,
  segments: 8
)
Batch Operations
# Batch write multiple items
products = [
  %MyApp.Product{category_id: "electronics", product_id: "phone-1", name: "iPhone", price: 999},
  %MyApp.Product{category_id: "electronics", product_id: "laptop-1", name: "MacBook", price: 1999},
  %MyApp.Product{category_id: "books", product_id: "book-1", name: "Elixir Guide", price: 29}
]

{:ok, result} = Dynamo.Table.batch_write_item(products)

# Transactions
Dynamo.Transaction.transact([
  {:update, %Account{id: "acc-1"}, %{balance: {:decrement, 100}}},
  {:update, %Account{id: "acc-2"}, %{balance: {:increment, 100}}}
])

Get Started in Minutes

Add Dynamo to your Elixir project and start building with confidence.

1

Install

# mix.exs
def deps do
  [
    {:dynamo, github: "bmalum/dynamo"}
  ]
end
2

Define Schema

defmodule MyApp.User do
  use Dynamo.Schema
  
  item do
    table_name "users"
    field :id, partition_key: true
    field :email, sort_key: true
    field :name
  end
end
3

Start Building

user = %MyApp.User{
  id: "user-123",
  email: "john@example.com",
  name: "John Doe"
}

{:ok, saved} = MyApp.User.put_item(user)

Ready to Transform Your DynamoDB Experience?

Join developers who are building scalable applications with type-safe DynamoDB operations.