Thank you for your interest in contributing to dbfordevs! We welcome contributions from the community to help make this database management tool even better.
- Code of Conduct
- Ways to Contribute
- Getting Started
- Development Workflow
- Coding Standards
- Commit Conventions
- Pull Request Process
- Testing
- Architecture Patterns
- Getting Help
This project adheres to a code of conduct that all contributors are expected to follow. Please be respectful and constructive in all interactions.
There are many ways to contribute to dbfordevs:
- Report bugs: Open an issue describing the bug, steps to reproduce, and your environment
- Suggest features: Propose new features or enhancements via GitHub issues
- Write documentation: Improve existing docs or add new guides
- Fix bugs: Pick up issues labeled
bugorgood first issue - Add features: Implement new functionality (discuss in an issue first for larger features)
- Improve tests: Add test coverage or improve existing tests
- Code review: Review open pull requests and provide constructive feedback
Before you begin, ensure you have the following installed:
- Rust: Install via rustup
- Bun: Install via bun.sh
- Tauri Dependencies: Follow the Tauri setup guide for your OS
- Git: For version control
- Fork the repository on GitHub
- Clone your fork locally:
git clone https://github.com/YOUR-USERNAME/dbfordevs.git cd dbfordevs - Add the upstream repository:
git remote add upstream https://github.com/danielss-dev/dbfordevs.git
bun installbun tauri devThis will start both the Vite frontend dev server and the Tauri application.
For UI-only changes without the Tauri backend:
bun devThis project uses Graphite for managing stacked pull requests. See docs/GRAPHITE.md for detailed instructions.
Quick start:
# Install Graphite CLI
bun install -g @withgraphite/graphite-cli
# Authenticate
gt auth
# Initialize in the repo
gt init
# Create a new branch
gt create my-feature-branch
# Make changes and commit
git add .
git commit -m "feat: add new feature"
# Submit PR
gt submitIf you prefer not to use Graphite:
- Create a new branch from
master:git checkout -b feature/my-feature
- Make your changes
- Commit using conventional commits
- Push to your fork:
git push origin feature/my-feature
- Open a pull request on GitHub
- Use TypeScript with strict mode enabled
- Follow existing component patterns in
src/components/ - Use Tailwind CSS for styling
- Use shadcn/ui and Radix UI primitives for UI components
- Prefer functional components with hooks
- Use Zustand for state management (see Architecture Patterns)
- Follow Rust's official style guide (
cargo fmt) - Run
cargo clippyand fix all warnings before submitting - Write async code using
tokio - Use
sqlxfor database operations - Follow the Tauri command pattern (see Architecture Patterns)
- Keep PRs focused and small
- Write clear, self-documenting code
- Add comments only where logic is not obvious
- Update documentation when changing behavior
- Ensure code builds without warnings
We "follow" Conventional Commits for all commit messages:
<type>(<scope>): <description>
[optional body]
[optional footer]
feat: A new featurefix: A bug fixdocs: Documentation changesstyle: Code style changes (formatting, missing semicolons, etc.)refactor: Code refactoring without changing behaviorperf: Performance improvementstest: Adding or updating testschore: Maintenance tasks (dependency updates, build config, etc.)ci: CI/CD changes
feat(ai): add support for Gemini AI provider
fix(connections): resolve SQLite connection timeout issue
docs(readme): update installation instructions
refactor(stores): simplify query store logicIf you want, you can use an AI tool to create the commit message.
-
Before Opening a PR:
- Ensure your code builds:
bun run buildandcargo build - Run type checks:
tsc --noEmit - Test manually in development mode
- Update documentation if needed
- Add tests for new features
- Ensure your code builds:
-
Opening a PR:
- Use a clear, descriptive title following conventional commit format
- Fill out the PR description template (if available)
- Link related issues using
Closes #123orFixes #456 - Add screenshots/videos for UI changes
- Mark as draft if work is in progress
-
PR Review:
- Address reviewer feedback promptly
- Keep discussions focused and constructive
- Request re-review after making changes
- Use
git commit --amendor fixup commits, then squash before merge
-
Merging:
- PRs require approval from maintainers
- Ensure CI checks pass
- Use "Squash and merge" for clean history
- Delete branch after merging
Frontend tests use Vitest with 86+ test cases covering utilities, connection parsing, export functions, and query history.
bun test # Run tests in watch mode
bun test:run # Run tests once
bun test:coverage # Run with coverage- Manual testing in
bun tauri devis required for all UI changes - Test across different themes (Light, Dark, Nordic, Solarized)
- Contributions to improve test coverage are welcome
Rust tests include unit tests and integration tests using testcontainers:
cd src-tauri
cargo test --lib # Unit tests only
cargo test --test sqlite_integration # SQLite (no Docker needed)
cargo test # All tests (Docker required for PG/MySQL)- Test database operations with PostgreSQL, MySQL, and SQLite
- Ensure error handling works correctly
- Verify connection pooling behavior
For significant changes, test:
- Fresh install works (
bun install+bun tauri dev) - Production build works (
bun tauri build) - Database connections (PostgreSQL, MySQL, SQLite, MSSQL, Oracle, MongoDB, Redis, Cassandra)
- AI assistant functionality (if applicable)
- Theme switching
- Data editing and diff preview
Familiarize yourself with these key patterns before contributing:
-
Define handler in
src-tauri/src/commands/*.rs:#[tauri::command] pub async fn my_command(arg: String) -> Result<String, String> { // Implementation Ok(result) }
-
Register in
src-tauri/src/lib.rs:tauri::generate_handler![ // ... other commands my_command ]
-
Create TypeScript wrapper in
src/hooks/useDatabase.ts:const myCommand = async (arg: string) => { return await invoke<string>('my_command', { arg }); };
-
Create store in
src/stores/:export const useMyStore = create<MyState>()( persist( (set) => ({ // state and actions }), { name: 'my-store', partialize: (state) => ({ /* selective persistence */ }), } ) );
-
Export from
src/stores/index.ts
- Implement database operations in
src-tauri/src/db/<driver>.rs - Each driver implements the same interface
- Connection pools are managed in
src-tauri/src/db/manager.rs
For more details, see CLAUDE.md.
- Questions: Open a GitHub Discussion
- Bugs: Open a GitHub Issue
- Documentation: Check docs/ folder for guides
- Graphite Workflow: See docs/GRAPHITE.md
When releasing a new version, use the built-in script:
bun scripts/bump-version.tsThis updates package.json, Cargo.toml, and tauri.conf.json automatically.
By contributing to dbfordevs, you agree that your contributions will be licensed under the MIT License.
Thank you for contributing to dbfordevs! Your efforts help make database management better for developers everywhere.