Thank you for your interest in contributing to VPNht Desktop! This document provides guidelines and instructions for contributing.
- Code of Conduct
- Getting Started
- Development Workflow
- Coding Standards
- Testing
- Security
- Pull Request Process
This project adheres to a standard code of conduct. By participating, you are expected to:
- Be respectful and inclusive
- Accept constructive criticism
- Focus on what is best for the community
- Show empathy towards others
- Node.js 18+ (LTS recommended)
- Rust 1.70+
- npm or pnpm
- Git
-
Fork the repository
-
Clone your fork:
git clone https://github.com/YOUR_USERNAME/desktop.git cd desktop -
Install dependencies:
npm install
-
Install Tauri CLI:
cargo install tauri-cli
-
Run the development server:
npm run tauri:dev
Use conventional branch names:
feat/description- New featuresfix/description- Bug fixesdocs/description- Documentation updatesrefactor/description- Code refactoringtest/description- Test improvementschore/description- Maintenance tasks
Follow Conventional Commits:
<type>(<scope>): <subject>
<body>
<footer>
Types:
feat- New featurefix- Bug fixdocs- Documentation onlystyle- Code style (formatting, semicolons)refactor- Code refactoringtest- Testschore- Build/dependency changes
Examples:
feat(servers): add latency sorting
Implement latency-based sorting for server list
with automatic refresh every 30 seconds.
Closes #123
- Use TypeScript for all new code
- Enable strict mode
- Use explicit return types for functions
- Prefer
interfaceovertypefor objects - Use optional chaining (
?.) appropriately
// Good
interface ServerConfig {
id: string;
hostname: string;
port?: number;
}
async function connectToServer(config: ServerConfig): Promise<Connection> {
// ...
}
// Avoid
function connectToServer(config) {
// ...
}- Use functional components with hooks
- Use
React.FCsparingly, prefer explicit props - Keep components under 250 lines
- Split logic into custom hooks
- Use
useCallbackfor memoized callbacks
// Good
interface ServerCardProps {
server: Server;
onConnect: (id: string) => void;
}
export function ServerCard({ server, onConnect }: ServerCardProps): JSX.Element {
const handleClick = useCallback(() => {
onConnect(server.id);
}, [server.id, onConnect]);
return (
<button onClick={handleClick}>{server.name}</button>
);
}- Follow Rust naming conventions
- Document all public APIs with
/// - Use
Resultfor fallible operations - Prefer
?over.unwrap() - Write tests for all public functions
/// Connects to a VPN server with the given configuration.
///
/// # Errors
///
/// Returns an error if the connection fails or times out.
pub async fn connect(config: ServerConfig) -> Result<Connection, VpnError> {
let socket = create_socket().await?;
// ...
}# Run all tests
npm test
# Run with coverage
npm run test:coverage
# Watch mode
npm run test:watch# In src-tauri directory
cd src-tauri
# Run all tests
cargo test
# Run with output
cargo test -- --nocapture
# Check coverage
cargo tarpaulin --out Xml- Unit tests for all utility functions
- Component tests for React components
- Integration tests for IPC commands
- E2E tests for critical user flows
Before submitting a PR:
- No hardcoded secrets or credentials
- Input validation implemented
- No SQL injection vulnerabilities
- No XSS vulnerabilities
- Error messages don't leak sensitive data
- Principle of least privilege followed
Please report security vulnerabilities to security@vpnht.com with:
- Description of the vulnerability
- Steps to reproduce
- Potential impact
- Suggested fix (if any)
Do not disclose security issues publicly until patched.
-
Create a branch from
main:git checkout -b feat/my-feature
-
Make your changes following coding standards
-
Run tests and ensure they pass:
npm test cd src-tauri && cargo test
-
Run linting:
npm run lint cd src-tauri && cargo clippy
-
Update documentation if needed
-
Commit with conventional message format
-
Push to your fork:
git push origin feat/my-feature
-
Create Pull Request using the template
-
Code review - Address reviewer feedback
-
Merge - Maintainers will merge after approval
- Tests added/updated
- Documentation updated
- Changelog updated
- Security review passed
- No merge conflicts
- CI checks passing
When adding UI text:
- Add translation keys to
src/i18n/locales/en.json - Use
useTranslationhook in components - Test in RTL languages (Arabic, Hebrew)
import { useTranslation } from 'react-i18next';
function MyComponent() {
const { t } = useTranslation();
return <button>{t('common.connect')}</button>;
}Ensure all components:
- Have proper ARIA attributes
- Support keyboard navigation
- Work with screen readers
- Meet WCAG 2.1 AA standards
- Check Documentation
- Open a Discussion
- Join our Discord
By contributing, you agree that your contributions will be licensed under the same license as the project.