
Hexagonal Architecture
Structure domain logic behind ports and adapters so HTTP, queues, and databases stay swappable in TypeScript, Java, Kotlin, or Go services.
Overview
hexagonal-architecture is an agent skill most often used in Build (also Ship) that designs Ports & Adapters boundaries with dependency inversion and testable use-case orchestration across TypeScript, Java, Kotlin, and Go
Install
npx skills add https://github.com/affaan-m/everything-claude-code --skill hexagonal-architectureWhat is this skill?
- Domain model stays free of framework imports; use cases orchestrate workflows
- Inbound ports for commands/queries; outbound ports for repos, gateways, and publishers
- Adapters at the edges for HTTP, CLI, workers, and cron without rewriting rules
- Dependency inversion so infrastructure swaps do not touch business logic
- Explicit when-to-use list for new features, refactors, and multi-interface apps
- 4 language targets called out: TypeScript, Java, Kotlin, Go
Adoption & trust: 3.5k installs on skills.sh; 210k GitHub stars; 2/3 security scanners passed (skills.sh audits).
What problem does it solve?
Your service logic is welded to ORM, HTTP handlers, and third-party SDKs so every infrastructure change breaks business rules and tests.
Who is it for?
Solo builders shipping multi-interface backends who expect to replace infra or add CLIs and workers without rewriting rules.
Skip if: One-off scripts, tiny CRUD spikes, or prototypes you plan to discard before maintainability matters.
When should I use this skill?
Building features for maintainability, refactoring coupled services, supporting multiple interfaces for one use case, or replacing infrastructure without rewriting business rules.
What do I get? / Deliverables
You get clear port interfaces, adapter implementations at the edges, and a domain core you can unit-test while swapping databases or transports.
- Port interface definitions
- Adapter implementations at system edges
- Domain-centric use-case layer
Recommended Skills
Journey fit
Spans multiple journey phases - primary shelf plus alternate fits below.
Ports-and-adapters work happens while you implement and evolve backend services, with refactors often triggered after ship when coupling hurts. Backend is where inbound/outbound ports, use cases, and adapter implementations are defined away from framework glue.
Where it fits
Introduce inbound/outbound ports before adding a second HTTP module and a queue consumer.
Wrap an external payment gateway behind an outbound port instead of calling the SDK inside use cases.
Refactor a layered controller-service-repository stack where entities import framework types.
Replace Postgres with a new store by swapping only the repository adapter implementing the outbound port.
How it compares
A structural design workflow for service boundaries—not a Laravel-specific verifier or a generic lint loop.
Common Questions / FAQ
Who is hexagonal-architecture for?
Solo and small-team backend builders who want framework-agnostic domain logic in typed services across common JVM, Go, and Node stacks.
When should I use hexagonal-architecture?
In build when adding features with multiple entrypoints, during ship review when untangling layered code, and in operate when swapping a database or message bus behind stable ports.
Is hexagonal-architecture safe to install?
It is design and refactor guidance without mandated shell commands; confirm package provenance via the Security Audits panel on this page.
SKILL.md
READMESKILL.md - Hexagonal Architecture
# Hexagonal Architecture Hexagonal architecture (Ports and Adapters) keeps business logic independent from frameworks, transport, and persistence details. The core app depends on abstract ports, and adapters implement those ports at the edges. ## When to Use - Building new features where long-term maintainability and testability matter. - Refactoring layered or framework-heavy code where domain logic is mixed with I/O concerns. - Supporting multiple interfaces for the same use case (HTTP, CLI, queue workers, cron jobs). - Replacing infrastructure (database, external APIs, message bus) without rewriting business rules. Use this skill when the request involves boundaries, domain-centric design, refactoring tightly coupled services, or decoupling application logic from specific libraries. ## Core Concepts - **Domain model**: Business rules and entities/value objects. No framework imports. - **Use cases (application layer)**: Orchestrate domain behavior and workflow steps. - **Inbound ports**: Contracts describing what the application can do (commands/queries/use-case interfaces). - **Outbound ports**: Contracts for dependencies the application needs (repositories, gateways, event publishers, clock, UUID, etc.). - **Adapters**: Infrastructure and delivery implementations of ports (HTTP controllers, DB repositories, queue consumers, SDK wrappers). - **Composition root**: Single wiring location where concrete adapters are bound to use cases. Outbound port interfaces usually live in the application layer (or in domain only when the abstraction is truly domain-level), while infrastructure adapters implement them. Dependency direction is always inward: - Adapters -> application/domain - Application -> port interfaces (inbound/outbound contracts) - Domain -> domain-only abstractions (no framework or infrastructure dependencies) - Domain -> nothing external ## How It Works ### Step 1: Model a use case boundary Define a single use case with a clear input and output DTO. Keep transport details (Express `req`, GraphQL `context`, job payload wrappers) outside this boundary. ### Step 2: Define outbound ports first Identify every side effect as a port: - persistence (`UserRepositoryPort`) - external calls (`BillingGatewayPort`) - cross-cutting (`LoggerPort`, `ClockPort`) Ports should model capabilities, not technologies. ### Step 3: Implement the use case with pure orchestration Use case class/function receives ports via constructor/arguments. It validates application-level invariants, coordinates domain rules, and returns plain data structures. ### Step 4: Build adapters at the edge - Inbound adapter converts protocol input to use-case input. - Outbound adapter maps app contracts to concrete APIs/ORM/query builders. - Mapping stays in adapters, not inside use cases. ### Step 5: Wire everything in a composition root Instantiate adapters, then inject them into use cases. Keep this wiring centralized to avoid hidden service-locator behavior. ### Step 6: Test per boundary - Unit test use cases with fake ports. - Integration test adapters with real infra dependencies. - E2E test user-facing flows through inbound adapters. ## Architecture Diagram ```mermaid flowchart LR Client["Client (HTTP/CLI/Worker)"] --> InboundAdapter["Inbound Adapter"] InboundAdapter -->|"calls"| UseCase["UseCase (Application Layer)"] UseCase -->|"uses"| OutboundPort["OutboundPort (Interface)"] OutboundAdapter["Outbound Adapter"] -->|"implements"| OutboundPort OutboundAdapter --> ExternalSystem["DB/API/Queue"] UseCase --> DomainModel["DomainModel"] ``` ## Suggested Module Layout Use feature-first organization with explicit boundaries: ```text src/ features/ orders/ domai