We love your input! We want to make contributing to VibeTunnel as easy and transparent as possible, whether it's:
- Reporting a bug
- Discussing the current state of the code
- Submitting a fix
- Proposing new features
- Becoming a maintainer
- macOS 14.0+ (Sonoma or later)
- Xcode 16.0+ with Swift 6.0 support
- Node.js 22.12+:
brew install node - Bun runtime:
curl -fsSL https://bun.sh/install | bash - Git: For version control
-
Fork and clone the repository
git clone https://github.com/[your-username]/vibetunnel.git cd vibetunnel -
Set up development environment
# Install Node.js dependencies cd web pnpm install # Start the development server (keep this running) pnpm run dev
-
Open the Xcode project
# From the root directory open mac/VibeTunnel-Mac.xcodeproj -
Configure code signing (optional for development)
- Copy
apple/Local.xcconfig.templatetoapple/Local.xcconfig - Add your development team ID (or leave empty for ad-hoc signing)
- This file is gitignored to keep your settings private
- Copy
The web server (Node.js/TypeScript) runs in development mode with hot reloading:
cd web
pnpm run dev # Keep this running in a separate terminalCustom Port Configuration (if port 4020 is already in use):
# Option 1: Run server directly with custom port (cleanest approach)
pnpm run dev:server --port 4021
# Option 2: Using environment variable
PORT=4021 pnpm run dev
# Option 3: Using the full dev command with arguments (requires --)
pnpm run dev -- --port 4021Development Commands:
pnpm run dev- Run everything (server, client watcher, CSS, assets)pnpm run dev:server- Run just the server (accepts --port directly!)pnpm run dev:client- Run just client-side watchers
Important: Never manually build the web project - the development server handles all compilation automatically.
- Open
mac/VibeTunnel.xcworkspacein Xcode - Select the VibeTunnel scheme
- Build and run (⌘R)
The app will automatically use the development server running on http://localhost:4020.
- Open
ios/VibeTunnel.xcodeprojin Xcode - Select your target device/simulator
- Build and run (⌘R)
We use modern Swift 6.0 patterns with strict concurrency checking:
- SwiftFormat: Automated formatting with
.swiftformatconfiguration - SwiftLint: Linting rules in
.swiftlint.yml - Use
@MainActorfor UI-related code - Use
@Observablefor SwiftUI state objects - Prefer
async/awaitover completion handlers
Run before committing:
cd mac
swiftformat .
swiftlint- Biome: For code formatting and linting (replaces ESLint + Prettier)
- TypeScript: Strict mode enabled
Run before committing:
cd web
pnpm run precommit # Runs format + lint fixes + typecheck in one commandOr run individually if needed:
pnpm run format # Format with Biome
pnpm run lint # Check with Biome + TypeScript
pnpm run lint:fix # Auto-fix Biome issues
pnpm run typecheck # Check TypeScript types only- NEVER use
setTimeoutin frontend code unless explicitly necessary - Always fix ALL lint and type errors before committing
- Never commit without user testing the changes
- No hardcoded values - use configuration files
- No console.log in production code - use proper logging
vibetunnel/
├── mac/ # macOS application
│ ├── VibeTunnel/ # Swift source code
│ │ ├── Core/ # Business logic
│ │ ├── Presentation/ # UI components
│ │ └── Utilities/ # Helper functions
│ ├── VibeTunnelTests/ # Unit tests
│ └── scripts/ # Build and release scripts
│
├── ios/ # iOS companion app
│ └── VibeTunnel/ # Swift source code
│
├── web/ # Web server and frontend
│ ├── src/
│ │ ├── server/ # Node.js server (TypeScript)
│ │ └── client/ # Web frontend (Lit/TypeScript)
│ └── public/ # Static assets
│
└── docs/ # Documentation
We use Swift Testing framework:
# Run tests in Xcode
xcodebuild test -workspace mac/VibeTunnel.xcworkspace -scheme VibeTunnel
# Or use Xcode UI (⌘U)Test categories (tags):
.critical- Must-pass tests.networking- Network-related tests.concurrency- Async operations.security- Security features
We use Vitest for Node.js testing:
cd web
pnpm run test- Write tests for all new features
- Include both positive and negative test cases
- Mock external dependencies
- Keep tests focused and fast
-
Create a feature branch
git checkout -b feature/your-feature-name
-
Make your changes
- Follow the code style guidelines
- Write/update tests
- Update documentation if needed
-
Test your changes
- Run the test suite
- Test manually in the app
- Check both macOS and web components
-
Commit your changes
# Web changes cd web && pnpm run precommit # Swift changes cd mac && swiftformat . && swiftlint # Commit git add . git commit -m "feat: add amazing feature"
-
Push and create PR
git push origin feature/your-feature-name
Then create a pull request on GitHub.
We follow conventional commits:
feat:New featurefix:Bug fixdocs:Documentation changesstyle:Code style changes (formatting, etc)refactor:Code refactoringtest:Test changeschore:Build process or auxiliary tool changes
- Use Xcode's debugger (breakpoints, LLDB)
- Check Console.app for system logs
- Enable debug logging in Settings → Debug
- Use Chrome DevTools for frontend debugging
- Server logs appear in the terminal running
pnpm run dev - Use
--inspectflag for Node.js debugging
"Port already in use"
- Another instance might be running (e.g., production VibeTunnel app)
- Check Activity Monitor for
vibetunnelprocesses - Quick fix:
pnpm run dev:server --port 4021(no -- needed!) - Or use environment variable:
PORT=4021 pnpm run dev - See "Custom Port Configuration" section above for all options
"Binary not found"
- Run
cd web && node build-native.jsto build the Bun executable - Check that
web/native/vibetunnelexists
WebSocket connection failures
- Ensure the server is running (
pnpm run dev) - Check for CORS issues in browser console
- Verify the port matches between client and server
When adding new features:
- Update the relevant documentation in
docs/ - Add JSDoc/Swift documentation comments
- Update README.md if it's a user-facing feature
- Include examples in your documentation
- Never commit secrets or API keys
- Use Keychain for sensitive data storage
- Validate all user inputs
- Follow principle of least privilege
- Test authentication and authorization thoroughly
- Join our Discord server (if available)
- Check existing issues on GitHub
- Read the Technical Specification
- Ask questions in pull requests
All submissions require review before merging:
- Automated checks must pass (linting, tests)
- At least one maintainer approval required
- Resolve all review comments
- Keep PRs focused and reasonably sized
By contributing, you agree that your contributions will be licensed under the MIT License. See LICENSE for details.
Your contributions make VibeTunnel better for everyone. We appreciate your time and effort in improving the project! 🎉