Reducing the Cost of Context Switching Across Apps
Why moving between apps and tasks carries a hidden cognitive cost, and how software can reduce the friction of switching for the people who use it.
Writing
Essays on design, engineering, and product decisions — written by the people who build our products. We share the reasoning, the trade-offs, and the cases behind the work.
Why moving between apps and tasks carries a hidden cognitive cost, and how software can reduce the friction of switching for the people who use it.
Why trust is built through engineering choices, not marketing: how secure architecture, transparent behavior, and good defaults earn it.
The questions a small studio asks before building anything, turning feature decisions into a deliberate test of purpose, cost, and fit.
What it takes to build software that remains maintainable for ten years, where most cost lives after launch and clarity beats cleverness.
How a product website earns a visitor’s trust through honest signals, clear information, and substance rather than badges and bold claims.
How a macOS utility turns plain text into well-formed PDF, covering text layout, pagination, and the rendering pipeline behind print-quality output.
How the macOS sandbox confines apps to protect users, what it permits and restricts, and how to build a capable app within its boundaries.
Content is now read by people and by language models. The same qualities that serve readers, clarity and structure, also serve machine understanding.
How search should behave in a small app, where scope is narrow and the right design is forgiving, fast, and matched to the data.
How scheduling tools cause decision fatigue, and how Flowo reduces it by making fewer decisions and deferring choices to the right moment.
Automated checks catch only part of accessibility. A workflow that combines tooling, keyboard and screen-reader testing, and real users catches the rest.
How the small words in an interface shape understanding, and how to write microcopy that guides the user clearly at the moment they need it.
How to learn enough from crashes to fix them while collecting no more user data than necessary, keeping diagnostics and privacy compatible.
Releasing too often exhausts a small team; too rarely lets risk pile up. A steady, predictable cadence keeps quality high without burning people out.
When an AI assistant answers from your content, it extracts a passage. How to write so the passage it lifts is accurate, complete, and attributed to you.
How to organize settings so common options are easy to find and advanced ones stay available, using progressive disclosure to manage complexity.
People are interrupted mid-task constantly. Preserving state, marking where they left off, and restoring context turn a jarring return into a smooth resumption.
How a two-person software studio ships quality products by replacing heavy process with a few disciplined habits around scope and focus.
How rendering choices affect battery life on Apple platforms, and the patterns that keep an interface smooth without draining the device.
Interfaces that present everything at once invite divided attention. Designing for single-tasking means showing one thing to do and protecting it from the rest.
Open endpoints get abused. Rate limiting, sensible defaults, and layered checks protect a service without punishing legitimate users.
How to ask for telemetry consent in a way that is honest and clear, so the user’s choice is genuinely informed rather than coerced.
Shipping a feature is not the end of the decision. How to assess, after release, whether a feature earned its keep or should be removed.
Powerful tools overwhelm if they reveal everything at once. Progressive onboarding teaches capability in layers, as the user is ready for each one.
How customers judge whether software pricing is fair, and why honest, legible pricing builds more durable trust than psychological tactics.
How to learn what you need about product usage without tracking individuals, using aggregation, on-device processing, and strict data minimization.
Choosing well-understood, proven tools over novel ones is an underrated engineering strategy. Why boring technology often delivers more than exciting alternatives.
Why most documentation goes unread, and how to write docs that answer real questions, stay current, and respect the reader’s time.
Most changelogs are ignored because they list commits, not changes that matter. How to write one that tells users what changed for them and why.
How caching makes applications feel fast, the strategies for keeping cached data fresh, and why invalidation is the hard part.
You can understand how a product is used without surveilling users. Consent, minimal data, and direct channels build a feedback loop people trust.
How offline-first apps reconcile concurrent edits, from last-writer-wins to CRDTs and operational transformation, with the trade-offs of each.
Deletion sounds simple and rarely is. Backups, caches, logs, and third parties all hold copies. A practical approach to honoring deletion requests fully.
Most people never change a default, so defaults are decisions made on their behalf. Setting them in the user’s interest is a core ethical responsibility.
How to use motion to clarify rather than decorate, so animation guides attention and explains change instead of demanding it.
Readability is more than reading level, and information scent decides whether people follow a path. How to assess both so content guides rather than stalls.
A clear-eyed comparison of one-time purchases and subscriptions for independent software, and how the choice should follow the product's costs.
Interfaces compete for attention but rarely support memory. Recognition over recall, durable cues, and respecting working-memory limits make tools easier to return to.
How to design software for a range of neurodivergent needs, from autism to dyslexia, by offering flexibility rather than one fixed experience.
Internal links tell search engines and readers how a site’s ideas connect. A deliberate structure builds topical authority and helps every page be found.
How structured data with schema.org and JSON-LD makes a website machine-readable, and how to add it correctly without misrepresenting your content.
How to choose among Core Data, SQLite, and flat files for an app’s local storage, based on the shape of the data and the queries you need.
Language models retrieve and cite content more reliably when it is structured. How to model content so a passage answers a question on its own.
How the choice of file format determines whether a user’s data survives the software, and why portability is an act of respect.
The real measure of a notification system is how many notifications people leave on. Relevance, control, and restraint keep a channel worth attending to.
Cognitive accessibility is often overlooked. Plain language, predictable structure, and reduced load make products usable for a far wider range of people.
How to structure and write content so AI assistants can understand, summarize, and represent it accurately when generating answers for users.
Launch time is the first impression. How to find what work blocks the first frame and defer or remove it so an app feels instant from the tap.
How to design notifications that genuinely help rather than exploit, respecting the user’s attention as something borrowed, not owned.
Checkout is where doubt is most expensive. Clarity about price, security cues that are real, and recoverable errors decide whether people complete a purchase.
How large language models choose which sources to cite in their answers, and how to structure content so it can be retrieved, extracted, and attributed.
JavaScript is the most expensive resource a page ships. Code splitting, tree shaking, and dependency discipline keep bundles small and pages responsive.
Why adding features steadily makes a product worse, and how scope discipline keeps software focused, maintainable, and genuinely useful.
Schema changes can lock tables and break running code. Backward-compatible, multi-step migrations let a schema evolve without downtime or broken deploys.
How a small team can build a design system that stays useful for years by keeping it minimal, grounded in tokens, and built only as real needs appear.
Everything must work from the keyboard. Visible focus, logical order, and disciplined focus management for menus and dialogs make an interface operable by all.
Why how fast software feels matters as much as how fast it is, and how to design for perceived performance alongside raw numbers.
How to build a typographic system for software using a modular scale, sensible line length and spacing, and a small set of consistent roles.
Dark mode is not an inverted light theme. Semantic color tokens and a few principles let one system serve both modes without maintaining two designs.
Shortcuts only help if people remember them. Consistency, mnemonic mappings, and discoverability turn shortcuts from a hidden feature into a learned habit.
The hidden assumptions about language and text that break software in other locales, and how to design for the world from the start.
Observability is not only for large systems. A small app needs enough logging to answer what happened, without drowning in noise or capturing personal data.
How to meet WCAG accessibility standards while keeping a product visually refined, by treating accessibility as a constraint that improves design.
How interface density affects cognitive load, and how to decide how much to show on screen based on the kind of mental effort a task demands.
The empty state is where users decide to stay or leave. How to design the shortest honest path from a blank screen to the product’s first real value.
A lightweight, practical approach to threat modeling that a small team can actually use to find and prioritize security risks before they ship.
Export is a promise that users own their data. The format decides whether that promise is real. What makes an export complete, open, and actually usable.
How to keep SwiftUI state predictable as an app grows, with guidance on ownership, sources of truth, and the most common mistakes.
Images dominate page weight. How to serve the right format and size, defer offscreen images, and reserve space so layout stays stable as they load.
Why empty and error states deserve as much care as the happy path, and how to turn these moments into guidance instead of dead ends.
How to keep a native macOS app fast by protecting the main thread, measuring with the right tools, and working to explicit performance budgets.
A component library succeeds when it reduces decisions, not when it covers every case. Composition, tokens, and clear ownership keep it usable as it grows.
How to design software that rewards keyboard fluency with shortcuts, command interfaces, and full navigability, without abandoning newcomers.
Streaks and points can support a habit or exploit one. Where motivation design crosses from helping the user into serving engagement at their expense.
How to build a light-mode color system that stays legible and calm, using a small palette, deliberate contrast, and color that carries meaning.
The same screen serves a confused newcomer and a fluent regular. How to design so first-run guidance does not become permanent clutter for returning users.
How to build products that collect only what they need, treating data minimization as an engineering practice rather than a policy afterthought.
Connectivity is intermittent, not binary. How to build apps that stay usable on slow links and degrade gracefully when the network disappears entirely.
How iOS governs background work to protect battery life, and how to schedule deferred tasks that the system will actually run.
API keys, signing certificates, and tokens leak through habit, not malice. Practical secrets hygiene for small teams without enterprise infrastructure.
How to use haptic feedback sparingly and meaningfully, so that touch confirms and guides without adding to the noise of an interface.
Comparing on-device and cloud machine-learning inference across privacy, latency, cost, and capability so teams can choose deliberately.
Reliable undo lets people act without fear. How to design forgiveness through reversible actions, clear scope, and recovery rather than confirmation dialogs.
An error message is a moment of friction that can either rescue or abandon the user. What separates a message that helps from one that blames or confuses.
How Swift’s ownership and reference-counting model prevents whole classes of memory bugs, and the patterns that keep retain cycles and leaks away.
Time is full of traps: offsets, daylight saving, leap seconds, and ambiguous local times. A few disciplines remove most date and timezone bugs.
A practical look at local-first architecture, where the user's device holds the source of truth, and how to weigh its benefits against its costs.
Forms are where many users succeed or give up. Labels, error handling, focus order, and clear instructions decide whether a form is usable by everyone.
Why most onboarding overspends a new user’s attention, and how to design a first run that teaches through use rather than upfront instruction.
Performance budgets turn speed from an afterthought into a constraint. How to set them, tie them to Core Web Vitals, and enforce them before regressions ship.
Why starting a task is harder than doing it, and how interface design can lower the activation cost for people with executive-function differences.
Server rendering, static generation, and full static export each answer different questions about freshness, scale, and cost. How to choose deliberately.
Settings grow faster than navigation can organize them. A good search indexes labels and synonyms, returns the control itself, and tolerates vague queries.
Local notifications seem simple until time zones, limits, and delivery rules intervene. How to schedule them so they fire when and how the user expects.
How to evolve a local data schema across app versions on devices you do not control, with migrations that never silently discard a user’s data.
Notifications are not free. They borrow attention, interrupt working memory, and accrue a cost users eventually repay by disabling them entirely.
Reach, thumb zones, and the realities of holding a large phone in one hand, and how to place primary actions where they can actually be reached.
Color that works for a glance can fatigue over hours. How to build a restrained, low-strain palette that stays comfortable through a long working session.
A practical account of structured concurrency, actors, and data isolation in Swift, with the trade-offs and failure modes that show up in real apps.
How to build focus modes that genuinely narrow attention rather than adding another layer of configuration and noise for the user to manage.