Case Study

Studiolo

Not a brake on the web but a transmission: the same pull, routed outward into your reading, making, and time.

Studiolo is a native macOS study environment, not a browser tab or a blocker you bolt on. Tauri v2 and Rust wrap a pure TypeScript domain core, with React for the surface. Twelve instruments across three motions, motion laws held by executable tests, and your writing as plain Markdown in a folder you own. Nothing in the core loop guesses, no telemetry, no account, no network calls of its own.

Venture
Pentinian, in-house
Role
Design + build, solo
Stack
TypeScript · Tauri v2 · Rust · React
Period
June 2026, ongoing
Status
In build, MVP on macOS
12
Instruments
21
Decision records
108
Documented tests
5
Motion laws
0
Network calls of its own
D1 · the glance

The situation

Measured reasoning and sustained attention have been sliding across wealthy countries since the mid 2010s. Studiolo starts from a plain premise: people did not get less capable, the environment changed. We traded active, self-directed thinking for passive consumption and constant context switching, and the feeds doing the pulling are engineered around variable rewards, the same mechanism that makes a slot machine hard to put down.

Almost every tool built to fight this is a brake. It sets itself against the web's pull, the user feels the friction as loss, willpower runs out, and the app is gone on the first bad evening. That is not a discipline problem, it is structural. A brake and a strong current can only end one way.

Studiolo is a transmission instead. It takes the same force the web spends trying to capture you and routes it the other way, into your own reading, your own making, your own time in the world. The web wants to pull everything inward and hold it. Studiolo takes whatever arrives and flings it back outward. (It is a native macOS app, by the way, not another tab pretending to save you from tabs.)

The creed is ordered, and the order is the rule. First restoration, return to people what the technology took. Second mature instrumentality, let the technology enhance a life. When a design choice is unclear, restoration wins, and that single tiebreaker is what keeps the thing from quietly drifting into a productivity tool, which is where every focus app without one ends up.

A transmission does not fight a force. It routes it.

Studiolo creed
D2 · the engaged read

What was built

01

The Frame, the app is the border not a window

A hairline border at rest around the whole screen. Summoned by hotkey, by pressing the cursor to the top edge, by a schedule, or by opening something that takes more than it gives. When it rises the desktop recedes behind a native frost and your study comes forward. There is no home screen, an architectural decision that reorganized everything downstream.

Frame
02

The Obsidian Skull, a block that yields

Feed it a site or an app and it goes quiet. Blocking yields counted drops, five minutes each, on a daily allowance of one to five. Raising the allowance takes effect tomorrow, lowering it is immediate. Re-entry mints a QR card with a wake delay, scanned by webcam or typed, on a one-hour reprint cooldown.

Skull
03

The Hourglass, pages that recede on their own rhythm

Dwell time with dispositions (banquet, library, workshop), pours settable from one minute to two hours, a draining hairline, and a page that recedes when the sand runs out. It hands you back to yourself rather than slamming a door.

Hourglass
04

The Commonplace, reading you actually own

Your words as plain Markdown in an open vault. Drop any Markdown or text file in from Obsidian or anywhere and the study has it within moments, editable, front matter preserved exactly. An index of headings, a search, and real folders where filing physically moves the file.

Commonplace
05

The Reliquary, twelve slots and the limit is drawn

Twelve slots for what you keep whole. Empty ones render dashed so the limit is felt. A thirteenth requires letting one go. Scarcity as an interface element rather than a nag.

Reliquary
06

The Cast, everything it makes it sends outward

The Music Box winds 15 to 60 minutes and frost holds the door while you live (Escape grants thirty seconds). The Press sets one kept thing in type and prints it. The Stationer holds four leaves. The Letterbox delivers a bounded daily edition of your own keepsakes and empties when read.

Cast
D3 · the hood

Under the hood

Frost that survives motionADR-014

