1. A port (interface)
The port is an interface owned by the core; it describes what the core needs without naming any technology.
interface NotificationPort {Typorithm · medium
Step 1 of 8 · intro card
Layered & Clean
Hexagonal architecture (ports and adapters) lets the core app define ports — interfaces for what it needs. Adapters for databases, HTTP, or email plug into those ports, so the core knows nothing about I/O and any adapter can be swapped, including a fake one for tests.
The core application defines ports: plain interfaces describing the inputs and outputs it requires, with no mention of databases, HTTP, or email.
Adapters live on the outside and implement those ports — an EmailAdapter, an SmsAdapter, or a test double can all satisfy the same NotificationPort.
Because the core depends only on the port, you can swap adapters freely, which makes the core trivially testable: inject a fake adapter and assert on it.
Ports are interfaces the core owns.
Adapters implement ports and hold the I/O.
The core knows nothing about concrete I/O.
// the port — an interface the core owns
interface NotificationPort {
send(msg: string): void;
}
// an adapter plugs into the port
class EmailAdapter implements NotificationPort {
send(msg: string): void {
smtp.deliver(msg);
}
}
// the core depends on the port, not on I/O
class SignupService {
constructor(private notifier: NotificationPort) {}
register(user) {
this.notifier.send("welcome");
}
}Connect each part of the code to the concept before you type.
The port is an interface owned by the core; it describes what the core needs without naming any technology.
interface NotificationPort {The email adapter implements the port; other adapters (SMS, push) could plug into the same port.
class EmailAdapter implements NotificationPort {The SMTP call lives only in the adapter; the core never touches it directly.
smtp.deliver(msg);The core service depends on the port interface, so it knows nothing about email or any concrete I/O.
constructor(private notifier: NotificationPort) {}Read the concept map and follow the code breakdown.
Type the implementation, repair mistakes and work through every recall exercise.
Use the final check without hints; revisit weak concepts in short practice sessions.