---
title: "North"
tagline: "Microservices"
language: "Rust"
license: "MIT"
since: "2021"
canonical: "https://xraph.com/work/north-framework"
---

# North

The second attempt, with better instincts. North got the lifecycle model right and the ergonomics wrong. Both lessons went into Forge, which is why Forge’s startup is an inspectable graph rather than an init function.

## Install

```bash
cargo add north
```

## What it is

A microservice framework in Rust, published in 2021 and no longer maintained. The second of two attempts at the same question: how much framework can you offer in Rust before the type signatures stop being readable by the people you are trying to help?

## What it got right

Startup modelled as an explicit dependency graph rather than an init function, largely because Rust forced me to be precise about ownership and ordering. That idea is load-bearing in Forge today.

Errors that carry the operation being attempted rather than only the cause. "connection refused" is not actionable; "starting postgres pool for service 'assets': connection refused" is.

Extension points designed before there were extensions, because retrofitting a seam in Rust is genuinely difficult.

## What it got wrong

The signatures. A handler that resolved two services from a container and returned a response had four generic parameters, two lifetimes and a trait bound wider than my editor. Async traits had not landed, so anything async meant boxed futures and the ergonomic taxes compounded.

> A framework whose signatures only its author can read has failed at the one thing frameworks are for.

Some of that has since improved in the language. A version written today would be a meaningfully better experience. I am not going to write it. Octopus is where my Rust goes now, and a gateway has no user-authored handlers in its type signatures.

---

*Unpublished draft. Not peer reviewed and not submitted to a venue.*


## Anatomy

- **Service**: A microservice with lifecycle and configuration built in.
- **Discovery**: Registration and lookup across the fleet.

## Constraints and trade-offs

- (decision) What it got right: lifecycle as a graph. Forge inherited it directly.
- (known gap) What it got wrong: too much magic at the macro layer to debug comfortably.
