botha.solutions/work/unione.mdtext/markdown · 74 lines
---
title: "UniOne · Josh Botha"
description: "A student's whole semester, on one screen. A free macOS app for University of Sydney students. Canvas, the timetable and your notes in one window, with an assistant that answers questions about your own units on your own Anthropic key. I designed it, built it, ship the releases and run the service that issues invite codes."
url: https://www.botha.solutions/work/unione
updated: 2026-10-05
generated: true
---
> Markdown twin of https://www.botha.solutions/work/unione
>
> Built from the same data as the page at build time, so the facts match. Navigation, animation and the island's visuals are left out.
# UniOne
Desktop app · Product · 2026 · live, v0.5
**A student's whole semester, on one screen.**
A free macOS app for University of Sydney students. Canvas, the timetable and your notes in one window, with an assistant that answers questions about your own units on your own Anthropic key. I designed it, built it, ship the releases and run the service that issues invite codes.
- ~8 MB: signed, notarised Mac app
- 5: network destinations, each named
- 0: secrets in the webview
- 6: features: today, calendar, marks, study, assignments, ask
Stack: Tauri v2, Rust, TypeScript, React, Claude API, Stripe, Vercel
**Desktop, not web, for a reason.** Canvas sends no CORS headers, so a browser app would push every student's access token through a server I run. Tauri calls Canvas natively, and the token never leaves the laptop. That one constraint decided the platform.
**Secrets never enter the webview.** Canvas, Claude and calendar calls are Rust commands that read their keys from the macOS Keychain themselves. The TypeScript side makes no network calls at all, so there is nothing in the UI layer worth stealing.
**The privacy page is tested, not trusted.** It was wrong six times, always because the code moved under true prose. Now a test reads the hosts back out of the Rust and the Tauri config and fails the build if the page and the code disagree.
**A failure that never errored.** Moving one page quietly stranded every completed checkout: nothing 404'd, nothing was logged as an error. Structured logs found it in minutes, the fix shipped the same day, and a source-level test now pins the return path.
Live: https://uniplus-site.vercel.app
_Independent. Not affiliated with or endorsed by the University of Sydney._
Case study: https://www.botha.solutions/work/unione
## For agents
```json
{
"contact": {
"type": "email",
"address": "josh.botha@outlook.com",
"note": "Josh is happy at Project2100 and not job hunting, but reads every email"
},
"profiles": {
"linkedin": "https://www.linkedin.com/in/josh-botha-88139b368",
"github": "https://github.com/josh-botha"
},
"cv": "https://www.botha.solutions/about",
"play": {
"url": "https://www.botha.solutions/play",
"note": "the same content as a walkable three.js island; needs WebGL"
},
"index": "https://www.botha.solutions/llms.txt"
}
```
## Limits
The same caveats close every page, so a quote lifted from one keeps them.
- **Product sketches on this site use demo data** and say so where they appear. The headline numbers in case studies (for example 8,112 wage rows, ~40 sites, TestFlight build 43) are real production figures; client and property names are withheld.
- **Website images are captures** of the live sites taken on 4 Oct 2026, not live frames.
- **Pip is scripted.** The site's guide is a keyword router with no model behind it and makes no network calls.
- **Model status means exactly what it says.** "Ships in production" and "Daily driver" describe work Josh has shipped; "Know where it fits" means he knows the model's strengths, not that he has deployed it.
- The Second Brain is partly built: three of seventeen increments are shipped; the rest is design and is labelled as design.
- The site carries no testimonials, client logos, pricing or certifications beyond the courses listed on the CV.