← the late compiler
C_000185 · software engineering · intermediate

Hexagonal Architecture

Placing domain logic at the centre with all external interaction through ports implemented by adapters, so the core depends on nothing outside itself.

Step 1 of 4

In words

What it is, why it matters, and what it is like.

Why am I learning this?

This unlocks: reading a real codebase without getting lost, understanding how a large AI service is structured so you can find where the logic lives, and being able to argue convincingly for a design choice in a code review. Specifically, it prepares you for the neighbouring notes you already keep: Ports and Adapters, Dependency Inversion, Separation of Concerns, and the Ilities. It also makes the later topics — Domain-Driven Design, Distributed Systems, API Design — land. Without it, a request that comes in through a web API, gets logged, hits a database, and sends an email looks like one tangled blob. With it, you see the blob as a core with four doors.

The idea, in plain terms

Imagine you run a small shop that sells spices. You have the shop counter where customers come, a storeroom at the back, and you phone your supplier when stock runs low. Now imagine you decide to close the counter and sell online. You don't rebuild the storeroom or the phone system. You add a website, and the website talks to the same rules you always used: if a customer asks for something, check the storeroom, take payment, and arrange delivery. The storeroom doesn't care whether the request came from a person at the counter or a web form. It only cares that someone asked for a jar of turmeric. That is the idea: the rules of the shop — what counts as a sale, when to reorder — sit in the middle, and every way of reaching them (the counter, the website, the phone) is just a different doorway. If you later add a mobile app, you don't touch the rules. You build another doorway. In software, the rules are the *domain logic*, the shopkeepers are the *core*, and each doorway is an *adapter*. The doorway defines a contract — 'anyone who wants to buy must present themselves here, in this format' — and each adapter translates between the outside world and that format. Now imagine the shopkeeper is a bank manager. The manager's rules about whether to approve a loan do not change whether the application comes in on paper, over the phone, or through a mobile app. The manager has a standard form: name, income, debt, job tenure. Any channel that can fill that form is fine. In code, that standard form is called a *port* — an interface the core defines, saying 'this is what I need and this is the shape I expect it in.' The actual forms — the paper form, the phone script, the mobile app screen — are the *adapters*. They translate between the real world and the port. The core never touches the real world directly. It never writes to a database directly. It never sends an email directly. It says, 'I need to save this loan decision — someone must provide that service.' The port says what that service looks like, and the adapter does the actual saving. That is the whole architecture. Draw it as a hexagon and you have the diagram that gives the pattern its name. The point is not the hexagon's six sides. The point is that everything outside the core can be changed without changing the core, and the core can be tested in a room with no walls, no wiring, no plumbing.

An analogy

Think of a car's engine versus the rest of the car. The engine produces power through a standard shaft — every vehicle that uses it knows what that shaft looks like. Whether the car has a manual gearbox, an automatic, or an electric motor in between, the engine does not care. The engine's job is only to turn the shaft. The gearbox and the driveshaft are adapters. Now push it: the engine also needs fuel, cooling, and oil. Each of those is another port — the fuel pump provides fuel, the radiator dissipates heat — and each has adapters. You can swap the whole cooling system without changing the engine's internal design. Where the analogy breaks down: in a car, the engine's parts are physically fixed; in software, the core can be updated while running, and the adapters can be swapped without stopping the engine. Also, a car engine is built once and shipped; a software core is rebuilt continuously as requirements change. The engine's shaft is a mechanical interface; software ports are abstract — they are just definitions of what functions exist and what they expect and return. The important limit: the engine knows nothing about the car around it, but the car's designers chose the engine. The core defines the ports; the outside world must obey them.

Definition

Hexagonal architecture (also called ports-and-adapters) is a way of structuring software so that the domain logic — the rules that matter to the business — sits in the centre, and every interaction with the outside world (databases, web servers, message queues, user interfaces) happens through ports the core defines and adapters the outside world implements.

Where this sits

This sits on top of two things you already keep notes on: Dependency Inversion and Separation of Concerns. Ports and adapters are the concrete form of dependency inversion — the interface belongs to the core, not to the database driver. And separation of concerns is the reason the core avoids knowing about HTTP or SQL. It is a refinement of layered architecture: instead of strict layers, you have a centre and a periphery. The centre is high-cohesion (all about the domain) and the periphery is loosely coupled to the centre through ports. The 'ilities' from your notes — maintainability, testability, scalability — are precisely what this architecture trades for. It gives you testability (core tested without infrastructure), maintainability (swapping a database is a small change), and typically helps scalability (you can put adapters behind queues or shards). It costs some initial complexity — more interfaces, more indirection — and that cost is worth it only when the domain is central and the infrastructure is likely to change. The neighbouring notes on REST and GraphQL are about the API adapters; microservice tradeoffs are about when the periphery becomes so large that the hexagon is really many hexagons talking to each other.

Signal from the Frontier

Get the next essay on mind, machine, and meaning

Essays at the intersection of AI, philosophy, and Indian governance. No promotional content.

We'll send a one-click sign-in link to confirm. No password needed.

Views expressed are personal and do not represent the Government of India or the Government of Uttarakhand.