Role Product Designer and founder, responsible for product direction, visual and interaction design, and every final decision.
Team Solo project. Product direction and every design decision are mine, with AI tools supporting the native build and documentation along the way.
Final platform Native iOS: SwiftUI + SwiftData, with a Home Screen widget (WidgetKit).
Starting point A working web MVP (React 18 + Vite 5, installable PWA), shipped as v1.0 in March 2026.
Process 5 documented phases and 22 days of structured work: product discovery, visual language & IA, native implementation, refinement, and release.
Status v1.0 on TestFlight. Full QA on simulator and on physical device; no open issues ahead of launch.
Project goal A polished, coherent portfolio piece, not user growth or usage metrics. Built, first and foremost, for Carlos’s own Bullet Journal practice.

Background

I keep a paper Bullet Journal, but a thought doesn’t always show up when the notebook is in front of me. JournalApp isn’t a notes app — it’s a fast-capture layer whose only job is to keep a fleeting thought alive until it can be written by hand. The notebook is permanent; the phone, deliberately, is not.

Process

Five phases across 22 days, planned before any of them started: product discovery, visual language & IA, native implementation, refinement, and release. The project started from a web MVP (React + Vite) that validated the concept — but every interaction was reinterpreted as if it had been designed natively for iOS from the start, never translated literally.

Result

JournalApp now lives as v1.0 on TestFlight: a native iOS app with instant capture, Bullet Journal notation, migration and review, and a Home Screen widget. Full QA on simulator and on physical device — no open issues ahead of launch.

The problem

I keep a paper Bullet Journal. The notebook is where I actually think, but a thought doesn’t always show up when the notebook is in front of me — it shows up on the subway, mid-call, halfway through a meeting. Notes apps solve that gap by becoming the thought’s final destination: folders, tags, formatting, semantic search. JournalApp starts from the opposite premise — the phone shouldn’t compete with the notebook for that thought; it should just hold it for a moment.

I wanted an app with just the features I actually needed, nothing that would distract me or pull me into doomscrolling. That’s why JournalApp isn’t a notes app. It’s a fast-capture layer whose only job is to keep a fleeting thought alive until it can be written by hand. The notebook is permanent; the phone, deliberately, is not.

The notebook is where thinking happens. The app’s only job is keeping a thought alive until it gets there.
— JournalApp Manifesto

Philosophy and principles

Before writing a single line of SwiftUI, I spent the entire first phase defining what JournalApp is and what it refuses to become — its philosophy, principles, and an explicit list of boundaries. Every decision after that traces back to one question:

Does this strengthen the relationship between the user and their notebook, or the relationship between the user and JournalApp?

The manifesto boils down to six lines, held as a design criterion across the whole sprint:

  • Software doesn’t have to compete for your attention. This one won’t.
  • Handwriting is slow on purpose. That’s not a flaw to fix.
  • We say no far more often than yes. Every feature added is a small vote for the app over the notebook.
  • Migrating a thought isn’t “completing” it. It’s sending it home.
  • JournalApp isn’t trying to become anyone’s second brain.
  • Success doesn’t look like engagement. It looks like barely remembering you used the app.

That last line also defined the product’s explicit boundaries: no tags, folders, accounts, cloud sync, or gamification — each deliberately rejected during discovery, because any of them would turn JournalApp into the destination instead of the bridge.

Diagram: Capture and Review overlap in the essential core the app kept, while rejected features like tags, folders, accounts, cloud sync, gamification, and streaks orbit outside as feature creep
Every feature considered had to earn its place inside the overlap. Everything on the right was easier to say no to than it looks.

Process: five phases, twenty-two days

No improvising: every day of the sprint belonged to one of five phases, planned before any of them started.

01
Product discovery

Philosophy, principles, mental model, information architecture.

Discovery
02
Visual language

Moodboard, typography, colour, iconography, paper textures.

Visual & IA
03
Native implementation

Xcode project, home screen, quick capture, edit/delete, migration, search and menu.

SwiftUI
04
Refinement and internal user testing

Visual direction review, motion and haptics, typography and colour, microcopy, internal testing.

Polish
05
Release

TestFlight prep, screenshots, icon, splash screen, release notes, final QA.

Release

Wireframes and process

Before touching real UI chrome, I mapped every core screen by hand: Capture, Search, Review with its bottom navigation, the onboarding Guide, and the Widget and Apple Watch surfaces. These aren’t clean deliverables, they’re working sketches, with open questions annotated straight onto the page exactly as they came up.

Early exploration wireframes

Hand-drawn wireframe of the JournalApp Capture screen, with notation and layout notes
Capture
Hand-drawn wireframe of the JournalApp Search screen
Search
Hand-drawn wireframe of the JournalApp Review mode and bottom navigation
Review and navigation
Hand-drawn wireframe of the JournalApp onboarding Guide screen
Guide
Hand-drawn wireframe exploring the JournalApp Widget, Apple Watch, and Notes ideas
Widget, Apple Watch and notes

Early, low-fidelity prototypes

Low-fidelity block wireframe of the JournalApp Capture screen
Capture
Low-fidelity block wireframe of the JournalApp Review sheet
Review
Low-fidelity block wireframe of the JournalApp Settings sheet
Settings

From web MVP to native app

The web MVP (React + Vite, installable PWA) validated the concept with real use, but nothing carried over literally: every interaction was reinterpreted as if designed natively for iOS from the start. Typography was the clearest audit — the MVP’s chrome used the system typeface, San Francisco, so I kept that and let Merriweather carry the captured text instead: a neutral sans for the chrome, a literary serif for the content.

The four fixed interactions

The interaction design rests on four gestures I treated as non-negotiable from early on, documented clearly so they wouldn’t drift over time:

  • Swipe left = delete, with a 3-second undo window.
  • Swipe right = migrate, instant and with no undo: migrating and deleting shouldn’t feel equally reversible.
  • No save button: autosave on every keystroke.
  • One thought, one capture: no sub-notes or nesting.

On top of that I built a notation system inherited directly from paper Bullet Journaling: “· ” for a task, “– ” for a note, “o ” for an event (rendered as °), and “* ” for priority (a boolean signifier on a task, not a fourth type). The marks render as real typographic characters, not system icons, because a Bullet Journal mark should read as something a hand would write.

JournalApp Settings screen — appearance, texture and typeface options
Settings — a warm terracotta accent over paper textures carries the product’s identity
JournalApp Guide screen with the Playbook's own editorial voice
Guide — the Playbook’s own editorial voice
JournalApp Home Screen widget on iOS showing pending count
Home Screen widget — refined over five rounds of on-device testing
JournalApp Review mode, a ritual paced slower than Capture
Review — a deliberate ritual, paced slower than Capture

Screens

JournalApp Capture screen, empty state
Capture — empty
JournalApp Capture screen, populated with tasks, notes and events
Capture — populated
JournalApp Review mode
Review
JournalApp Migrated view, last 7 days
Migrated — last 7 days
JournalApp Guide screen
Guide

Reflection

What I value most about this project isn’t any single screen, but the discipline of the process: writing the philosophy before the code, auditing every assumption inherited from the MVP instead of taking it for granted, and being willing to build something complete (a grid texture, a weekly-calendar gesture) and pull it once it was built and tested and simply didn’t serve the concept. In a product whose measure of success is that the user “barely remembers using the app,” that same restraint had to govern my own design process too.

If a future version of JournalApp forgets any of this, it isn’t JournalApp anymore. It’s just another notes app.