Thank you for your interest in KeyboardWriter! We welcome all contributions.
- Code of Conduct
- How Can I Contribute?
- Development Setup
- Code Style
- Commit Messages
- Pull Request Process
This project follows the Contributor Covenant. Please read our Code of Conduct before contributing.
TL;DR: Be kind, respectful, and constructive.
Found a bug? Great! Here's how to report it:
- Check first if the bug already exists as an issue
- If not, create a new issue
- Include the following information:
- Description of the bug
- Steps to reproduce
- Expected vs. actual behavior
- Browser & OS
- Screenshots (if helpful)
Have an idea for a new feature?
- Create an issue with the
enhancementlabel - Describe the feature and its benefits
Want to contribute code? Fantastic!
Good First Issues: Look for issues with the good first issue label
- Node.js 18+
- npm 9+
- Git
# 1. Fork the repository on GitHub
# 2. Clone your fork
git clone https://github.com/YOUR-USERNAME/keyboardwriter.git
cd keyboardwriter
# 3. Add the original repo as upstream
git remote add upstream https://github.com/yourusername/keyboardwriter.git
# 4. Install dependencies
npm install
# 5. Start the dev server
npm run dev| Script | Description |
|---|---|
npm run dev |
Start Vite dev server |
npm run build |
Create production build |
npm run preview |
Preview the build |
npm run lint |
ESLint check |
npm run lint:fix |
ESLint auto-fix |
npm run format |
Prettier formatting |
npm run type-check |
TypeScript check |
npm run test |
Unit tests |
We use ESLint and Prettier for consistent code style.
// Good: Explicit types for public APIs
function calculateWPM(chars: number, timeMs: number): number {
return Math.round((chars / 5) / (timeMs / 60000));
}
// Good: Interface for complex objects
interface Challenge {
id: string;
title: string;
difficulty: 'easy' | 'medium' | 'hard';
}
// Avoid: any
function process(data: any) { ... }
// Better: Generics or concrete types
function process<T>(data: T): T { ... }src/
+-- components/ # Reusable UI components
+-- core/ # Core modules (Store, EventBus, etc.)
+-- data/ # Static data (Lessons, Exercises)
+-- domain/ # Domain Models & Enums
+-- pages/ # Page components
+-- services/ # Business logic services
+-- styles/ # CSS modules
| Type | Convention | Example |
|---|---|---|
| Files (Classes) | PascalCase | VirtualKeyboard.ts |
| Files (Utils) | camelCase | helpers.ts |
| Classes | PascalCase | class TypingEngine |
| Functions | camelCase | function calculateWPM() |
| Constants | UPPER_SNAKE | const MAX_WPM = 300 |
| Interfaces | PascalCase (no I-prefix) | interface Challenge |
We follow Conventional Commits:
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
| Type | Description |
|---|---|
feat |
New feature |
fix |
Bug fix |
docs |
Documentation |
style |
Formatting (no code change) |
refactor |
Code refactoring |
perf |
Performance improvement |
test |
Add/modify tests |
chore |
Build, dependencies, etc. |
# Feature
feat(playground): add Python matrix transpose challenge
# Bug Fix
fix(keyboard): correct finger highlighting for special chars
# Documentation
docs: update README with new screenshots
# Refactoring
refactor(store): simplify state management logic# Get the latest changes
git fetch upstream
git checkout main
git merge upstream/main
# Create a feature branch
git checkout -b feat/amazing-feature- Write code
- Add tests (if possible)
- Make sure all tests pass:
npm run test - Check types:
npm run type-check - Check linting:
npm run lint
git add .
git commit -m "feat(scope): add amazing feature"git push origin feat/amazing-featureThen on GitHub: "Compare & pull request"
- Code follows the style guide
- All tests pass
- Type-check has no errors
- Lint-check has no errors
- PR description explains the changes
- Screenshots added (for UI changes)
- At least one maintainer reviews the PR
- Feedback is discussed
- Changes are made (if necessary)
- PR is merged!
All contributors are mentioned in the README and receive a virtual achievement:
"Open Source Hero"
Your first merged Pull Request!
- Create an Issue
- Or start a Discussion
Thank you for your contribution!