Hexagonal architecture

Alistair Cockburn’s 2005 article calls the pattern “Ports and Adapters,” with “Hexagonal Architecture” as its alternative name. Users, programs, tests, or batch scripts can drive the application. Tests can run without its eventual devices and databases.

A port is an interface for an application job. A technology-specific adapter implements that interface for an outside system. The application need not know what is on the other side. The distinction is inside versus outside, not a prescribed number of sides.

Rat-stack’s stance

Joel Hooks:

I think hexagonal and ports and adapters, generally speaking, is an extremely good fit and matches what we are kind of doing anyway inside of our effect layer. So if we were putting a name on the architecture or a principle from which we derive our own version of the architecture, hexagonal would be it. We are not zealots. However, we do recognize really good ideas when we see them.

Rat-stack’s Effect layer follows the inside/outside boundary. We adapt that principle without requiring the whole architecture, its diagram, or particular folder names.

How rat-stack does it

On the driving side, interfaces call the application. One capability, every surface18 starts with a contract, binds a handler, and projects CLI, HTTP, MCP, RPC, and code mode21. The no-hand-rolled-surface rule keeps interface construction in the projection package.

On the driven side, where the application calls services, Effect Context.Service definitions provide ports for sending interest mail, subscriber intake (SubscriberIntake), and confirmation (SubscriberConfirm). Layers provide recording or HTTP mail, unconfigured or HTTP confirmation, and in-memory storage. Tests provide memory, recording, and fake services. Worker wiring builds the production HTTP adapters alongside InterestMode; it does not swap the whole adapter set on each mode.

The switch to the external signup implementation also changes application behavior. The handler branches on mode, and the confirm routes do too. The form template keeps its fields and POST target across modes, but rendering inserts a human-check widget when a site key is configured. Its complete markup is not guaranteed identical.

Typed preparation for agent-assisted intake uses the same service boundary: IntakeTicket, AbuseScore, and IntakeEvents, question and consent schemas, and test layers live in core. Interest signup12 records the agent-only application path and email confirmation11 boundary.

Boundaries fixed

Three leaks have been fixed:

Cartridges36 adds rat-stack’s own packaging and removal test, including infrastructure supplied through Layer.provide. A Layer as constructor12 explains the construction mechanism.

Sources

  1. Hexagonal architecture the original 2005 article. Alistair Cockburn. Original ports-and-adapters article; used for the inside/outside boundary. Accessed 2026-10-01.
  2. rat-stack/packages/core/src/interest-confirm-port.ts at main · joelhooks/rat-stack · GitHub. GitHub joelhooks/rat-stack. Confirmation port; used for the driven-side service boundary. Accessed 2026-10-01.
  3. rat-stack/packages/core/src/interest-mailer.ts at main · joelhooks/rat-stack · GitHub. GitHub joelhooks/rat-stack. Mail port; used for sending interest mail without choosing transport. Accessed 2026-10-01.
  4. rat-stack/packages/core/src/interest-intake.ts at main · joelhooks/rat-stack · GitHub. GitHub joelhooks/rat-stack. Intake port; used for subscriber intake independent of its adapter. Accessed 2026-10-01.
  5. rat-stack/packages/subscriber-delivery/src/delivery.ts at main · joelhooks/rat-stack · GitHub. GitHub joelhooks/rat-stack. Delivery composition; used for the HTTP adapters outside core. Accessed 2026-10-01.
  6. rat-stack/apps/site/src/worker.ts at main · joelhooks/rat-stack · GitHub. GitHub joelhooks/rat-stack. Worker composition; used for production adapter wiring. Accessed 2026-10-01.

Last changed 2026-10-10 in 978dccc. Source on GitHub. Change log.

Linked from

  1. A clean playground. rat-stack does real work with packages that stay easy to add and remove.

    Interest signup keeps delivery in an adapter package outside core.

  2. Agent guide. An Effect stack so pure (aspirational) Kit Langton will blush.

    Hexagonal architecture — Ports name the application’s jobs; adapters connect them to the outside world.

  3. Change log. What changed in the files served here, newest first.

    Hexagonal architecture — edited: docs: point live docs, skills and Brain pages at apps/site

  4. Code snippets quote a pinned source. Shipped design brief: pinned Git objects, typed diagnostics, and one build-only snippet model for both views.

    The package follows ports and adapters.¶

  5. Effect keeps the surfaces on one contract. Schema owns values, projections build interfaces, and Layers supply implementations.

    Hexagonal architecture names the adapter boundary.

  6. Engine-neutral tokens keep adapters replaceable. The highlighter port exposes text, roles, and font styles rather than Shiki types.

    This follows ports and adapters.¶

  7. Feature flags. Typed feature flags with owners, removal dates, and stable subject rollouts.

    The Config adapter reads deployment configuration.

  8. Full agent guide. An Effect stack so pure (aspirational) Kit Langton will blush.
  9. HTTP success needs a status check and a decoder. Supply the client, check the response status, decode accepted data, and name failures at the adapter boundary.

    Provider clients remain in adapters under hexagonal architecture.¶

  10. Interest signup. Agent-only applications start email confirmation through interfaces owned by core and delivery implemented in a separate package.

    See hexagonal architecture.

  11. 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.

    Learn owns the FeedbackAuthor port.

  12. Learn the stack | rat-stack. Hands-on guides to Effect actions, XState lifecycles, and the seams between stack pieces.

    Follow ports and adapters for provider boundaries and agent next actions for hypermedia guidance.

  13. learn-rat-stack. Trace a capability through Effect, XState, five projections, the CLI, and Alchemy. Try hosted search and read.

    This follows hexagonal architecture: composition supplies the file-system dependency.¶

  14. One capability, every surface. A schema-typed contract and one handler feed every interface rat-stack keeps.

    HATEOAS covers links that guide an agent’s next action; hexagonal architecture names the ports-and-adapters principle.¶

  15. Pin the source and report drift separately. A pinned excerpt stays fixed while a separate diagnostic compares it with HEAD.

    The configured registry follows ports and adapters.¶

  16. Rat Stack lore | rat-stack. Short, source-grounded notes on the ideas and decisions behind rat-stack.

    Hexagonal architecture — Ports name the application’s jobs; adapters connect them to the outside world.

  17. rat-stack. An Effect stack so pure (aspirational) Kit Langton will blush.
  18. Source change history (log.md). The generated change log as Markdown.

    Hexagonal architecture — edited: docs: point live docs, skills and Brain pages at apps/site

  19. 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.

    See hexagonal architecture.¶

Unlinked mentions (33)