7.1 KiB
Contributing to Homelable
Thanks for taking the time to contribute! This document covers everything you need to get started.
Table of Contents
- Ways to Contribute
- Reporting Bugs
- Suggesting Features
- Development Setup
- Project Structure
- Coding Standards
- Testing
- Submitting a Pull Request
- Commit Message Format
Ways to Contribute
- Report bugs or unexpected behavior
- Suggest new features or improvements
- Fix open issues (check the issue tracker)
- Improve documentation
- Add service signatures to
service_signatures.json
Reporting Bugs
Before opening an issue, search existing ones to avoid duplicates.
When filing a bug, include:
- Homelable version (visible in the sidebar bottom-left)
- Deployment method (Docker Compose, Proxmox LXC, source)
- Steps to reproduce
- Expected vs actual behavior
- Relevant logs (
docker compose logs backend/docker compose logs frontend) - Browser console errors if it's a UI issue
Suggesting Features
Open an issue with the enhancement label. Describe:
- The problem you're trying to solve
- Your proposed solution
- Any alternatives you considered
For large changes, discuss first before writing code — it avoids wasted effort.
Development Setup
Prerequisites
- Node.js 20+ and npm
- Python 3.11–3.13 (3.14 not yet supported by all dependencies)
- nmap installed on your system (required for scanner)
- Docker + Docker Compose (optional, for full-stack testing)
1. Clone the repo
git clone https://github.com/Pouzor/homelable.git
cd homelable
2. Backend
cd backend
python3.13 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
# Copy and configure environment
cp .env.example .env # edit AUTH_PASSWORD_HASH, SECRET_KEY, etc.
# Start the backend (auto-reloads on change)
uvicorn app.main:app --reload --port 8000
API docs available at http://localhost:8000/docs.
3. Frontend
cd frontend
npm install
npm run dev # http://localhost:5173
Vite proxies /api to localhost:8000 — the backend must be running.
4. Verify tooling
./scripts/verify-tooling.sh
Project Structure
homelable/
├── frontend/src/
│ ├── components/
│ │ ├── canvas/ # React Flow canvas, custom nodes & edges
│ │ ├── panels/ # Sidebar, detail panel, toolbar
│ │ ├── modals/ # Add/edit node, scan config, pending devices
│ │ └── ui/ # Shadcn/ui base components
│ ├── stores/ # Zustand state (canvas, auth, scan)
│ ├── hooks/ # Custom React hooks
│ ├── types/ # TypeScript interfaces & enums
│ ├── api/ # Axios client & typed endpoints
│ └── utils/ # Layout, export, color helpers
│
├── backend/app/
│ ├── api/routes/ # FastAPI route handlers
│ ├── services/ # Scanner, status checker, canvas service
│ ├── db/ # SQLAlchemy models, Alembic migrations
│ ├── schemas/ # Pydantic request/response schemas
│ └── core/ # Config, JWT, scheduler
│
├── docker/ # Nginx configs
├── scripts/ # LXC bootstrap, dev helpers
└── mcp/ # MCP server (AI integration)
Coding Standards
General
- No untested code merged — every feature or fix must include tests
- Keep changes focused — one concern per PR
Frontend (TypeScript + React)
- Strict TypeScript — no
any, no type assertions unless truly necessary - React Flow node domain fields go in
node.data, never on the node root - State management via Zustand stores — no prop drilling beyond 2 levels
- Styling via TailwindCSS utility classes — follow the existing design system
- Run before committing:
cd frontend npm run lint npm run typecheck npm test
Backend (Python + FastAPI)
- Python 3.11+ syntax
- Pydantic v2 schemas for all request/response types
- SQLAlchemy async sessions — never block the event loop
- Scanner logic runs in a background thread — never in an async route directly
- All schema changes via Alembic migrations — never modify tables directly
- Run before committing:
cd backend source .venv/bin/activate ruff check . pytest
Design System
| Token | Value |
|---|---|
| Background | #0d1117 |
| Surface | #161b22 |
| Card | #21262d |
| Accent cyan | #00d4ff |
| Online | #39d353 |
| Offline | #f85149 |
| Pending | #e3b341 |
| Font (UI) | Inter |
| Font (IPs/ports) | JetBrains Mono |
Testing
Tests run automatically via a pre-commit hook when frontend or backend files are staged.
Frontend
cd frontend
npm test # run all tests
npm run test:coverage # with coverage report
Test files live in __tests__/ next to their module, named *.test.ts(x).
What to test: Zustand store actions, utility functions, non-trivial component logic.
Backend
cd backend
source .venv/bin/activate
pytest # run all tests
pytest -v tests/test_nodes.py # single file
Test files live in backend/tests/test_*.py.
What to test: all API routes (happy path + error cases), auth flows, service logic.
Use the client and headers fixtures from conftest.py — they provide an in-memory SQLite database so tests are isolated and fast.
Submitting a Pull Request
-
Fork the repo and create a branch from
main:git checkout -b feat/my-feature -
Make your changes — include tests.
-
Run the full test suite (frontend + backend) and make sure everything passes.
-
Open a PR against
main:- Use a clear title (see commit format below)
- Describe what changed and why
- Reference any related issues (
Closes #123) - Include screenshots for UI changes
-
Keep the PR focused — one feature or fix per PR. Large refactors should be discussed in an issue first.
Commit Message Format
Follow Conventional Commits:
<type>: <short description>
[optional body]
| Type | When to use |
|---|---|
feat |
New feature |
fix |
Bug fix |
docs |
Documentation only |
refactor |
Code change with no behavior change |
test |
Adding or fixing tests |
chore |
Build, deps, tooling |
Examples:
feat: add logout button to sidebar
fix: stop click propagation on pending device checkbox
docs: add CONTRIBUTING.md
Questions?
Open a GitHub Discussion or drop a comment on a relevant issue.