Thank you for your interest in contributing! This guide contains everything you need to get started.
- Docker 20.10+
- Docker Compose
- Make
- Google Chrome or Chromium
# Clone the repository
git clone https://github.com/vinimlo/tabAla.git
cd tabAla
# Start the development environment
make devAll commands are executed via Docker through the Makefile:
| Command | Description |
|---|---|
make help |
List all available commands |
make dev |
Start development server (interactive mode) |
make dev-detached |
Start development server (background) |
make build |
Build the extension for production |
make test |
Run test suite with Vitest |
make test-watch |
Run tests in watch mode |
make test-ui |
Open Vitest visual interface |
make test-coverage |
Generate test coverage report |
make lint |
Run ESLint for code validation |
make lint-fix |
Run ESLint with auto-fix |
make shell |
Open interactive shell in the container |
make lockfile |
Regenerate package-lock.json |
make clean |
Remove build artifacts (dist/) |
make stop |
Stop all running containers |
Note: Do not run npm commands directly. Always use make commands to ensure environment consistency.
- Run
make build - Go to
chrome://extensions - Enable "Developer mode" in the top right corner
- Click "Load unpacked"
- Select the
dist/folder
To reload after changes: click the reload icon (🔄) on the extension card.
| Technology | Usage |
|---|---|
| Svelte | Lightweight reactive UI |
| TypeScript | Static typing |
| Vite | Fast builds |
| Vitest | Unit testing |
| Docker | Development environment |
| Chrome Extension Manifest V3 | Platform |
tabAla/
├── src/
│ ├── popup/ # Popup UI (Svelte)
│ │ ├── App.svelte
│ │ ├── components/
│ │ └── stores/
│ ├── background/ # Service worker
│ │ └── index.ts
│ ├── lib/ # Shared logic
│ │ ├── storage.ts # chrome.storage wrapper
│ │ └── types.ts # TypeScript types
│ └── manifest.json # Manifest V3
├── public/ # Static assets (icons)
├── tests/ # Unit tests
├── docs/ # Documentation
│ └── mvp.md
├── dist/ # Build output (gitignore)
├── Dockerfile # Development image
├── docker-compose.yml # Container orchestration
└── Makefile # Automation commands
- Popup: Svelte interface rendered when clicking the extension icon
- Service Worker: Background script for commands and shortcuts
- Storage Layer: Abstraction over chrome.storage.local
[User] → [Popup/Shortcut] → [Storage Layer] → [chrome.storage.local]
↓
[State Store (Svelte)]
↓
[Updated UI]
interface Link {
id: string;
url: string;
title: string;
favicon?: string;
collectionId: string;
createdAt: number;
}
interface Collection {
id: string;
name: string;
order: number;
}- Inbox: Default collection that always exists and cannot be deleted
- Orphan links: Links from deleted collections are moved to Inbox
- Uniqueness: The same URL can exist in multiple collections
- Sorting: Links sorted by date (most recent first)
- Svelte components: PascalCase (
LinkItem.svelte) - Functions/variables: camelCase
- Constants: UPPER_SNAKE_CASE
- Types/Interfaces: PascalCase
- Prefer
constoverlet - Use async/await (never callbacks for storage)
- Do not use synchronous chrome.storage APIs (deprecated)
- Do not store sensitive data (passwords, tokens)
- Do not use Manifest V2 — always V3
- Avoid large bundles — keep the extension lightweight (<500KB)
- Do not block UI during storage operations
- Never hardcode credentials or API keys
# Run all tests
make test
# Run in watch mode (rerun on save)
make test-watch
# Open Vitest visual interface
make test-ui
# Generate coverage report
make test-coverage- Check if port 5173 is in use:
lsof -i :5173 - Confirm Docker is running:
docker info
- Make sure the volume is mounted correctly
- On macOS/Windows, enable file sharing for the project directory
- Check the logs:
docker-compose logs -f
- The container runs as user
node(uid 1000) - If needed, adjust permissions:
chmod -R 755 .
- Verify that
make buildran without errors - Confirm the
dist/folder exists and containsmanifest.json - Try removing the extension and loading it again
- Run
make buildto generate the new bundle - In
chrome://extensions, click the reload icon (🔄) on the extension - If it persists, remove the extension and load it again
- Fork the project
- Create a branch (
git checkout -b feature/new-feature) - Make your changes
- Run the tests (
make test) - Validate the code (
make lint) - Commit your changes (
git commit -m 'Add new feature') - Push to the branch (
git push origin feature/new-feature) - Open a Pull Request
- Chrome Extensions Docs
- Svelte Docs
- docs/mvp.md — Full MVP specification