For nine days, islet has lived in a terminal. The daemon runs on a Raspberry Pi, the analytics engine crunches numbers in the background, the API accepts uploads — all invisible unless you know the right curl command. Logging a meal meant SSH and a CLI. That works at a desk. It does not work holding a fork.

Safety note: islet is a personal project and is not medical advice. It does not make dosing decisions. PCU values are informational only and must not be used as dosing advice.

The server already supported meal logging — a food logging API (introduced in Phase 1.5) with AI-assisted carb estimation via the server estimation API and a configurable provider, session management, and meal lifecycle. The capability existed, but only through a terminal.

Why native

A web app was the obvious choice. But meal logging has a specific interaction pattern: you’re eating, you pull out your phone, you type what you’re eating, you put the phone down. The whole thing needs to take less than a minute. It needs to work with one hand.

Native SwiftUI gets you the keyboard behaviour, the scroll physics, the date picker, and the system navigation for free. A web app would need to fight for all of those.

Fastest client wins for a system of one.

What the app does

Four screens. No onboarding.

Dashboard
Current glucose reading colour-coded by range, insulin on board, carbs on board, model-based 30-minute prediction, data freshness.
Food logger
Manual entry with macro tags (fat, protein, fibre, GI, absorption speed) — or ask the AI to estimate carbs through a multi-turn conversation.
Meal history
Recent meals with status badges. Delete unconfirmed entries.
Settings
Server URL and bearer token. Test connection button. That's it.

The AI estimation is the most interesting part. You describe what you’re eating — “two slices of sourdough with butter and a fried egg” — and the model either estimates directly or asks follow-up questions. The conversation is multi-turn: it might ask about portion size or cooking method before committing to a number. When it does estimate, the form auto-fills with carbs, GI level, and absorption speed. You review, adjust if needed, and submit.

The estimation API behind this is stateless. The client sends the full conversation history on every request; the server holds no session state for the AI conversation. That means the server can restart between turns without breaking a conversation, and there’s nothing to expire or clean up.

The Warm Amber theme

The app shares its visual identity with this website.

Background
Card
Warm Amber
Text

Dark background, warm amber accent, off-white text. The same palette as the site you’re reading now. Glucose readings get their own colour logic: a cold-to-hot spectrum where low readings are indigo, in-range is green, and highs run from orange to red.

Urgent low
Low
In range
High
Urgent high

The temperature metaphor makes the colours intuitive without needing a legend. Cold is concerning, warm is concerning, green is where you want to be.

Building from Windows

The development machine runs Windows. The build target is iOS. This is not a normal workflow.

XcodeGen solves the project file problem. The Xcode project is generated from a YAML file, so Swift source code can be written and committed from any platform. The actual build happens via SSH to a Mac running Xcode. Write, push, SSH, build, deploy.

SwiftUI and async/await made the client side straightforward. The API client is an actor — thread-safe by construction, no manual locking. Network calls are async functions that return Codable models. The views are declarative.

What was not straightforward: making Swift’s Codable decoders match the actual API response shapes. Several rounds of “the app compiles, the JSON doesn’t decode” before the models and the server agreed on field names and nesting.

4
screens
1,608
Swift SLOC
1
user

Designing for one

islet has exactly one user. There is no onboarding flow, no account creation, no usage analytics. The server URL and token are pre-configured. The server URL points to islet.griffiths.cymru.

That changes every design decision. There’s no need for error messages that explain the system to a stranger. No need for a forgot-password flow. No need for feature discovery. The app opens, shows the data, logs the food, and gets out of the way.

Every feature either solves a daily problem or it doesn’t exist.