macos-patterns

Essential native macOS development patterns that web developers don't know about. Use this skill whenever the user is building a macOS app and needs guidance on native patterns, or when they ask about menu bar apps, floating panels, window levels, keyboard shortcuts, file pickers, clipboard, drag an

By fayazara · 475 installs

npx skills add fayazara/macos-app-skills --skill macos-patterns

Source repository · Upstream listing

Native macOS Patterns for Web Developers This is a reference guide for the macOS specific patterns that have no web equivalent. When building a native macOS app, these are the things that trip up everyone coming from web development. The AI should consult this before generating macOS code to avoid confidently producing patterns that don't work. Menu Bar Apps There are two approaches. Use MenuBarExtra for simple menus, NSStatusItem for full control. SwiftUI MenuBarExtra (simple) This creates a menu bar only app. The menu content is a standard SwiftUI view. For a popover style menu bar app (richer UI than a plain menu), use the .window style: AppKit NSStatusItem (full control) For custom menus, dynamic icons, or complex interactions: isTemplate = true is essential. Without it, your icon will be invisible in light mode or look wrong in dark mode. NSPopover for Rich Menu Bar Content For a popover attached to the menu bar icon (like Bartender, iStatMenus): Activation Policy Dock Icon Toggling A macOS app can dynamically show/hide its Dock icon and Cmd Tab presence at runtime. Menu bar only apps start as .accessory (invisible in Dock) and temporarily become .regular when they open windows like Settings. Use reference counting if multiple windows can be open simultaneously: NSPanel vs NSWindow NSPanel is a subclass of NSWindow for auxiliary content that should not steal focus. Use it for: Floating overlays (preview cards, recording indicators) Palettes and tool windows Inspectors Anything that should stay visible while the user works in another app Key configuration: To host SwiftUI content in the panel: Override focus behavior when needed: Screen Capture Exclusion If your app shows floating UI that shouldn't appear in screenshots/recordings: Window Levels macOS has a multi tier window level system that controls where windows appear relative to the entire OS (not just your app): Set via: Collection Behaviors Control how windows interact with Spaces, fullscreen, and Cmd Tab: Screen Geometry macOS uses bottom left origin coordinates. The Y axis is flipped compared to the web. Use frame when positioning over the menu bar (notch overlays). Use visibleFrame for normal window placement. Quartz vs AppKit Y Axis Core Graphics / Quartz uses top left origin . AppKit uses bottom left origin . When converting between the two: Multi Monitor Never assume a single screen. Always handle the case where NSScreen.main is not the only display: Keyboard Shortcuts There are 3 tiers, each for different use cases. Tier 1: SwiftUI keyboard shortcuts (in app, when focused) Tier 2: NSEvent monitors (app wide or global) Returning nil from a local monitor consumes the event (stops propagation). Global monitors cannot consume events. Tier 3: Carbon hotkeys (system wide, works when app is not focused) The only way to register true global keyboard shortcuts. Uses the Carbon API (1990s era, still not deprecated): The callback runs on an arbitrary thread always dispatch to main: File Pickers Open (select files/directories) Save Directory picker Clipboard / Pasteboard macOS's pasteboard is fundamentally different from the web's navigator.clipboard . It is a multi item, multi type container. A single pasteboard item can advertise multiple types. When reading, check types in priority order. Drag and Drop SwiftUI (simple) AppKit (full control) Register as a drop target: NavigationSplitView + Inspector Layout The native macOS pattern for a sidebar + detail + inspector layout: The .inspector() modifier creates a native right side panel that slides in/out, automatically manages layout, and integrates with the window's toolbar. Launch at Login Use SMAppService (macOS 13+): The requiresApproval state is unique to macOS the app has asked to launch at login, but the user must manually approve it in System Settings General Login Items. Always disable in debug builds to avoid polluting the login item list during development. Quick Look Preview Show a system Quick Look panel for any file (images, PDFs, videos, documents): NSWorkspace OS Integration UserDefaults + @AppStorage Programmatic access Reactive SwiftUI binding @AppStorage automatically reads from and writes to UserDefaults , and triggers SwiftUI view updates when the value changes. ScreenCaptureKit Capture screen content at native Retina resolution: The points to pixels conversion is critical. ScreenCaptureKit works in points, but output dimensions must be in pixels for Retina resolution. Common Mistakes Web Devs Make What they try Why it fails What to do instead SwiftUI Window scene for floating UI Steals focus, shows in Dock, no transparency Use NSPanel with .nonactivatingPanel z index thinking for window ordering macOS uses discrete window levels, not a flat stack Set window.level to .floating , .screenSaver , etc. window.innerHeight for positioning Doesn't account for menu bar, Dock, or notch Use NSScreen.visibleFrame or .frame depending on context navigator.clipboard.writeText() macOS requires clearContents() first Always call pasteboard.clearContents() before writing addEventListener('keydown') for global shortcuts Only works when app is focused Use Carbon RegisterEventHotKey for system wide <input type="file" mental model macOS has modal, sheet modal, and async file pickers Use NSOpenPanel with the right presentation mode Single monitor assumptions macOS users commonly have 2 3 displays Always use NSScreen.screens and find the right one CSS animation for everything macOS has spring physics, reduced motion, per window animation Use SwiftUI .animation(.spring(...)) and check accessibilityDisplayShouldReduceMotion