Thank you for your interest in contributing to Handy! This guide will help you get started with contributing to this open source speech-to-text application.
Handy aims to be the most forkable speech-to-text app. The goal is to create both a useful tool and a foundation for others to build upon—a well-patterned, simple codebase that serves the community. We prioritize:
- Simplicity: Clear, maintainable code over clever solutions
- Extensibility: Make it easy for others to fork and customize
- Privacy: Keep everything local and offline
- Accessibility: Free tooling that belongs in everyone's hands
Before you begin, ensure you have the following installed:
-
Fork the repository on GitHub
-
Clone your fork:
git clone git@github.com:YOUR_USERNAME/Handy.git cd Handy -
Add upstream remote:
git remote add upstream git@github.com:cjpais/Handy.git
-
Install dependencies:
bun install
-
Download required models:
mkdir -p src-tauri/resources/models curl -o src-tauri/resources/models/silero_vad_v4.onnx https://blob.handy.computer/silero_vad_v4.onnx
-
Run in development mode:
bun run tauri dev # On macOS if you encounter cmake errors: CMAKE_POLICY_VERSION_MINIMUM=3.5 bun run tauri dev
For detailed platform-specific setup instructions, see BUILD.md.
Handy follows a clean architecture pattern:
Backend (Rust - src-tauri/src/):
lib.rs- Main application entry point with Tauri setupmanagers/- Core business logic (audio, model, transcription)audio_toolkit/- Low-level audio processing (recording, VAD)commands/- Tauri command handlers for frontend communicationshortcut.rs- Global keyboard shortcut handlingsettings.rs- Application settings management
Frontend (React/TypeScript - src/):
App.tsx- Main application componentcomponents/- React UI componentshooks/- Reusable React hookslib/types.ts- Shared TypeScript types
For more details, see the Architecture section in README.md or AGENTS.md.
- Search existing issues at github.com/cjpais/Handy/issues
- Check discussions at github.com/cjpais/Handy/discussions
- Try the latest release to see if the issue has been fixed
- Enable debug mode (
Cmd/Ctrl+Shift+D) to gather diagnostic information
When creating a bug report, please include:
System Information:
- App version (found in settings or about section)
- Operating System (e.g., macOS 14.1, Windows 11, Ubuntu 22.04)
- CPU (e.g., Apple M2, Intel i7-12700K, AMD Ryzen 7 5800X)
- GPU (e.g., Apple M2 GPU, NVIDIA RTX 4080, Intel UHD Graphics)
Bug Details:
- Clear description of the bug
- Steps to reproduce
- Expected behavior
- Actual behavior
- Screenshots or logs if applicable
- Information from debug mode if relevant
Use the Bug Report template when creating an issue.
We use GitHub Discussions for feature requests rather than issues. This keeps issues focused on bugs and actionable tasks while allowing more open-ended conversations about features.
- Search existing discussions at github.com/cjpais/Handy/discussions
- Check common feature requests:
- Go to Discussions
- Click "New discussion"
- Choose the appropriate category (Ideas, Feature Requests, etc.)
- Describe your feature idea including:
- The problem you're trying to solve
- Your proposed solution
- Any alternatives you've considered
- How it fits with Handy's philosophy
This is critical: Before writing any code, please do the following:
-
Search existing issues and PRs - Check both open AND closed issues and pull requests. Someone may have already addressed this, or there may be a reason it was closed.
-
If something was previously closed - If you want to revisit a closed issue or PR, you need to:
- Provide a strong argument for why it should be reconsidered
- Gather community feedback first via Discussions
- Link to that discussion in your PR
-
Get community feedback for features - PRs with demonstrated community interest are much more likely to be merged. Start a discussion, get feedback, and link to it in your PR. This helps ensure Handy stays focused and useful for the most people without becoming bloated.
Community feedback is essential to keeping Handy the best it can be for everyone. It helps prioritize what matters most and prevents feature creep.
-
Create a feature branch:
git checkout -b feature/your-feature-name # or git checkout -b fix/your-bug-fix -
Make your changes:
- Write clean, maintainable code
- Follow existing code style and patterns
- Add comments for complex logic
- Keep commits focused and atomic
-
Test thoroughly:
- Test on your target platform(s)
- Verify existing functionality still works
- Test edge cases and error conditions
- Use debug mode to verify audio/transcription behavior
-
Commit your changes:
git add . git commit -m "feat: add your feature description" # or git commit -m "fix: describe the bug fix"
Use conventional commit messages:
feat:for new featuresfix:for bug fixesdocs:for documentation changesrefactor:for code refactoringtest:for test additions/changeschore:for maintenance tasks
-
Keep your fork updated:
git fetch upstream git rebase upstream/main
-
Push to your fork:
git push origin feature/your-feature-name
-
Create a Pull Request:
- Go to the Handy repository
- Click "New Pull Request"
- Select your fork and branch
- Fill out the PR template completely, including:
- Clear description of changes
- Links to related issues or discussions
- Community feedback (especially important for features)
- How you tested the changes
- Screenshots/videos if applicable
- Breaking changes (if any)
Remember: PRs with community support are prioritized. If you haven't already, start a discussion to gather feedback before or alongside your PR. It is not explicitly required to gather feedback, but it certainly helps your PR get merged faster.
AI-assisted PRs are welcome! Use whatever tools help you contribute, just be upfront about it.
In your PR description, please include:
- Whether AI was used (yes/no)
- Which tools were used (e.g., "Claude Code", "GitHub Copilot", "ChatGPT")
- How extensively it was used (e.g., "generated boilerplate", "helped debug", "wrote most of the code")
Rust:
- Follow standard Rust formatting (
cargo fmt) - Run
cargo clippyand address warnings - Use descriptive variable and function names
- Add doc comments for public APIs
- Handle errors explicitly (avoid unwrap in production code)
TypeScript/React:
- Use TypeScript strictly, avoid
anytypes - Follow React hooks best practices
- Use functional components
- Keep components small and focused
- Use Tailwind CSS for styling
General:
- Write self-documenting code
- Add comments for non-obvious logic
- Keep functions small and single-purpose
- Prioritize readability over cleverness
Manual Testing:
- Run the app in development mode:
bun run tauri dev - Test your changes with debug mode enabled
- Verify on multiple platforms if possible
- Test with different audio devices
- Try various transcription scenarios
Building for Production:
bun run tauri buildTest the production build to ensure it works as expected.
Documentation improvements are highly valued! You can contribute by:
- Improving README.md, BUILD.md, or this CONTRIBUTING.md
- Adding code comments and doc comments
- Creating tutorials or guides
- Improving error messages
- Updating the project website content
- Be respectful and inclusive - We welcome contributors of all skill levels
- Be patient - This is maintained by a small team, responses may take time
- Be constructive - Focus on solutions and improvements
- Be collaborative - Help others and share knowledge
- Search first - Check existing issues/discussions before creating new ones
Look for issues labeled good first issue or help wanted if you're new to the project. These are typically:
- Well-defined and scoped
- Good for learning the codebase
- Mentor support available
- Discord: Join our Discord community
- Discussions: Ask questions in GitHub Discussions
- Email: Reach out at contact@handy.computer
By contributing to Handy, you agree that your contributions will be licensed under the MIT License. See LICENSE for details.
Thank you for contributing to Handy! Your efforts help make speech-to-text technology more accessible, private, and extensible for everyone.