Thank you for your interest in contributing to VoiceWrite!
- macOS 26.0+ (Tahoe)
- Xcode 16+ with Command Line Tools
- Swift 6.2
git clone https://github.com/leftouterjoins/voicewrite.git
cd voicewrite
make buildmake runVoiceWrite/
├── App/ # App entry point
│ └── VoiceWriteApp.swift
├── Core/
│ ├── Models/ # AppState, data types
│ └── Services/ # Audio, transcription, typing, permissions
├── Features/
│ ├── MenuBar/ # Menu bar popover UI
│ ├── Settings/ # Settings window
│ └── ListeningOverlay/ # Screen border animation
└── Resources/ # Assets
Follow Swift conventions:
- Use
letovervarwhen possible - Prefer value types (structs/enums) over classes
- Use
async/awaitfor asynchronous code - Mark ViewModels with
@MainActor - Use guard clauses for early returns
// Types: UpperCamelCase
struct TranscriptionResult { }
// Properties/methods: lowerCamelCase
var isRecording: Bool
func startTranscription() async throws
// Booleans: use "is", "has", "should" prefixes
var isEnabled: Bool
var hasUnsavedChanges: Bool- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes
- Ensure the build succeeds:
make build - Commit with a clear message
- Push to your fork
- Open a Pull Request
- Keep changes focused and atomic
- Update documentation if needed
- Add tests for new functionality when applicable
- Follow existing code patterns
When opening an issue:
- Use the issue templates
- Include your macOS version
- Provide steps to reproduce
- Attach console logs if relevant (Console.app → filter by "VoiceWrite")
Open a Discussion in the Q&A category.
By contributing, you agree that your contributions will be licensed under the MIT License.