6.8 KiB
Ship-Readiness Audit
Before claiming the app "feels native," walk through this list. Most apps fail 5–10 items on first pass. Each failure costs cheap-to-fix engineering, but compounds.
Score: green ✓ if observably correct, red ✗ if not, gray ◯ if N/A.
A. Cold launch (10 items)
- ◯ App launches from hotkey to visible window in < 200 ms (warm) / < 600 ms (cold).
- ◯ No white/black flash before content appears. (
_doAfterNextPresentationUpdateon Mac,DefaultBackgroundColor+NavigationCompletedon Win.) - ◯ Window appears at the correct screen and position (last position remembered, multi-monitor aware).
- ◯ Initial focus is in the most likely input control. User can type immediately.
- ◯ No "loading…" placeholder visible to the user during normal launch.
- ◯ Dock/Taskbar icon shows correct app icon, not a generic Electron-style icon.
- ◯ Menu bar / system tray icon is monochrome (Mac convention) or follows system theme.
- ◯ ⌘-Space / global hotkey works on first launch without re-registration.
- ◯ App registers with Login Items (Mac) / Startup (Win) on user opt-in, not silently.
- ◯ Quitting the app actually quits — no hidden zombie processes.
B. Window & focus (10 items)
- ◯ ⌘W (Mac) / Ctrl-W (Win) closes the window.
- ◯ ⌘M (Mac) / Win-Down (Win) minimizes.
- ◯ Green button (Mac) zooms to content size, doesn't fullscreen unless Option held.
- ◯ Clicking outside the launcher window dismisses it (if that's the design).
- ◯ Window remembers size and position across launches.
- ◯ Multi-monitor: window opens on the active screen, not always screen 0.
- ◯ Fullscreen mode (if applicable) uses native fullscreen, not a maximized window.
- ◯ Settings opens in a separate native window (⌘, on Mac, Ctrl-, on Win).
- ◯ No modal "dialogs" implemented as DOM overlays. Use NSAlert / MessageBox or native sheets.
- ◯ When the app loses focus, the launcher hides (or follows the configured behavior — but predictably).
C. Input & cursor (10 items)
- ◯ No
cursor: pointeron rows, buttons, or tabs. - ◯ Text selection disabled on labels, headings, button text.
- ◯ Native context menu (or removed entirely), not WebKit's.
- ◯ No link previews on force-touch / long-press.
- ◯ No spellcheck red underlines on chrome.
- ◯ IME composition works correctly (test with Pinyin specifically; Japanese kana; Korean Hangul).
- ◯ Full keyboard navigation: every action reachable via Tab + Enter.
- ◯ Focus rings visible and platform-styled.
- ◯ Escape always does something meaningful — close popover, cancel action, dismiss.
- ◯ Type-ahead in lists: typing letters jumps to matching items.
D. Visual & material (10 items)
- ◯ Window background uses platform material (NSVisualEffectView / Liquid Glass / mica / acrylic).
- ◯ Dark mode follows system, switches without flicker.
- ◯ Accent color matches system accent (not a hardcoded brand color).
- ◯ System font in use; no web font for chrome.
- ◯ No CSS
box-shadowfor window shadow (OS draws it). - ◯ No CSS
border-radiusfor window corners (OS draws them, matching platform radius). - ◯ Translucency works correctly: blur visible through transparent regions.
- ◯ No
cursor: pointer(yes, again — most common offender). - ◯ Animations honor
prefers-reduced-motion. - ◯ No page transitions / route fades.
E. Scrolling (5 items)
- ◯ Overlay scrollbars on Mac (fade out).
- ◯ Thin scrollbars on Win 11; classic if user opted out.
- ◯ No
behavior: 'smooth'on programmatic scroll. - ◯ Scroll inertia feels native, not document-style.
- ◯ Scroll position preserved across navigation within a window.
F. Performance (10 items)
- ◯ Resident memory under 500 MB at idle.
- ◯ No noticeable hitch when expanding/collapsing the search results.
- ◯ No frame drops when typing fast into a search field with live results.
- ◯ Background CPU < 0.5% when window hidden (Mac) / window minimized (Win).
- ◯ Battery impact rated "low" by Activity Monitor (Mac) after 1 hour of idle.
- ◯ Hidden window doesn't get WebKit-throttled (test: scheduled UI updates fire promptly when window re-shown).
- ◯ File indexer doesn't pin a core (off-loaded to Rust subprocess, niced appropriately).
- ◯ Extension/plugin crash doesn't take down the app.
- ◯ Network call timeouts surface as user-visible errors within 10 seconds, not 60.
- ◯ Loading state for any operation > 200 ms; nothing for under.
G. System integration (10 items)
- ◯ URL scheme registered and works system-wide.
- ◯ File associations work; double-clicking an associated file opens the app.
- ◯ Drag-and-drop with real file URLs, accepted by Finder/Explorer correctly.
- ◯ Copy to clipboard writes all expected pasteboard types (text, RTF, HTML for rich content).
- ◯ Save dialogs are native (NSSavePanel / IFileSaveDialog).
- ◯ Native notifications via NSUserNotification / Windows Toast.
- ◯ Auto-update is real (Sparkle / MSIX / custom). User isn't prompted to "download a new version."
- ◯ Crash reports go to a real crash reporter with symbolicated stack traces.
- ◯ Single-instance on Windows (second launch focuses existing instance).
- ◯ Bundle/manifest correct: identifier, version, icon, document types.
H. Accessibility (5 items)
- ◯ VoiceOver / Narrator can navigate the entire interface.
- ◯ Focus is announced when it moves.
- ◯ Color contrast meets WCAG AA.
- ◯ Works with system font size bumped to large.
- ◯ All actions reachable without a mouse.
I. Cross-platform parity (5 items)
- ◯ Mac and Windows ship the same feature set (no "this feature only on Mac").
- ◯ Both shell binaries hit the same IPC schema version after an update.
- ◯ Extensions written by third parties work identically on both OSes.
- ◯ Visual differences between OSes match platform conventions, not arbitrary.
- ◯ Bug fixes propagate to both OSes from a single codebase change in most cases.
How to use this list
For a v1.0 launch: aim for 90% green. The 10% red should all be in section H (accessibility) or I (cross-platform parity) where some lag is acceptable. Reds in A–G are launch blockers.
For a code review: pick the 5–10 items most relevant to the PR's surface area and check them explicitly.
For a regression audit after a refactor: walk the whole list. Refactors tend to silently undo native-feel work.
The single most diagnostic test
Hand the app to a designer who uses native Mac/Windows apps daily but has never seen yours. Don't tell them anything. Watch for the first time they say "wait, this feels weird." That moment is one of the items above. Find it, fix it, ship.