Skip to main content

Contributing

Thank you for your interest in contributing to Elftia. This document describes the complete workflow for participating in development.


Setting Up Your Development Environment

See the Local Development guide for detailed steps. Quick summary:

{/* Prerequisites */}
{/* Node.js v24 (see .nvmrc) + native build tools */}

git clone <repo-url> elftia
cd elftia
npm install
cp .env.example .env
npm run dev

Branch Strategy

BranchPurposeProtection Rules
mainStable release, always shippableRequires PR + Review
dev/*Feature development branches-
fix/*Bug fix branches-

Branch Naming

{/* New feature */}
git checkout -b dev/feature-name

{/* Bug fix */}
git checkout -b fix/bug-description

{/* Examples */}
git checkout -b dev/notes-feature
git checkout -b fix/chat-scroll-issue

Code Standards

See Code Standards for the full specification. Key points:

ESLint

  • error-level rules block commits (import ordering, no-var, eqeqeq, prefer-const, Hook rules)
  • warn-level rules allow commits but are recommended to fix
  • Husky runs eslint --fix automatically before commits

File Size

File TypeRecommended LimitHard Limit
React components400 lines800 lines
Custom Hooks300 lines600 lines
Utility functions150 lines300 lines
Type definitions100 lines200 lines
Services300 lines600 lines

Naming

  • Components: PascalCase (UserMessage.tsx)
  • Hooks: usePascalCase (useChatActions.ts)
  • Directories: kebab-case (chat-messages/)
  • Semantic tokens (no hardcoded colors)

Commit Convention

Use Conventional Commits format:

<type>: <description>

[optional body]

[optional footer]

Type Reference

TypeDescriptionExample
featNew featurefeat: add notes export feature
fixBug fixfix: resolve chat scroll position reset
refactorRefactorrefactor: split ChatInterface into smaller components
docsDocumentationdocs: update IPC channels reference
styleCode formatting (no logic changes)style: fix import ordering
testTeststest: add unit tests for useFavorites
choreBuild/tooling changeschore: update Vite to v7.1

Example

git commit -m "feat: add favorites feature with session-scoped bookmarks

- Add FavoritesService with SQLite persistence
- Add FavoritesRouter with Zod validation
- Add useFavorites hook and FavoritesList component
- Add i18n support for en/zh/ja"

Pull Request Requirements

Core Principles

  • One PR does one thing — do not mix feature development with bug fixes
  • Tests — new features include tests
  • Docs — update documentation when necessary
  • CI Pass — all checks pass

PR Title

Concisely describe the change using Conventional Commits format:

feat: add favorites feature
fix: resolve chat message duplication
refactor: extract message rendering into separate components

PR Description Template

## Changes
- Brief description of change 1
- Brief description of change 2

## How to Test
- [ ] Manual test step 1
- [ ] Manual test step 2
- [ ] Unit tests pass

## Screenshots (if UI changes)

New Feature Development Checklist

See Adding a Feature for the complete end-to-end flow.

Backend

StepFile LocationDescription
1. Shared typespackages/desktop/app/shared/contracts/Type definitions shared between frontend and backend
2. Servicepackages/desktop/app/main/services/Business logic encapsulation
3. Routerpackages/desktop/app/main/services/routers/IPC routing + Zod validation
4. Registrationrouters/index.tsregisterAllRouters()Create instance and register
5. Preloadpackages/desktop/app/preload/index.tsExpose to frontend

Frontend

StepFile LocationDescription
1. Hookpackages/renderer/src/features/<feature>/hooks/ (cross-feature hooks go in shared/hooks/)Data fetching and state management
2. Componentpackages/renderer/src/features/<feature>/components/ (shared UI in components/ui/)UI rendering
3. Routeapp/lazy/ (pages.tsx etc.) + app/App.tsxNew pages require lazy-load registration (legacy import path from '../lazy' via lazy/index.ts barrel is still compatible)
4. i18npackages/renderer/src/locales/{en,zh,ja}/Three-language translations

Documentation

ConditionNeeds Update
New module added.claude/skills/architecture-index/SKILL.md
User-visible featuredocs/elfi-kb/ knowledge base
New route addeddocs/elfi-kb/INDEX.md mapping table

Code Review Focus Areas

Frontend/Backend Separation

  • Does the frontend only pass user input and configuration parameters?
  • Does the backend handle all external calls?
  • Is the returned data in its final form?
  • Is transmission of large data like base64 over IPC avoided?

Security

  • Are Router parameters validated with Zod?
  • Are API keys used only in the main process?
  • Are there potential XSS risks?

File Size

  • Is the new file within the recommended limit?
  • Does the modified file exceed the warning threshold?
  • Does it need to be split?

Error Handling

  • Do network requests have try-catch?
  • Are error messages user-friendly?
  • Are there appropriate loading and empty states?

Documentation

  • Has the architecture index been updated?
  • Has the knowledge base been updated?
  • Are all three i18n languages in sync?

Bug Reports

Report Template

## Environment
- OS: Windows 11 / macOS 15 / Ubuntu 24
- Elftia version: v0.5.0
- Node.js version: v24.x

## Steps to Reproduce
1. Open the settings page
2. Switch to the "Appearance" tab
3. Click on wallpaper settings
4. After selecting an image...

## Expected Behavior
The wallpaper should display normally.

## Actual Behavior
The wallpaper does not display; console error: TypeError: Cannot read property 'path' of undefined

## Additional Information
- Diagnostic data export (Settings → Advanced → Export Diagnostic Data)
- Screenshots or screen recordings
- Console error logs

Exporting Diagnostic Data

Export diagnostic data from within the app to help troubleshoot issues:

Settings → Advanced → Diagnostic Tools → Export Diagnostic Data

Or via the DevTools Console:

const data = await window.api.diagnostics.bundle({ includeLogs: true });

Contact

  • Project Issues — feature requests and bug reports
  • Pull Requests — code contributions
  • Discussions — technical discussion and questions