16bit / easy-multitenancy
Drop-in plugin to enable multitenancy based on SQLite dbs
Fund package maintenance!
16bit
Installs: 2
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 1
pkg:composer/16bit/easy-multitenancy
Requires
- php: ^8.2
- illuminate/console: ^11.0||^12.0
- illuminate/contracts: ^11.0||^12.0
- illuminate/database: ^11.0||^12.0
- illuminate/routing: ^11.0||^12.0
- illuminate/support: ^11.0||^12.0
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pint: ^1.14
- nunomaduro/collision: ^8.8
- orchestra/testbench: ^10.0.0||^9.0.0
- pestphp/pest: ^4.0
- pestphp/pest-plugin-arch: ^4.0
- pestphp/pest-plugin-laravel: ^4.0
- phpstan/extension-installer: ^1.4
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-phpunit: ^2.0
- spatie/laravel-ray: ^1.35
This package is auto-updated.
Last update: 2025-11-24 12:52:20 UTC
README
A simple, drop-in Laravel package for database-per-tenant multitenancy using SQLite. Perfect for SaaS applications where each tenant gets their own isolated SQLite database with automatic URL-based tenant identification and seamless database switching.
Installation
You can install the package via composer:
composer require 16bit/easy-multitenancy
Publish the config file:
php artisan vendor:publish --tag="easy-multitenancy-config"
This is the contents of the published config file:
return [ 'database' => [ 'path' => env('TENANT_DB_PATH', database_path('tenants')), 'connection' => env('TENANT_DB_CONNECTION', 'tenant'), 'extension' => '.sqlite', ], 'cache' => [ 'prefix_enabled' => env('TENANT_CACHE_PREFIX', true), ], 'session' => [ 'prefix_enabled' => env('TENANT_SESSION_PREFIX', true), ], 'storage' => [ 'prefix_enabled' => env('TENANT_STORAGE_PREFIX', true), 'path' => env('TENANT_STORAGE_PATH', 'tenants'), ], 'queue' => [ 'tenant_aware' => env('TENANT_QUEUE_AWARE', true), ], 'routes' => [ 'parameter' => 'tenant', 'middleware' => ['web'], 'auto_prefix' => env('TENANT_AUTO_PREFIX_ROUTES', true), 'excluded_routes' => [ 'home', ], 'excluded_patterns' => [ 'up', 'horizon*', 'telescope*', 'api/*', '_debugbar/*', '*.js', '*.css', '*.map', ], ], ];
Features
- Database-per-tenant architecture using SQLite
- Automatic route prefixing with tenant identification
- Seamless database switching based on URL
- Tenant-isolated storage, cache, and sessions
- Queue job tenant awareness with the
TenantAwaretrait - Artisan commands for tenant management
- Events for tenant lifecycle hooks
- Custom URL generator for tenant-aware routing
Usage
Creating a Tenant
# Interactive creation with prompts php artisan tenant:create # Create with specific name php artisan tenant:create acme # Create without user php artisan tenant:create acme --no-user
Listing Tenants
php artisan tenant:list
Running Migrations
# Migrate specific tenant php artisan tenant:migrate acme # Migrate with fresh (drop all tables) php artisan tenant:migrate acme --fresh # Migrate and seed php artisan tenant:migrate acme --seed # Migrate all tenants php artisan tenant:migrate-all
Seeding Databases
# Seed specific tenant php artisan tenant:seed acme # Seed with specific seeder class php artisan tenant:seed acme --class=DatabaseSeeder # Seed all tenants php artisan tenant:seed-all
Accessing Tenants in Code
The package automatically identifies tenants from the URL and switches the database context. All routes are automatically prefixed with {tenant} parameter.
use Bit16\EasyMultitenancy\Facades\Tenant; // Get current tenant $currentTenant = Tenant::current(); // Returns tenant identifier (e.g., 'acme') // Get current tenant ID (alias for current()) $tenantId = Tenant::id(); // Get current database path $database = Tenant::database(); // Check if tenant exists if (Tenant::exists('acme')) { // Tenant exists } // Get all tenants $tenants = Tenant::all(); // Manually switch tenant (rarely needed) Tenant::identify('acme'); // Forget current tenant context Tenant::forget();
Tenant-Aware Queue Jobs
Add the TenantAware trait to your jobs to ensure they run in the correct tenant context:
use Bit16\EasyMultitenancy\Traits\TenantAware; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; class ProcessOrder implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, TenantAware; public function handle() { // Job automatically runs in the correct tenant context } }
Events
The package dispatches several events you can listen to:
use Bit16\EasyMultitenancy\Events\TenantIdentified; use Bit16\EasyMultitenancy\Events\TenantNotFound; use Bit16\EasyMultitenancy\Events\DatabaseSwitched; // Listen to tenant identified event Event::listen(TenantIdentified::class, function ($event) { // $event->tenant // $event->database }); // Listen to database switched event Event::listen(DatabaseSwitched::class, function ($event) { // $event->tenant // $event->database // $event->connection }); // Listen to tenant not found event Event::listen(TenantNotFound::class, function ($event) { // $event->tenant });
Route Configuration
By default, all routes are automatically prefixed with the tenant parameter. You can exclude specific routes:
// In config/easy-multitenancy.php 'routes' => [ 'parameter' => 'tenant', 'middleware' => ['web'], 'auto_prefix' => env('TENANT_AUTO_PREFIX_ROUTES', true), 'excluded_routes' => [ 'home', ], 'excluded_patterns' => [ 'up', 'horizon*', 'telescope*', 'api/*', '_debugbar/*', '*.js', '*.css', '*.map', ], ],
Generating URLs
The package includes a custom URL generator that automatically includes the tenant parameter:
// Generate URL to a route url('/dashboard'); // Automatically becomes /{tenant}/dashboard // Named routes route('dashboard'); // Automatically includes tenant parameter // Generate URL for a specific tenant route('dashboard', ['tenant' => 'acme']);
Testing
composer test
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Credits
License
The MIT License (MIT). Please see License File for more information.