The Frame's whole affordance is that the desktop recedes behind a real material. The obvious build is CSS backdrop-filter: blur(), and it was a lie in motion. WebKit drops the filter the instant a compositing animation settles, so the frost was right in a screenshot and wrong in use, which is the worst kind of wrong for a product whose only claim is calm.

  • The fix left the web layer entirely: native macOS material driven from Rust, plus explicit window levels. Always-on-top is level 3, the Dock 20, the menu bar 24; the pushed Frame sits at 1000 and the QR card at 1001, then at rest the Frame drops back to 3 and turns click-through so it cannot catch a stray click.
  • Route windows by webview label, not by URL query parameter. That one change killed a class of heisenbugs.
  • The desktop framework denies inter-window events by default: a one-line capabilities manifest once you know, an afternoon when you do not.
  • The Rust shell is 747 lines exposing fourteen commands. Everything else lives in TypeScript.
One pure core, several shells@studiolo/core

The domain is @studiolo/core, eighteen modules of pure TypeScript with no UI and no I/O: the Frame state machine, the Skull and its card, the Hourglass, the Commonplace and its Markdown layer, the room, the watcher's tally, and the rest. @studiolo/ui holds the tokens and the motion system, the single source of movement. @studiolo/data is interfaces only, deliberately unimplemented. apps/desktop is the Tauri v2 shell, macOS first, while the mobile shell, the extension, and the relay are README stubs, and the roadmap names the mobile shell as the test of the architecture's central bet.

Persistence is a beachhead, not the endpoint. Today it is plain Markdown with front matter in a folder you own, and settings as one read-merge-write JSON object. Designed and dormant: on-device SQLite and CRDT sync behind an end-to-end encrypted relay, earning their complexity only when the social layer arrives. Twenty-one architecture decision records carry the reasoning next to the code, and the most instructive, ADR-019, was amended three times in a single day.

Motion laws, held by executable tests5 laws

Motion here is not a stylesheet convention, it is five tests that fail the build.

  • Three tiers only: respond 110 ms, resist 240 ms, return 420 ms.
  • It answers the hand faster than it settles, and keeps time slowly, like weather.
  • It never loops, pulses, or blinks. Every animation is one shot.
  • It moves nothing at rest, and honors reduced motion from the operating system and from an in-app lever.

One exception is recorded rather than smuggled: the empty room's eye blinks on a slow random clock, eighteen to thirty-six seconds, and the note calls it a scoped mercy. A design system that can name its own exception is one that survives its author's next mood.

A free placement grid lived one evening. What replaced it wrote the philosophy in five words: the constraint is the taste.

ADR-019, amended three times
the room

The design system

The palette is one warm monochrome in two lights, day and night, on a single semantic set, because cold gray reads as malfunction and this is a place you are meant to sit in. High-contrast variants exist for both lights, and everything resolves through CSS variables, so one property swap changes the entire study. There is exactly one accent, oxblood, and it is spent sparingly.

Accessibility is built in at the front, not buried in a preferences pane. A reading serif carries the type by default, with Atkinson Hyperlegible one lever away for dyslexia, sitting next to high-contrast and reduced-motion as first-class controls. The room itself is the interface: a middle zone and two side zones split by draggable sashes on a 27-row grid, where every curio wears one of three designed face breadths and nothing is ever stretched. One curio, the Brown Study, is left deliberately plain, on the recorded rule that where a thing cannot be both effortless and self-proving, it defaults to effortless.

Ivory#F6F1E7 · day ground
Paper#EFE7D8 · raised day surface
Ink#1C1B18 · day text
Sepia#8A6F4D · the warm mid
Oxblood#6E2B23 · the one accent
Night ivory#191713 · night ground
operations

What it changes

Was. Every focus tool sets itself against you. The friction registers as loss, willpower depletes, and the app is gone inside a fortnight.

Now. The same force, routed outward. Blocking yields counted drops instead of a locked door, the Hourglass hands pages back instead of seizing them, and the Cast turns attention into printed, posted, physical output.

Was. Progress shown as a score, a streak, or social approval, which quietly imports the incentive structure of the thing you are trying to escape.

