The Ruby ecosystem, championed by frameworks like Rails, has long prioritized developer happiness and convention over configuration. Yet, when it comes to the database, that happiness is often tested. You find yourself managing the ceremony of ActiveRecord migrations, fighting with complex query interfaces, or sacrificing the structure you value for the flexibility of a schemaless NoSQL database.
StatelyDB brings the joy back to data persistence for Ruby developers. We believe your database should feel as elegant and productive as the language you love. Through our schema-first workflow and powerful code generation, we eliminate boilerplate and give you clean, plain old Ruby objects (POROs) to work with. Stop wrestling with your data layer and start building.
As a Ruby developer, you have likely encountered these common data-layer frustrations:
Every rake db:migrate is a source of stress. A small change requires a carefully written migration that could lock tables, cause downtime, and is difficult to roll back, especially at scale.
For all its power, ActiveRecord can be a heavy abstraction. You end up with a complex object model that can obscure what is actually happening in the database, leading to performance surprises.
You turn to a NoSQL solution for flexibility but lose the structure and validation you need. Your application code becomes littered with defensive checks to handle inconsistent data shapes returned from the database.
You spend time writing manual data mappers or serializers to translate between your database's representation and your application's domain objects.
These issues introduce friction and risk, slowing down your ability to ship features and innovate.
StatelyDB is designed to provide a developer experience that feels native to the Ruby philosophy: simple, elegant, and productive.
Your single source of truth is a TypeScript-based Elastic Schema™ file in your repository. This schema defines the shape of your data and serves as the blueprint for your generated Ruby code.
// schema/schema.ts
import { itemType, string, uuid } from "@stately-cloud/schema";
/** A user of our new application. */
itemType("User", {
keyPath: "/user-:id",
fields: {
id: { type: uuid, initialValue: "uuid" },
name: { type: string },
email: { type: string },
},
});
Run a single command to generate a Ruby library containing POROs for every item in your schema. This is not a complex ORM; it is just clean, idiomatic Ruby.
stately schema generate \
--language ruby \
--schema-id <your-schema-id> \
./lib/stately_clientThis generates a set of files you can require in your application, giving you classes like StatelyDB::Types::User.
With the generated code, working with StatelyDB is as simple as initializing a Ruby object. Our API is minimal and intuitive.
Compare the simplicity of StatelyDB with the verbosity of a raw NoSQL driver like DynamoDB's.
StatelyDB: Simple and Clean
require_relative './lib/stately_client/stately'
def create_user(client, name, email)
# Create and put a simple Ruby object.
user_to_create = StatelyDB::Types::User.new(
name: name,
email: email
)
created_user = client.put(user_to_create)
puts "Created user with ID: #{created_user.id}"
created_user
end
Typical DynamoDB SDK: Verbose and Complex
require 'aws-sdk-dynamodb'
def create_user(dynamo_client, name, email)
user_id = SecureRandom.uuid
# Manually construct the item hash with type annotations.
item = {
'PK' => "USER##{user_id}",
'SK' => 'METADATA',
'id' => user_id,
'name' => name,
'email' => email
}
# Construct and send the verbose request.
dynamo_client.put_item({
table_name: 'my-table',
item: item
})
# Return the manually constructed object.
{ id: user_id, name: name, email: email }
end
With StatelyDB, you write less code, it is easier to read, and you eliminate an entire class of potential errors. You can focus on your application's business logic, not the ceremony of database interaction.
The most powerful feature for a growing application is the ability to change. When your product needs evolve, simply update your schema.ts file, add a migration command, and regenerate your Ruby code. StatelyDB's Elastic Schema ensures your changes are always backwards and forwards compatible. You can deploy new code with confidence, knowing you will not break older versions of your application, all without the stress of traditional database migrations.
StatelyDB is designed to provide a developer experience that feels native to the Ruby philosophy: simple, elegant, and productive.
Your single source of truth is a TypeScript-based Elastic Schema™ file in your repository. This schema defines the shape of your data and serves as the blueprint for your generated Ruby code.
// schema/schema.ts
import { itemType, string, uuid } from "@stately-cloud/schema";
/** A user of our new application. */
itemType("User", {
keyPath: "/user-:id",
fields: {
id: { type: uuid, initialValue: "uuid" },
name: { type: string },
email: { type: string },
},
});
Run a single command to generate a Ruby library containing POROs for every item in your schema. This is not a complex ORM; it is just clean, idiomatic Ruby.
stately schema generate \
--language ruby \
--schema-id <your-schema-id> \
./lib/stately_clientThis generates a set of files you can require in your application, giving you classes like StatelyDB::Types::User.
With the generated code, working with StatelyDB is as simple as initializing a Ruby object. Our API is minimal and intuitive.
Compare the simplicity of StatelyDB with the verbosity of a raw NoSQL driver like DynamoDB's.
StatelyDB: Simple and Clean
require_relative './lib/stately_client/stately'
def create_user(client, name, email)
# Create and put a simple Ruby object.
user_to_create = StatelyDB::Types::User.new(
name: name,
email: email
)
created_user = client.put(user_to_create)
puts "Created user with ID: #{created_user.id}"
created_user
end
Typical DynamoDB SDK: Verbose and Complex
require 'aws-sdk-dynamodb'
def create_user(dynamo_client, name, email)
user_id = SecureRandom.uuid
# Manually construct the item hash with type annotations.
item = {
'PK' => "USER##{user_id}",
'SK' => 'METADATA',
'id' => user_id,
'name' => name,
'email' => email
}
# Construct and send the verbose request.
dynamo_client.put_item({
table_name: 'my-table',
item: item
})
# Return the manually constructed object.
{ id: user_id, name: name, email: email }
end
With StatelyDB, you write less code, it is easier to read, and you eliminate an entire class of potential errors. You can focus on your application's business logic, not the ceremony of database interaction.
The most powerful feature for a growing application is the ability to change. When your product needs evolve, simply update your schema.ts file, add a migration command, and regenerate your Ruby code. StatelyDB's Elastic Schema ensures your changes are always backwards and forwards compatible. You can deploy new code with confidence, knowing you will not break older versions of your application, all without the stress of traditional database migrations.
Ready to work with a database that values developer happiness as much as you do?
Follow our Getting Started Guide to create your account, store, and schema.
Install the Ruby SDK: Add it to your Gemfile and run bundle install. gem 'statelydb'
Generate your Ruby client code as shown above.
Initialize the client and start building.
It is that simple