Mahalli is a desktop application for inventory and invoicing. It helps you manage clients, products, quotes, orders, and invoices — across multiple workspaces.
Check out a quick video demonstration of Mahalli's features:
Mahalli is specifically designed around the B2B document chain used by Moroccan businesses. The full flow is:
- Quote / Devis — The seller generates a quote and sends it to the client for approval.
- Customer Order / Bon de commande — Once the quote is approved, it converts into a formal purchase order.
- Delivery Note / Bon de livraison — When goods are dispatched, a delivery note is issued against the order to confirm what was shipped and when.
- Invoice / Facture — The final billing document, generated after delivery. Invoices are immutable once finalized.
- Payment Tracking — Partial and full payments are recorded against invoices. Outstanding balances are computed per client.
- Credit Note / Avoir — When a finalized invoice needs a correction (returned goods, pricing errors), a credit note is issued against it rather than modifying or deleting the original.
Each document type carries the Moroccan legal identity fields required on printed paperwork: ICE, IF (identifiant fiscal), RC (registre de commerce), and Patente / TP, for both clients and the seller's own profile.
Mahalli provides comprehensive tools to manage each step of this process efficiently.
Mahalli uses a two-layer SQLite database architecture:
A permanent catalog database that runs at all times. It tracks all registered tenant databases — their names, slugs, file paths, and which one is currently active.
Each tenant database is an independent SQLite file that holds all business data (clients, products, orders, quotes, invoices, inventory) for a given workspace. The active tenant connection is hot-swappable at runtime — users can create new workspaces, clone existing ones, and switch between them without restarting the app.
src-tauri/
├── src/ # Main Tauri app
│ ├── commands/ # Tauri commands exposed to the frontend
│ │ └── databases.rs # create, switch, list databases
│ ├── db/ # DB manager, path resolution, system setup
│ └── jobs/ # Background jobs (image optimizer)
└── crates/
├── system-entity/ # SeaORM entities for the system/catalog DB
├── system-migration/ # Migrations for the system DB
├── system-service/ # Queries/mutations for the system DB
├── tenant-entity/ # SeaORM entities for tenant databases
├── tenant-migration/ # Migrations for tenant databases
└── tenant-service/ # Queries/mutations for tenant databases
Before you begin, ensure you have Bun and the Tauri prerequisites installed. For SeaORM entity and migration generation, install the matching v2 CLI:
cargo install sea-orm-cli@^2.0.0-rc.34- Clone the repository and navigate to the project root.
- Install frontend dependencies:
bun install- Start the development server:
bun run tauri devbun run tauri build| Command | Description |
|---|---|
make dev |
Start the development server |
make build |
Build a debug desktop executable |
make check |
Run cargo check on the Rust code |
make lint |
Format Rust code and lint frontend code |
| Command | Description |
|---|---|
make tenant-migrationsup |
Run all pending tenant migrations |
make tenant-migrationslast |
Revert the last tenant migration |
make tenant-migrationsdown |
Drop and reset the tenant database |
make tenant-entity |
Regenerate SeaORM entities from the tenant DB |
make migration name=<name> |
Generate a new tenant migration file |
Shorthands make migrationsup, make migrationslast, make migrationsdown, and make entity all target the tenant database.
| Command | Description |
|---|---|
make system-migrationsup |
Run all pending system migrations |
make system-migrationslast |
Revert the last system migration |
make system-migrationsdown |
Drop and reset the system database |
make system-entity |
Regenerate SeaORM entities from the system DB |
make system-migration name=<name> |
Generate a new system migration file |
make update-v v=1.2.3