We want to make Git visual for everyone. Join us in building the most intuitive Git client.
Thank you for your interest in contributing to Dragit! This document outlines our standards, processes, and expectations. Please read it carefully before submitting any code.
- Code of Conduct
- Security & Integrity
- Before You Start
- Development Standards
- Pull Request Process
- Reporting Issues
We are committed to providing a welcoming and inclusive environment. All contributors are expected to:
- Be respectful and constructive in all communications
- Welcome newcomers and help them get started
- Focus on what's best for the community and the project
- Accept constructive criticism gracefully
All commits MUST be signed using GPG or SSH. Unsigned commits will be rejected.
This requirement ensures:
- Authenticity: We can verify who wrote the code
- Integrity: Commits cannot be tampered with
- Trust: Users can trust the provenance of our codebase
How to set up commit signing:
# Configure Git to sign all commits
git config --global commit.gpgsign true
git config --global user.signingkey YOUR_KEY_IDAlternatively, use SSH signing:
If you discover a security vulnerability, do NOT open a public issue. Instead, email us directly at [feedback@kheiflabs.com] with details. We will respond within 48 hours.
This is mandatory. Before writing any code, you must understand our architecture:
Dragit follows a Process-Driven Vertical Slice Architecture. Key concepts:
- Process Isolation: Main (Node.js) and Renderer (React) are strictly separated
- Vertical Slices: Code is organized by features, not technical layers
- Type-Safe IPC: All communication uses shared contracts—no magic strings
- Explicit Wiring: Manual dependency injection in
startup.ts
# Fork and clone the repository
git clone https://github.com/YOUR_USERNAME/dragit.git
cd dragit
# Install dependencies
npm install
# Start development mode
npm run devsrc/
├── shared/ # Contracts & Types (Single Source of Truth)
│ └── features/ # One contract per feature
├── main/ # Backend (Node.js)
│ └── features/ # Services + Handlers
├── preload/ # Secure Bridge
└── renderer/src/ # Frontend (React)
└── features/ # UI Components + Hooks
All code must follow the vertical slice architecture:
| New Code Location | What Belongs There |
|---|---|
shared/features/{name}/ |
Contracts, types, channel constants |
main/features/{name}/ |
Service (logic), Handler (IPC), Index (factory) |
renderer/src/features/{name}/ |
Components, hooks, styles |
❌ Never:
- Import from
main/inrenderer/(or vice versa) - Add IPC handlers outside of a Handler class
- Use magic strings for IPC channels
- Bypass the
startup.tsregistration
These conventions are strictly enforced:
| Item | Convention | Example |
|---|---|---|
| Feature Folders | kebab-case |
git-history/, file-staging/ |
| Contract Files | *.contract.ts |
git.contract.ts |
| Service Classes | PascalCase + Service | GitService, FileSystemService |
| Handler Classes | PascalCase + Handler | GitHandler, FileSystemHandler |
| React Hooks | camelCase with use prefix |
useGitLogs, useFolderOpen |
| IPC Channels | namespace:action |
git:getCommits, fs:openDialog |
| Component Files | PascalCase | GitLogList.tsx, WelcomeScreen.tsx |
No
anytypes allowed.
- All IPC communication must go through
shared/contracts - Use
unknowninstead ofanywhen type is truly unknown, then narrow it - Enable strict TypeScript settings (already configured)
// ❌ Bad
const data: any = await window.api.getCommits();
// ✅ Good
import type { GetCommitsResult } from '@shared/features/git/git.contract';
const data: GetCommitsResult = await window.api.getCommits(request);We are establishing testing patterns. For now:
- Services should be written as pure classes (no Electron dependencies)
- Handlers should be thin wrappers around services
- This separation enables easy unit testing
We use Prettier and ESLint. Before committing:
npm run format # Auto-format code
npm run lint # Check for issues
npm run typecheck # Verify typesUse descriptive branch names with prefixes:
| Prefix | Use Case | Example |
|---|---|---|
feat/ |
New features | feat/branch-visualization |
fix/ |
Bug fixes | fix/commit-list-scroll |
docs/ |
Documentation | docs/update-readme |
refactor/ |
Code refactoring | refactor/git-service |
chore/ |
Maintenance tasks | chore/update-deps |
Follow Conventional Commits:
<type>(<scope>): <description>
[optional body]
[optional footer]
Examples:
feat(git): add commit graph visualization
fix(fs): handle spaces in folder paths
docs(arch): update feature creation guide
When opening a PR, include:
- What: Brief description of changes
- Why: The problem being solved or feature being added
- How: High-level approach taken
- Testing: How you verified the changes work
- Screenshots: For UI changes
- All PRs require at least one approving review
- CI checks must pass (lint, typecheck, build)
- All commits must be signed
- Squash merge is preferred for clean history
Since Dragit is licensed under Apache License 2.0:
- If you add significant third-party code, update the
NOTICEfile - Ensure any dependencies are compatible with Apache 2.0
- Include proper attribution for external code
When reporting bugs, include:
- Environment: OS, Node.js version, Electron version
- Steps to Reproduce: Detailed steps to trigger the bug
- Expected Behavior: What should happen
- Actual Behavior: What actually happens
- Screenshots/Logs: If applicable
For feature requests:
- Problem: What problem does this solve?
- Solution: Your proposed solution
- Alternatives: Other solutions you considered
- Mockups: For UI features, rough sketches help
- 📖 Architecture Guide — Understand the codebase
- 💬 Discussions — Ask questions and share ideas
- 🐛 Issues — Report bugs or request features
Contributors will be recognized in:
- The project's contributor list
- Release notes for significant contributions
- Special mentions for exceptional contributions
Thank you for helping make DragIt for everyone! 🚀