A lightweight macOS app that replaces Voice Memos with superior, on-device transcription. All processing happens locally—no cloud uploads, no privacy compromises. MarkdownMax delivers transcription quality that exceeds Voice Memos' native capabilities while keeping everything on your device.
Current transcription solutions are fragmented and inadequate:
- Voice Memos provides no transcription or poor quality transcription
- Third-party services require manual uploads and have high latency
- No single, integrated place to capture, transcribe, and organize audio
- Students and professionals waste significant time manually taking notes or re-listening to content
- Existing tools don't preserve context or allow easy searching through recordings
- Students – need accurate lecture transcriptions for studying and note-taking
- Founders & Entrepreneurs – want to record and transcribe meetings, investor calls, and brainstorming sessions
- Professionals – need quick access to transcribed conference sessions and training materials
- Researchers – require high-quality transcripts of interviews and recorded discussions
- Local-only transcription – all processing on-device, no cloud uploads, no data leaving your Mac
- Superior accuracy – transcription quality exceeds Voice Memos' native capabilities
- One-click recording – simple, native macOS experience with faster startup than Voice Memos
- Real-time processing – transcription happens as you record (or immediately after)
- Smart searchability – full-text search across all recordings and transcripts
- Auto-organization – automatic tagging and categorization by topic, date, and speaker
- Markdown export – export transcripts as formatted markdown for easy integration with note-taking apps
- Complete privacy – recordings and transcripts never leave your device
- Local ML models – leverage modern on-device speech recognition (e.g., Whisper, native macOS APIs)
- Minimal dependencies – lightweight app that runs without cloud infrastructure
- Optimized for Apple Silicon – built for M1/M2/M3 Macs to ensure fast, efficient transcription
- Storage efficiency – intelligent compression and local database for fast search and retrieval
- Modern on-device ML models (Whisper, etc.) now offer accuracy comparable to cloud services
- Privacy concerns and data protection regulations make local-only solutions increasingly valuable
- Apple Silicon enables fast, efficient ML inference on consumer hardware
- Remote work and hybrid meetings have increased demand for accurate recording and note-taking
- Existing solutions (Otter.ai, Fireflies, etc.) require cloud uploads and ongoing subscriptions
- Users increasingly prefer tools that keep sensitive meeting/lecture data local and secure
Why SwiftUI over alternatives:
- Native performance: Direct access to macOS APIs without Electron overhead
- Modern syntax: Declarative UI, clean code, built for macOS
- Menu bar support: MenuBarExtra component for seamless menu bar integration
- Low memory footprint: ~50MB base vs Electron's 150MB+
- Instant startup: <2 seconds launch time
- Full macOS integration: Keyboard shortcuts, notifications, Finder drag-and-drop
Alternative considered (Electron): ❌ Rejected
- 3x larger app size (~150MB vs ~50MB)
- Extra screen recording permissions complexity
- Slower transcription performance (unnecessary overhead)
| Model | Word Error Rate (WER) | Speed (10min audio) | Best For |
|---|---|---|---|
| Whisper Medium (MLX) | 2-3% | 2-3 minutes | CHOSEN: Best balance |
| Whisper Large V3 | 1% | 5-7 minutes | Premium tier option |
| Apple SpeechAnalyzer (new) | ~8% | 45 seconds | Fallback/speed option |
- Accuracy: 2-3% WER—excellent for lectures, meetings, technical content
- Speed: 2-3 minutes for 10-minute audio on M1/M2/M3 (acceptable for post-recording)
- Privacy: 100% local, no data transmission required
- Licensing: MIT license—fully open source, permitted for commercial bundling
- GPU acceleration: Metal framework provides 8-12x speedup on Apple Silicon
- Model size: 1.5GB model bundled with app
- Users who prioritize accuracy over speed can optionally download Large model
- Large model: 1% WER, 5-7 minute transcription (ideal for legal/medical use)
-- Installed models tracking
CREATE TABLE installed_models (
id INTEGER PRIMARY KEY,
model_name TEXT NOT NULL UNIQUE, -- 'tiny', 'small', 'medium', 'large'
version TEXT, -- e.g. '3.1.0'
file_path TEXT NOT NULL, -- ~/Library/Application Support/MarkdownMax/models/whisper-medium/
size_mb INTEGER, -- Size in MB
is_active BOOLEAN DEFAULT 0, -- Currently selected model
downloaded_at TIMESTAMP,
last_used TIMESTAMP
);
-- Recordings metadata
CREATE TABLE recordings (
id INTEGER PRIMARY KEY,
filename TEXT NOT NULL,
file_path TEXT NOT NULL,
duration_seconds INTEGER,
date_created TIMESTAMP,
waveform_data BLOB, -- For waveform visualization
transcribed_with_model TEXT, -- Which model transcribed this ('medium', 'small', etc.)
transcription_status TEXT -- 'pending', 'transcribing', 'complete', 'failed'
);
-- Transcripts with timestamps
CREATE TABLE transcripts (
id INTEGER PRIMARY KEY,
recording_id INTEGER,
text TEXT,
confidence_score REAL,
start_time REAL,
end_time REAL,
FOREIGN KEY (recording_id) REFERENCES recordings(id)
);
-- Full-text search index for fast transcript searching
CREATE VIRTUAL TABLE transcript_search USING fts5(
content=transcripts,
text,
recording_id
);- Zero dependencies: Single .sqlite file, no external services
- Fast search: FTS5 (Full-Text Search) indexes transcripts for instant search
- Scales predictably: 10,000+ recordings with indexed queries in <100ms
- File-based: Automatic backups via Time Machine, user-controlled storage
- Privacy: All data stored locally in one encrypted file
- Search 10,000 transcripts: <50ms with FTS5 index
- Batch insert 1,000 recordings: <500ms
- Typical database size: ~100 KB per 10-minute recording (metadata + index)
| Format | File Size (per 10 min) | Transcription Speed | Recommendation |
|---|---|---|---|
| WAV (Linear PCM) | 10.6 MB | Fastest | PRIMARY |
| AAC | 1.2 MB | Slightly slower | Archive format |
| FLAC | 4 MB | Good | Optional |
- Lossless: Perfect audio quality for transcription accuracy
- Whisper-optimized: No resampling needed (Whisper expects 16-bit PCM)
- Fast transcription: Whisper processes WAV format optimally
- Post-processing: Record as WAV, optionally convert to AAC for archival
// AVAudioEngine for real-time recording
let audioEngine = AVAudioEngine()
let inputNode = audioEngine.inputNode
// Record at 48 kHz (Whisper will auto-resample to 16 kHz)
let audioFile = AVAudioFile(forWriting: fileURL, settings: [
AVFormatIDKey: kAudioFormatLinearPCM,
AVSampleRateKey: 48000,
AVNumberOfChannelsKey: 1 // Mono
])
// Install tap and write to file
inputNode.installTap(...)- Sample rate: 48 kHz (Whisper auto-resamples to 16 kHz if needed)
- Bit depth: 16-bit (standard for speech recognition)
- Channels: Mono (sufficient for single speaker, more efficient)
- Buffer size: 64-128 samples for low-latency monitoring
Download source: Hugging Face Hub (free, established)
- Each model hosted as separate repo:
whisper-tiny,whisper-small,whisper-medium,whisper-large - Models in MLX format (already quantized and optimized)
- Public repos (anyone can download, no auth required)
- Download via CDN (fast, reliable)
App's download logic:
// Example download URL
let modelURL = URL(string: "https://huggingface.co/models/ish/whisper-medium-mlx/resolve/main/model.mlx")
// Download manager:
// 1. Check if model exists locally
// 2. If not, fetch from HF CDN
// 3. Show progress bar
// 4. Verify checksum
// 5. Update installed_models tableAdvantages:
- No hosting costs (Hugging Face is free)
- No bandwidth costs (HF handles CDN)
- Version control built-in
- Community can fork/improve models
~/Library/Application Support/MarkdownMax/
├── models/
│ ├── whisper-tiny/
│ │ ├── model.mlx (~39 MB)
│ │ └── config.json
│ ├── whisper-small/
│ │ ├── model.mlx (~244 MB)
│ │ └── config.json
│ ├── whisper-medium/
│ │ ├── model.mlx (~1.5 GB)
│ │ └── config.json
│ └── whisper-large/
│ ├── model.mlx (~3 GB)
│ └── config.json
├── database.sqlite
└── recordings/
- App size: ~50-100MB (vs ~3GB bundled) = 30-60x smaller
- User choice: User controls which models to download based on needs
- Storage control: Users can delete unused models anytime
- Flexibility: Easy to add new models without app updates
- Lower friction: Faster initial install, easier adoption
- App downloads without models (~50-100MB DMG)
- First launch: Onboarding flow to select and download desired model(s)
- Model management: Settings window to download/delete/switch models
- Runtime: App checks for installed models, uses selected one
| Model | Size | WER | Speed (10min) | Best For | RAM |
|---|---|---|---|---|---|
| Tiny | 39 MB | 4-5% | 8 sec | Quick transcription, lower accuracy | 1 GB |
| Small | 244 MB | 3-4% | 45 sec | Balanced, works on older Macs | 2 GB |
| Medium | 1.5 GB | 2-3% | 2-3 min | RECOMMENDED for most users | 4-6 GB |
| Large | 3 GB | 1% | 5-7 min | Premium accuracy (legal/medical) | 8-10 GB |
- Download: In-app download manager with progress bar
- Delete: Remove any model to free up space
- Switch: Change active model in settings (instant)
- Version tracking: Each model has version number (independent of app version)
- Model updates: Users can re-download updated models without app update
- Metal acceleration: Uses GPU for 8-12x speedup on M1/M2/M3
- Minimal dependencies: Pure framework, no Python required
- Quantization support: int8 quantization = 4x smaller model with minimal accuracy loss
- MIT licensed: Free for commercial use
| Mac | Model | Duration | Time | Real-time factor | RAM |
|---|---|---|---|---|---|
| M1 | Tiny | 10 min | 50 sec | 10x | 1 GB |
| M1 | Medium | 10 min | 2:30 | 4x | 5 GB |
| M2 | Small | 10 min | 45 sec | 11x | 2 GB |
| M2 | Medium | 10 min | 2:00 | 5x | 5 GB |
| M3 | Medium | 10 min | 1:45 | 5.7x | 5 GB |
| M3 | Large | 10 min | 5:00 | 2x | 8 GB |
Design approach:
@main
struct MarkdownMaxApp: App {
var body: some Scene {
MenuBarExtra("MarkdownMax", systemImage: "waveform.circle") {
VStack(spacing: 12) {
HStack {
Circle()
.fill(isRecording ? Color.red : Color.gray)
.frame(width: 8, height: 8)
Button(action: toggleRecording) {
Text(isRecording ? "Stop Recording" : "Start Recording")
}
.keyboardShortcut("r", modifiers: [.command])
}
Divider()
// Recent recordings list
VStack(alignment: .leading, spacing: 8) {
ForEach(recentRecordings) { recording in
RecordingRow(recording)
}
}
Divider()
HStack {
Button("Settings", action: openSettings)
.keyboardShortcut(",", modifiers: [.command])
Spacer()
Button("Quit", action: NSApp.terminate)
.keyboardShortcut("q", modifiers: [.command])
}
}
.frame(width: 300)
}
}
}| Shortcut | Action |
|---|---|
| ⌘R | Toggle recording (works in any app) |
| ⌘⇧T | Open transcript of last recording |
| ⌘, | Open settings |
| ⌘Q | Quit app |
Implementation: Use KeyboardShortcuts library (Sindre Sorhus, via SPM)
- Right-click context menu: "Transcribe with MarkdownMax" for audio files
- Drag-and-drop: Drag audio files to menu bar icon to transcribe
- Notifications: Show progress via macOS Notification Center
- Spotlight indexing (v1.1+): Make transcripts searchable via Spotlight
1. App launches
2. Detects: No models installed
3. Shows: "Welcome to MarkdownMax"
4. User selects: Model(s) to download
- "I want fast transcription" → Tiny (39 MB)
- "Balanced & accurate" → Medium (1.5 GB) ← DEFAULT
- "Maximum accuracy" → Large (3 GB)
- "I'm not sure" → Medium recommended
5. Downloads selected model(s) with progress bar
6. Completion: "Ready to record!"
7. First recording starts immediately
Installed Models Section:
- Tiny (39 MB) — Not installed | Download | Delete
- Medium (1.5 GB) — Active model | Delete | Switch | Re-download (update)
- Large (3 GB) — Not installed | Download
Active Model:
- Current: Medium
- Switch to: [Dropdown selector]
- Auto-switch on space low: [Toggle] — If <1GB free, auto-switch to smaller model
Storage:
- Total models size: 1.5 GB / 4.5 GB available
- Clear all models: [Button]
- Main: Menu bar popover (no separate window needed)
- Onboarding: Modal on first launch (model selection)
- Transcript: Full transcript view with export options (separate window)
- Settings: Model management, keyboard shortcuts, storage, advanced options
- App download (DMG): ~50-100 MB (no models included)
- User downloads models on-demand: 39 MB (Tiny) to 3 GB (Large)
- Total installed: 50-100 MB + selected model(s)
Benefits of small app download:
- Fast initial install (seconds vs minutes)
- Lower barrier to trying the app
- Users only download the models they need
- Easy to switch/delete models as needs change
- ✅ Full control over pricing and features
- ✅ Faster updates (no review process, users update models independently)
- ✅ Better privacy messaging ("We distribute & handle your data")
- ✅ Can offer beta/early access
- ✅ No 30% revenue cut
- ✅ Better alignment with privacy-first positioning
- ✅ Model updates independent from app updates (users control which models to use)
- Developer ID certificate ($99/year Apple Developer membership)
- Code signing script in build pipeline
- Notarization (Apple's automated malware scan, ~5-15 min)
- DMG package creation for distribution
- Website hosting with download link
- Gumroad or payment processor (if paid version)
- Auto-update mechanism (Sparkle framework recommended)
- Primary: Website with direct .dmg download
- Payment (if paid): Gumroad ($0 fees for free, revenue share for paid)
- Optional: Homebrew Cask (free, great for open source versions)
- Optional: Setapp (revenue share, wider audience)
# Step 1: Code signing (done in Xcode build process)
codesign --deep --force --verify --verbose --sign "Developer ID Application: Your Name" MarkdownMax.app
# Step 2: Create DMG for distribution
hdiutil create -volname MarkdownMax -srcfolder build/ -ov -format UDZO MarkdownMax.dmg
# Step 3: Notarize (submit to Apple)
xcrun notarytool submit MarkdownMax.dmg \
--apple-id your-email@example.com \
--team-id YOUR_TEAM_ID \
--password app-specific-password
# Notarization completes in 5-15 minutes, results emailed- Whisper model: MIT License (✅ permitted for commercial bundling, no attribution required but recommended)
- Code: Choose your own (recommend: MIT or GPL depending on openness goals)
MarkdownMax collects NO data.
- Audio recordings are stored ONLY on your Mac
- Transcripts are stored ONLY on your Mac
- No analytics, crash reports, or telemetry
- Speech recognition model runs offline
- No internet connection required or used
- Recordings and transcripts remain under your control
- GDPR: ✅ Fully compliant (local storage, no data transmission)
- HIPAA: ✅ Suitable for medical/legal use (local-only encryption)
- CCPA: ✅ Compliant (no data collection)
- Attorney-client privilege: ✅ Protected (data stays on device)
- Terms of Service (can be minimal for local app)
- Privacy policy (use template above)
- OpenAI Whisper attribution: "Powered by OpenAI Whisper" (optional but good practice)
- No analytics or telemetry code
On Apple Silicon:
| Mac | 5-min audio | 10-min audio | 30-min audio |
|---|---|---|---|
| M1 | 1 min 15 sec | 2 min 30 sec | 7 min 30 sec |
| M2 | 1 min | 2 min | 6 min |
| M3/Pro | 50 sec | 1 min 45 sec | 5 min 15 sec |
- CPU-only: 1x speed (~30 min for 10-min audio)
- Metal GPU acceleration: 8-12x faster (2-3 min for 10-min audio)
- Tiny (39M): 10 min audio → 8 seconds
- Base (74M): 10 min audio → 15 seconds
- Small (244M): 10 min audio → 45 seconds
- Medium (769M): 10 min audio → 2-3 minutes ← We use this
- Large (1.5B): 10 min audio → 5-7 minutes
- Launch: <2 seconds
- Start recording: <500ms
- Transcription: Depends on audio duration (see above)
- Full-text search: <50ms for 10,000 recordings
- Transcript export: <1 second
- SwiftUI app scaffold with menu bar (MenuBarExtra)
- AVAudioEngine recording (WAV output)
- Permission handling (microphone access)
- SQLite database schema (records, transcripts, installed_models)
- Basic UI: Start/Stop recording button
- Model download manager (from Hugging Face)
- Model storage in ~/Library/Application Support/MarkdownMax/models/
- Onboarding flow (first launch model selection)
- Settings window for model download/delete/switch
- Track installed models in database
- Test model selection and switching
- MLX-Whisper integration with selected model
- Transcription pipeline (record → transcode → transcribe)
- Real-time transcription progress UI
- Handle missing model error (prompt to download)
- FTS5 full-text search implementation
- Recording list UI with search
- Persistent storage of transcripts
- Track which model transcribed each recording
- Markdown export (with timestamps)
- TXT and PDF export options
- Keyboard shortcuts (global ⌘R, ⌘⇧T, etc.)
- Menu bar UI refinement (recent recordings list)
- Finder integration (drag-and-drop, right-click)
- Notification Center progress updates
- Code signing setup
- Notarization process
- DMG creation and testing
- Website setup with download link
- ✅ One-click recording
- ✅ Automatic transcription with selected model
- ✅ Onboarding & model selection (first launch)
- ✅ Model download/delete/switch in settings
- ✅ Full-text search
- ✅ Markdown export
- ✅ Menu bar interface
- ✅ Keyboard shortcuts
- ✅ All 4 model options available (Tiny, Small, Medium, Large)
- 🎯 Speaker diarization (who spoke when)
- 🎯 Auto-tagging (extract topics, people, dates)
- 🎯 Spotlight integration (search OS-wide)
- 🎯 Waveform visualization
- 🎯 Auto-switch to smaller model if storage is low
- 🎯 Model updates (re-download newer versions)
All components are well-documented, proven, and production-ready:
- SwiftUI + AVAudioEngine: Mature, widely used
- Whisper models: Proven accuracy, MIT licensed, available on Hugging Face
- MLX framework: Fast, documented, Metal acceleration works
- SQLite: Bulletproof, zero dependencies
- macOS code signing/notarization: Well-established process
- Model downloads: Straightforward HTTP download from Hugging Face CDN
Architecture advantages of on-demand model downloads:
- Minimal app size (~50-100 MB) = low friction for adoption
- Users control storage vs accuracy tradeoff
- Model updates independent from app releases
- Easy A/B testing different models for users
- Scales well: can add new models without app update
Ready to begin development.
- SwiftUI scaffold + menu bar (MenuBarExtra)
- AVAudioEngine recording (WAV format)
- SQLite database schema (with installed_models table)
- Basic recording UI (Start/Stop button)
Week 3-4 introduces model management (download, select, delete) which will be the core differentiator.