Now. Cultivation, not score. Your study grows like a room. No XP bar, no likes anywhere, the feed never the reward, on the plain reasoning of the overjustification effect.

Was. Your notes living in someone else's database, yours only through their export button.

Now. Plain Markdown in an open vault on your own disk, front matter preserved exactly, Obsidian or anything else free to read and write the same folder. No analytics, no telemetry, no account, no network calls of its own.

Was. A business that quietly profits whenever progress feels slow.

Now. Revenue from print, physical goods, institutions, and optional cosmetics. Never paid speed, levels, or depth, because selling faster progress hands the business a reason to make progress feel slow.

cost

Economics

LineBasisAnnual
Server and syncLocal-first by construction. Markdown files and a JSON settings object live on the user's disk. The sync layer is designed, interfaced, and deliberately unimplemented until a social feature needs it.$0
Analytics and telemetryNone. No account system, no event pipeline, no data warehouse, so none of the recurring cost and none of the compliance surface either.$0
Inference costZero, and it is a principle before it is a saving. Nothing in the core loop guesses for you. In a category where every rival is bolting on a model, that is a stated refusal that happens to cost nothing.$0
Code signing, notarizationNot yet incurred. Distribution is deliberately out of scope for this phase, so there is no installer to sign yet.not costed

Modeled, awaiting actuals. There is no price, no revenue, and no per-seat line in the record, so nothing here carries a real dollar figure. The honest economics are structural: a local-first, telemetry-free product with nothing inferring in its core has a marginal cost per user of about zero and no data-processing compliance burden. That is a property of the business model, not a line item.

Reserved for your numbers. If Studiolo is ever priced, three figures make this real: the intended price of the Press and the goods, the per-unit print cost, and the notarization and distribution overhead once it actually ships. Drop them in and this table stops being a model.
outcomes

In the world

01

Twelve instruments running locally, built in eleven days

An MVP across thirty-two numbered sessions, June 3 to 13 2026, against a four-week plan. Five instruments were live at the inventory snapshot, a sixth landed that same night, and the rest inside three days.

02

A domain core with no UI and no I/O, fully tested

108 tests documented across the core and the motion laws, and the motion laws are themselves executable, so an animation that loops fails a test rather than a review.

03

A frost problem solved at the right layer

The CSS version was correct in a screenshot and wrong in motion. Moving it to native macOS material and explicit window levels is the kind of fix that costs a day and disappears when you get it right.

04

A project that audits its own marketing against its own code

The inventory's documentation-debt section caught the case study overclaiming a cut feature, a stale test count, and a visual language the build does not keep. Most teams never do this at all.

what is not done

Honest edges

The sync layer is interfaces only.

No local database, no CRDTs, no migrations. The Post, the social half, does not exist, and neither does the encrypted relay it would need. What ships is the single-user study, whole.

macOS only.

No Windows, no Linux, no mobile shell, no browser extension. The frost is the reason: the solution is native, driven from Rust against a macOS material, and porting it is the first item on the roadmap.

No CI, no code signing, no notarization, no installer.

Distribution is deliberately out of scope for this phase. That is a defensible choice for a portfolio artifact and a blocker for a product, and the record says so in those words.

The test count drifted across documents.

48, then 67 and 72, then 108, against a source tree that now carries more. The documented figure is 108, and the project's own audit flags the drift rather than quietly restating it.

An earlier attempt is archived, not deleted.

A 2025 version built as a marketing website with a simulated desktop metaphor, thirty-one numbered spec folders, no domain core, no tests. Keeping it visible is part of the honesty.

Provenance. Every figure traces to the Studiolo case study, creed, architecture, bestiary, inventory and journal documents, the twenty-one architecture decision records, the design token and motion modules, and the Tauri shell source, read as of 25 July 2026. Where the project's own documentation-debt audit flags a discrepancy, this page reports the audit rather than the claim. Cost figures are modeled and labeled as such.