# Cartridges

> For agents: start with the [agent guide](https://ratstack.sh/llms.txt). Every page is Markdown by default; add `Accept: text/html` for HTML.

New on /news: [tla-ts 0.0.9 adds TLC's -continue](/news).

A cartridge is a package that owns one job and the resources it needs.
A service is the named interface callers use for that job. Its service tag identifies the service.
A Layer describes how to build services and supply their dependencies.

An Alchemy Layer can also declare the cloud resources behind a service.
`Layer.provide` supplies the chosen implementation to the application.
Replacing that Layer changes the implementation and its dependencies without changing callers.

The database cartridge makes this concrete. `DatabaseVendor` represents either D1 or Hyperdrive Postgres.
`packages/database/src/d1.ts` [declares the D1 schema and database](/lore/infrastructure-as-effects#worked-example-a-d1-layer).

`packages/database/src/hyperdrive-postgres.ts` declares the Postgres schema, Hyperdrive connection, and migration registration.
Both provide the same `RunLog` service. The auth cartridge consumes `DatabaseVendor`.

`packages/auth/src/auth.ts` picks Better Auth's D1 or Hyperdrive adapter.

A cartridge must:

- Have a label.
- Add with one package and one Layer or Alchemy Stack line.
- Remove without breaking unrelated packages.
- Declare the bindings that give it access to its resources.
- Be easy to throw away.

Removal must leave no loose resources or broken imports. Delete the package and its provision line, then run `pnpm turbo run check test build`.

[Analytics](/systems/analytics) is a second running example: `packages/events` owns capture and its Basin resources. [README](/README.md) lists the steps needed to remove it. `packages/subscriber-delivery` is a provider adapter behind core's ports. One-line infrastructure removal remains unproven for that package.

## Where the pattern comes from

This project calls the pattern a "cartridge". Sam describes Layers as a way to carry infrastructure and permissions with a service, and calls the idea "SaaS as NPM." [devtools.fm, 21:15](https://youtu.be/MtKHzAH6uXM?t=1275). He also describes swapping implementations by providing different Layers. [Effect Office Hours 27, 34:35](https://youtu.be/fPSxB7ZgSJw?t=2075).

Interchangeability between provider implementations remains unproven. Sam describes test or development Layers for infrastructure and a type error when code still requires a removed binding. [Happy Path 116, 15:25](https://youtu.be/YEn4A7XxgF4?t=925) [Effect Office Hours 27, 07:05](https://youtu.be/fPSxB7ZgSJw?t=425).

See [one capability, every surface](/lore/one-capability-every-surface) for the shared contract and [a clean playground](/lore/a-clean-playground) for the house rule behind these boundaries.

## Sources

1. [rat-stack/VISION.md at main · joelhooks/rat-stack · GitHub](https://github.com/joelhooks/rat-stack/blob/main/VISION.md)
   GitHub joelhooks/rat-stack. Cartridge criteria; used for labeling, composition, removal, and self-containment. Accessed 2026-10-01.

2. [rat-stack/packages/database/src/vendor.ts at main · joelhooks/rat-stack · GitHub](https://github.com/joelhooks/rat-stack/blob/main/packages/database/src/vendor.ts)
   GitHub joelhooks/rat-stack. Database vendor boundary; used for the D1 and Hyperdrive example. Accessed 2026-10-01.

3. [rat-stack/packages/auth/src/auth.ts at main · joelhooks/rat-stack · GitHub](https://github.com/joelhooks/rat-stack/blob/main/packages/auth/src/auth.ts)
   GitHub joelhooks/rat-stack. Auth composition; used for the cartridge that consumes the database vendor. Accessed 2026-10-01.

## Lore on this page

- [Auth](/systems/auth)
- [Bindings](/lore/bindings)
- [A clean playground](/lore/a-clean-playground)

## Linked from

- A clean playground → rat-stack does real work with packages that stay easy to add and remove. → [Read page](https://ratstack.sh/lore/a-clean-playground)

- A Layer as constructor → Sam Goodwin compares an Effect Layer that builds a service to a constructor. → [Read page](https://ratstack.sh/lore/layer-constructor-pattern)

- A service captures its construction dependencies → Build a service with its dependencies, then expose methods that callers can use without rebuilding the graph. → [Read page](https://ratstack.sh/lore/services-capture-dependencies)

- add-a-store → Add persistence through a service named for an application job, with validation, vendor Layers, migrations, bounded reads, and shared backend tests. → [Read page](https://ratstack.sh/skills/add-a-store)

- Agent guide → An Effect stack so pure (aspirational) Kit Langton will blush. → [Read page](https://ratstack.sh/llms.txt)

- Agent rules for rat-stack (AGENTS.md) → What you may change, which commands to run, and which changes need approval. → [Read page](https://ratstack.sh/AGENTS.md)

- An MCP your users want → Rhys Sullivan's practical guide gives rat-stack a checklist for useful MCP tools. → [Read page](https://ratstack.sh/lore/an-mcp-your-users-want)

- Analytics → One event per HTTP request, stored unchanged for queries to select and interpret later. → [Read page](https://ratstack.sh/systems/analytics)

- Auth → Email and password sign-in through Better Auth, with the signed-in person provided to each RPC call. → [Read page](https://ratstack.sh/systems/auth)

- Bindings → Sam Goodwin describes bindings as the place where runtime permissions and configuration meet infrastructure. → [Read page](https://ratstack.sh/lore/bindings)

- Capture first, shape later → Store events without rejecting them for an evolving event shape, then decide their shape when you query. → [Read page](https://ratstack.sh/lore/capture-first)

- Change log → What changed in the files served here, newest first. → [Read page](https://ratstack.sh/log)

- Database → One interface records action runs and their outcomes in either Cloudflare D1 or Postgres through Hyperdrive. → [Read page](https://ratstack.sh/systems/database)

- Durability → Seven durable Effect patterns, each with its seam, its fence, and the incident that taught it. → [Read page](https://ratstack.sh/systems/durability)

- Effect + Alchemy peer patterns → Source-grounded patterns from repos on nearby Effect and Alchemy pins. → [Read page](https://ratstack.sh/resources/same-version-repos)

- Effect + Alchemy peers → Public repositories that share rat-stack's prerelease lines. → [Read page](https://ratstack.sh/resources/peers)

- Feature flags → Typed feature flags with owners, removal dates, and stable subject rollouts. → [Read page](https://ratstack.sh/systems/flags)

- Full agent guide → An Effect stack so pure (aspirational) Kit Langton will blush. → [Read page](https://ratstack.sh/llms-full.txt)

- Hexagonal architecture → Ports name the application's jobs; adapters connect them to the outside world. → [Read page](https://ratstack.sh/lore/hexagonal-architecture)

- Hosted agent interfaces → Discovery documents, HTTP, MCP, A2A, and bounded code mode expose the public reference to agents. → [Read page](https://ratstack.sh/systems/agent-front-door)

- Infrastructure as effects → Sam Goodwin relates application operations to infrastructure requirements in one typed program. → [Read page](https://ratstack.sh/lore/infrastructure-as-effects)

- Layer composition makes dependencies explicit → Supply a service's dependencies, choose which services remain visible, and reuse Layer identity within a build. → [Read page](https://ratstack.sh/lore/layers-make-dependencies-explicit)

- Learn mode presents concepts at useful depths → An agent presents source-derived concepts during real work and keeps learning events in a private local log. → [Read page](https://ratstack.sh/systems/learn)

- Learn the stack | rat-stack → Hands-on guides to Effect actions, XState lifecycles, and the seams between stack pieces. → [Read page](https://ratstack.sh/skills)

- One capability, every surface → A schema-typed contract and one handler feed every interface rat-stack keeps. → [Read page](https://ratstack.sh/lore/one-capability-every-surface)

- Property-based testing → State a rule that must hold for every input, then let a generator hunt for the smallest input that breaks it. → [Read page](https://ratstack.sh/lore/property-based-testing)

- Purpose and boundaries of rat-stack (VISION.md) → What this starter is for and what a useful copy should keep. → [Read page](https://ratstack.sh/VISION.md)

- query-design → Design or review SQL reads, writes, scans, backfills, and slow database paths. Use before changing a store method or any loop that queries. Covers round-trip arithmetic, batching, keyset paging, index evidence, row budgets, PlanetScale Vitess limits, Hyperdrive connections, statement-count tests, and statement-template fences. → [Read page](https://ratstack.sh/skills/query-design)

- Rat Stack lore | rat-stack → Short, source-grounded notes on the ideas and decisions behind rat-stack. → [Read page](https://ratstack.sh/lore)

- Rat Stack systems | rat-stack → The systems rat-stack ships, the standard each keeps, and how to check it. → [Read page](https://ratstack.sh/systems)

- rat-stack → An Effect stack so pure (aspirational) Kit Langton will blush. → [Read page](https://ratstack.sh/)

- rat-stack-mode → Route non-trivial rat-stack code, data, design, investigation, and documentation tasks to every matching playbook and principle. → [Read page](https://ratstack.sh/skills/rat-stack-mode)

- Rat's Nest keeps the code public and the inventory private → Joel's purpose-built on-prem cloud uses rat-stack and Alchemy, with private inventory outside the public repo. → [Read page](https://ratstack.sh/lore/rats-nest)

- Source change history (log.md) → The generated change log as Markdown. → [Read page](https://ratstack.sh/log.md)

- Structure an Effect codebase by domain → Start with folders for application work, services and Layers in the same file, and startup code that supplies implementations. → [Read page](https://ratstack.sh/lore/structure-effect-by-domain)

- Tests prove behavior through supplied services → Supply services through Layers, choose properties or models for domain rules, and reject tests that cannot detect broken behavior. → [Read page](https://ratstack.sh/lore/tests-that-earn-their-place)

- Turbo remote cache → A separate Worker stores streamed Turbo artifacts in R2, with one credential per team and lifecycle expiry. → [Read page](https://ratstack.sh/systems/turbo-cache)

- uncomplect → Find responsibilities that a rat-stack design combines, separate them into capabilities, cartridges, machines, features, and clients, and enforce that separation through types and checks. Use when asked to simplify, review, or replace a design, "what would Rich Hickey do", "optimize for deletion", or "define this error out of existence". → [Read page](https://ratstack.sh/skills/uncomplect)

- Worker init runs twice → Alchemy Worker initialization runs in deploy and runtime contexts, so resource declarations need a boundary. → [Read page](https://ratstack.sh/lore/init-runs-twice)

## Unlinked mentions

- [A clean playground](https://ratstack.sh/lore/a-clean-playground) → md describes the cartridge test.

- [Agent rules for rat-stack (AGENTS.md)](https://ratstack.sh/AGENTS.md) → Role: Better Auth cartridge over the chosen DatabaseVendor: Auth, CurrentPerson, and the RPC middleware that provides it; only Unauthenticated crosses the wire.

- [Analytics](https://ratstack.sh/systems/analytics) → The cartridge does not prove that a delete physically erases a row by a known time.

- [Auth](https://ratstack.sh/systems/auth) → It uses the implementation chosen by the database cartridge.

- [Effect + Alchemy peer patterns](https://ratstack.sh/resources/same-version-repos) → Use one BetterAuth service with the database cartridge’s selected Layer.

- [Effect + Alchemy peers](https://ratstack.sh/resources/peers) → No closer lifecycle or cartridge pattern identified.

- [Hosted agent interfaces](https://ratstack.sh/systems/agent-front-door) → A cartridge is a package for one job, with its implementation and required infrastructure.¶

- [Learn mode presents concepts at useful depths](https://ratstack.sh/systems/learn) → A cartridge is a package for one job, with its implementation and required infrastructure.

- [Purpose and boundaries of rat-stack (VISION.md)](https://ratstack.sh/VISION.md) → Anything good can go in if it passes the cartridge test:

- [query-design](https://ratstack.sh/skills/query-design) → rat-stack’s current database cartridge supplies D1 and Hyperdrive Postgres adapters.

- [rat-stack](https://ratstack.sh/) → The hosted agent interfaces run in Mischief; extracting them into a separate cartridge is still work to do.

- [uncomplect](https://ratstack.sh/skills/uncomplect) → Look for Drizzle queries, SQL dialects, or provider SDK calls outside their cartridge.¶
