Transform your DynamoDB experience with type-safe schemas, familiar Ecto-inspired syntax, and powerful features that make NoSQL development a joy.
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)
Built for modern Elixir developers who want the power of DynamoDB with the safety and elegance of structured schemas.
Define schemas that enforce data consistency and catch errors at compile time.
Ecto-inspired DSL that feels natural to Elixir developers.
Built-in support for batch operations and parallel scans.
Multiple configuration levels to suit your application needs.
Full support for DynamoDB transactions with clean syntax.
Mix tasks for table management and schema generation.
From simple CRUD operations to complex transactions, Dynamo makes it elegant.
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
# 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"}
)
# 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 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}}}
])
Add Dynamo to your Elixir project and start building with confidence.
# mix.exs
def deps do
[
{:dynamo, github: "bmalum/dynamo"}
]
end
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
user = %MyApp.User{
id: "user-123",
email: "john@example.com",
name: "John Doe"
}
{:ok, saved} = MyApp.User.put_item(user)
Join developers who are building scalable applications with type-safe DynamoDB operations.