← All writing

/ 3 min read

Local first, observe only: lessons from building a desktop tool for developers

What I learned building Alita, a cross platform system manager for developers in Python, Rust and Go: keeping data on the machine, never acting without asking, and using native code only where it pays for itself.

  • Python
  • Rust
  • Go
  • Desktop

Alita started as a tool for myself. On a normal working day I had a terminal for processes, another for ports, a browser tab for the API client, a dashboard for pull requests and a calendar reminder for certificates that were about to expire. I wanted one place that showed all of it, worked offline and did not send my machine's details to someone else's server.

It grew into a cross platform system manager for developers and their teams, built in Python with native parts in Rust and Go. These are the principles that shaped it, and the ones I would start with again.

Local first means the machine is the source of truth

Everything Alita records lives on the machine. Measurements and history are stored in SQLite, split into shards so that old data can be compacted or dropped without rewriting everything. Secrets, such as tokens for Git hosts or API environments, are encrypted with the operating system's own keystore rather than a homemade scheme.

Nothing leaves the machine except requests to the addresses you configure yourself. There is no account to create and no telemetry. For a tool that sees running processes, open ports and local files, that is not a feature on a pricing page; it is the condition for anyone trusting it at all.

Observe by default, act only when asked

A system manager can do damage: kill a process, delete files, change a firewall rule. The rule in Alita is that observing is free and acting always needs a person. Every destructive action is explicit, shows what it is about to do, and asks for confirmation. Monitors and dashboards can be as clever as they like, but they never change the system on their own.

That rule made many design questions easy. Should a monitor restart a crashed service automatically? It can suggest it, with one click to do so. Should cleanup delete old build folders? It lists them with their sizes and lets you choose.

Small parts in strict layers

The application ships as a single file, but the source is many small parts in strict layers: core, platform, tracking, monitors, engine, server and UI. Each layer may only depend on the layers below it, and tests enforce that, so a quick import from the UI into the core fails the build instead of quietly tangling the code.

LAYERS = ["core", "platform", "tracking", "monitors", "engine", "server", "ui"]

def test_imports_point_down():
    for module in iter_modules("alita"):
        own = LAYERS.index(module.layer)
        for target in module.imports:
            assert LAYERS.index(target.layer) <= own, f"{module.name} imports upward: {target.name}"
A layering test, simplified: every import must point down the stack.

For a project with one maintainer, that discipline is what keeps it changeable. I can rewrite a monitor without reading the UI, and replace the platform layer for one operating system without touching the others.

Native code where it pays for itself

Python is the right language for most of Alita: quick to write, rich in libraries and easy to read later. It is the wrong language for a few jobs, and those got native code instead.

  • A background agent in Rust and Go keeps measuring when the window is closed, with a footprint small enough to forget about.
  • A Go front door checks every local request before the Python hub sees it, so the hub never handles anything unauthenticated.
  • A Rust core, also compiled to WebAssembly, powers formatters, validators and diffs, so the same code runs in the desktop app and in the browser UI.
  • A Rust HTTP engine for the API workspace handles proxies, company certificate authorities and client certificates, which are exactly the cases where developer tools usually fail inside corporate networks.

The rule I followed: start in Python, measure, and move a part to native code only when there is a clear reason, such as memory, startup time, security boundary or code shared with the browser. Rewriting for its own sake would have tripled the work for no benefit anyone could feel.

Three operating systems, honestly

Cross platform is easy to claim and hard to mean. Processes, services, firewall rules, keystores and installers all work differently on Windows, macOS and Linux. Alita keeps those differences in the platform layer behind one interface and ships installers for all three that support silent installs, so a team can roll it out with their usual tools.

What it taught me

Building a product end to end, alone, sharpened habits I now bring to team work: write down the rules that keep a codebase healthy and let tests enforce them, keep trust boundaries explicit, and choose the boring tool until the interesting one has earned its place. It also made me a better frontend engineer, because I had to live with every decision on both sides of the API.

Next article ↗

What two years of backend taught me about building interfaces