Seams generates modular Rails engines inside your Rails app.
You ship one Rails app. Inside it, each feature (auth, accounts, billing, teams, and so on) lives in its own engine under engines/. Each engine has its own models, tests, and boundaries. Engines talk to each other through events, not by reaching into each other's code. Custom RuboCop cops enforce that.
Every generated file is plain Rails code in your repo. You can read it, change it, or delete it. Nothing is hidden behind the gem.
Note
Seams is the executable companion to the book Modular Rails: Architecture for the Long Game. The full guides live on the documentation site. seams-example is a reference host with every engine wired up.
| Supported | Tested in CI | |
|---|---|---|
| Ruby | 3.3 or newer | 3.3, 3.4, 4.0.7 |
| Rails | 7.1 or newer (below 9) | 8.1.4 |
| Database | PostgreSQL | PostgreSQL 18 |
Important
PostgreSQL is required. The generated engines use jsonb columns, and each engine's test suite runs against Postgres. SQLite and MySQL are not supported.
Add Seams to your Gemfile:
# Gemfile
gem "seams", "~> 0.2"Warning
Use 0.2.0 or newer. Version 0.1.0 requires Ruby 4.0 and predates many fixes, including the admin engine working and Ruby 3.3 support.
Then install the framework:
bundle install
bin/rails generate seams:install
bundle installseams:install adds the framework files, a CI workflow, a bin/seams command, and a few development gems (hence the second bundle install). Every step after this uses bin/seams.
Generate the engines you need. The order matters, because later engines build on earlier ones. Each generator can add gems to your Gemfile, so run bundle install after each one, before the next:
bin/seams core && bundle install # shared building blocks (always first)
bin/seams auth && bundle install # sign-in, sessions, OAuth, API tokens
bin/seams accounts && bundle install # the tenant (Account) and its members
bin/seams notifications && bundle install # in-app, email, and SMS notifications
bin/seams billing && bundle install # Stripe subscriptions
bin/seams teams && bundle install # optional teams inside an account
bin/seams design --shell && bundle install # UI components and an app layoutThen finish the setup:
bin/rails tailwindcss:build # the design layout loads the compiled CSS
bin/rails db:encryption:init # auth encrypts personal data; paste the printed
bin/rails credentials:edit # active_record_encryption block into credentials
bin/rails db:migrate
bin/seams list # show engines, their events, and subscribersImportant
Skip the encryption keys and sign-up fails with Missing Active Record encryption credential. Skip the Tailwind build and every page using the design layout fails with The asset 'tailwind.css' was not found.
Start the app with bin/rails server. Sign up at /auth/registration/new and sign in at /auth/session/new.
Tip
New to Seams? Follow Getting Started. It goes step by step from bundle install to a running app.
| Command | What it generates |
|---|---|
bin/seams core |
Shared basics: per-request Current attributes, an audit log, tenant scoping, an email validator. |
bin/seams auth |
Identity (the person signing in), sessions, OAuth providers, API tokens. Personal data is encrypted at rest. |
bin/seams accounts |
Account (the tenant), memberships with roles, account scoping. |
bin/seams notifications |
Notifications over in-app, email, and SMS. Choose channels with --channels in_app,email,sms (default: all). |
bin/seams billing |
Stripe subscriptions using the official stripe gem (19.x), a webhook router with 13 handlers, and lifetime deals. |
bin/seams teams |
Teams, team memberships, and invitations. Choose features with --with invitations,roles (default: all). |
bin/seams admin |
An admin area built on Administrate and Pundit. Optional. See Admin engine below. |
bin/seams design |
A design system: 33 ui_* components, Tailwind v4 theme tokens, a form builder, and a /design/guide gallery. --shell also adds an app layout and a starter dashboard. |
bin/seams permissions |
An editable map of which roles can do what, in config/initializers/seams_permissions.rb. See Permissions. |
| Command | What it does |
|---|---|
bin/rails generate seams:install |
Installs the framework, the CI workflow, and bin/seams. |
bin/seams engine <name> |
Generates an empty engine for your own feature. |
bin/seams remove <name> |
Removes an engine, cleans up references to it, and adds a migration that drops its tables. |
bin/seams list |
Lists engines, the events they publish, and who subscribes to them. |
bin/seams test <engine> |
Runs one engine's tests. |
bin/seams quality <engine> |
Runs RuboCop on one engine. |
bin/seams resolve --eject <engine>/<file> |
Marks a generated file as yours, so future runs of the generator leave it alone. Also --list-markers <engine> and --list-ejected. |
bin/rails generate seams:auth:add_oauth_provider <name> |
Adds an OAuth provider to the auth engine. |
You also get:
- Four custom RuboCop cops. Two fail the build when one engine reaches into another's code or models. The other two check background job queue names and migration comments.
- A GitHub Actions workflow that runs each engine's tests in parallel.
- A quality toolchain set up by
seams:install:- strong_migrations and lefthook git hooks are on by default. Turn them off with
--no-strong-migrationsor--no-lefthook. - herb (ERB lint) is off by default. Turn it on with
--herb.
- strong_migrations and lefthook git hooks are on by default. Turn them off with
- A Dockerfile and a Kamal
deploy.yml, written only if your app doesn't already have them. Rails 8 apps ship their own Dockerfile, which Seams leaves in place.
bin/seams admin adds an admin area at /admin. It needs the auth engine. It adds the administrate and pundit gems to your Gemfile.
Important
Only staff can open the admin area by default. Set staff: true on an Auth::Identity to let that person in:
Auth::Identity.find_by(email: "you@example.com").update!(staff: true)Signed-out visitors are sent to the sign-in page. Signed-in identities that aren't staff get a 403.
Tenant mode: let each customer's admins manage their own account
By default the admin area runs in platform mode: staff see every account. In tenant mode, an account's admins see only their own account's data.
Tenant mode needs three settings. Without the last two, tenant admins get a 403.
# config/initializers/seams_admin.rb
Seams::Admin.configure do |c|
c.tenancy_scope = :tenant
# Let any signed-in identity past the gate. The tenant policies then
# decide what each role may do.
c.authenticator = ->(ctrl) { ctrl.current_identity.present? }
# Tell the admin area which membership the request belongs to.
# This example takes the identity's first active membership. Use
# however your app picks the current account (subdomain, session, a switcher).
c.current_membership_resolver = lambda do |ctrl|
identity = ctrl.current_identity
identity && Accounts::Membership.find_by(identity_id: identity.id, active: true)
end
endWith these set:
- An
adminorownerof an account sees only that account's rows. - Requests for another account's records return 404.
- A
membergets a 403.
Step-by-step guide: Setting up the admin area. The generated engines/admin/README.md has the full reference.
Seams writes code into your app. So updating the gem does not change engines you already generated. Read the CHANGELOG before you update, and apply the changes that affect you.
Note
If you generated engines before the September 2026 changes, check these:
- solid_cable 4.1 or newer: each engine's test app needs
engines/*/spec/dummy/config/cable.yml, containingtest:withadapter: test. Without it, the engine's tests fail to load. - Billing: the generated code now targets
stripe ~> 19.0. The generated services now raiseBilling::GatewayErrorinstead ofStripe::*errors. Set your Stripe webhook endpoint to the same API version as the gem. - Admin: regenerate the admin engine, or copy the fixes listed in the CHANGELOG. Earlier versions could not boot or serve any admin page.
If you adopted Seams before Wave 9, start with the Wave 8 upgrade guide.
The documentation site has every guide below, with search. The API reference is on rubydoc.info.
Start here
- Getting Started: install, first engine, running app
- Engine catalogue: every engine in detail
- Architecture overview: why Seams is built this way
Building and extending
- Adding an engine
- Removing an engine
- Writing an adapter: swap in Mailgun, Twilio, Paddle, and others
- Writing follow-up generators
- Setting up the admin area
- Insertion points and the catalogue of markers
- Deploying
Reference
- Current attributes:
Auth::Current,Accounts::Current,Teams::Current,Core::Current - Permissions: ability codes, roles, the grant map
- Observability: logging, tracing, metrics
- Testing
Design system
- Design system overview (start here)
- Foundations: tokens and scales
- Components: the 33
ui_*components - Forms:
Design::FormBuilder - Theming
- Accessibility
Architecture history
- Wave 9: the full system walk-through, including the identity / account / team split
- Wave 10: insertion points, follow-up generators, the eject command
- Wave 11: the admin engine
- Personal data and GDPR
- Architecture Decision Records
| Instead of | Seams gives you |
|---|---|
| Bullet Train or Jumpstart Pro | The code lives in your repo, not behind a gem. Seams also enforces engine boundaries with RuboCop cops. |
rails plugin new --mountable |
Engines come wired with events, registries, observability, boundary checks, and CI. |
| Microservices | One process and one deploy. No HTTP between services. Engines talk through synchronous events with explicit subscribers. |
Note
Seams is in active development and has not reached 1.0. Breaking changes are listed in the CHANGELOG. Open work is tracked in issue #5.
Each change is checked in CI:
- RuboCop, Brakeman, and bundle-audit
- the gem's own tests, on Ruby 3.3, 3.4, and 4.0.7
- an end-to-end run that creates a new Rails app with
rails new, generates every engine, runs each engine's tests, and boots the app against Postgres
- How to contribute: CONTRIBUTING.md covers setup, the checks, and the pull request workflow. Run
bin/auditbefore you push. - Security issues: SECURITY.md
- Getting help: SUPPORT.md
- How the project is run: GOVERNANCE.md and MAINTAINERS.md
- Community expectations: CODE_OF_CONDUCT.md
- AI coding agents: AGENTS.md and llms.txt
- Citing Seams: CITATION.cff
MIT. See LICENSE.