If there is a feature that could be improved or added, or even just a comment, contact me at dave@daves-corner.com.
Calixy is a Laravel-compatible appointment and availability package that uses the Unified Databases connection layer instead of Laravel's native database manager.
The package now ships with two setup modes:
startupedition: SQLite, auto-bootstrap, no manual install requiredproedition: explicit install flow for SQL Server, MySQL, PostgreSQL, or custom database wiring
It is designed for:
- staff and resource availability
- buffer times and blackout dates
- recurring schedules
- rescheduling and cancellations
- waitlists
- deposits and no-show fees
- timezone-safe booking rules
- multi-location and multi-tenant filtering
- system config storage for the starter app timezone
- company branding with a customizable company name and logo URL or uploaded logo
- starter pages for Services, Locations, Team, Notifications, Google, and Microsoft
It also ships with built-in UI themes:
sunriseatlanticevergreen
The package root now also includes a Laravel-style public/index.php entry point so there is a clear web start location inside the package source.
When you open that starting page in the startup edition, it boots a fully functional SQLite-backed application with a left-side navigation shell, starter service data, a calendar view, weekly availability, booking, rescheduling, cancellations, blackout dates, and waitlist management.
The startup edition also seeds a timezone catalog into SQLite from a local snapshot Timezones.php so the selected system timezone is stored in the database instead of only in config.
Locations and Team are now wired into the starter context as live filters, so the calendar, booking flow, appointments, waitlist, and setup forms can all be scoped to the selected location and booking owner.
Start from an existing Laravel app.
If you want to install and work with this repository directly, clone it first and run Composer from inside the cloned project folder:
git clone https://github.com/dharmor/Calixy.git
cd Calixy
composer installComposer must be run from the directory that contains composer.json. If you see:
File "./composer.json" cannot be found in the current directory
you are in the wrong folder. Change into the Calixy project directory first, then run composer install again.
For the default startup edition, just require the package and let it boot:
composer config repositories.calixy vcs https://github.com/dharmor/Calixy.git
composer require calixy/unified-appointments:dev-mainIf you are developing locally from a checked-out copy of this repository, use a path repository instead:
composer config repositories.calixy path ../Calixy
composer require calixy/unified-appointments:dev-mainOn first boot, the package will create and use:
database/unified-appointments.sqlite
No php artisan unified-appointments:install step is required for that startup SQLite flow. The startup page is intended to work immediately from public/index.php.
For this repository (standalone startup mode), run:
php -S 127.0.0.1:8000 -t publicThen open:
http://127.0.0.1:8000/
If you open /unified-appointments/about, that is the package About card, not the startup dashboard.
Windows note: if your current directory is a UNC path (for example \\server\share\...), PHP's built-in server may fail with Directory public does not exist. because it falls back to C:\Windows.
Use a mapped drive path instead (for example Y:\Github\Calixy) before running the command.
On Windows with Docker Desktop running, install and start Calixy with:
.\scripts\docker-install.ps1The script builds a self-contained PHP 8.5 / Apache 2.4 container, starts a MySQL 9.7 container, installs Composer and NPM dependencies, builds Vite assets, runs Laravel migrations and seeders against MySQL, and starts Calixy at:
http://localhost:8084
Use a different port:
.\scripts\docker-install.ps1 -Port 8081Recreate the Docker containers and MySQL volume before installing:
.\scripts\docker-install.ps1 -FreshCalixy should be published as a Composer package (calixy/unified-appointments) and used from a separate Laravel app.
This repository is configured as package-first:
- do not commit
vendor/ - do not commit
.env - do not commit
composer.lockfor this library package - keep local runtime settings in
.envand share defaults via.env.example
Release steps:
composer validate --strict
git tag v0.1.0
git push origin main --tagsThen require it from your starter/demo Laravel app:
composer require calixy/unified-appointmentsIf you want Pro edition behavior or another database engine, publish the config and run the explicit install command:
composer config repositories.calixy vcs https://github.com/dharmor/Calixy.git
composer require calixy/unified-appointments:dev-main
php artisan vendor:publish --tag=unified-appointments-config
php artisan unified-appointments:installThe SQL scripts needed for manual database setup are located in database/install.
Optional:
php artisan vendor:publish --tag=unified-appointments-viewsThe package also registers Laravel API routes by default under:
/unified-appointments
The startup defaults are now:
- default to
startupedition - use SQLite at
database/unified-appointments.sqlite - auto-create the SQLite file and schema on first boot
- seed the initial application so the starting page is usable immediately
- reserve the install command for Pro and alternate database setups
return [
'database_library_path' => 'C:\\Apache24\\htdocs\\Unified Databases',
'edition' => env('UNIFIED_APPOINTMENTS_EDITION', 'startup'),
'startup' => [
'auto_bootstrap' => env('UNIFIED_APPOINTMENTS_AUTO_BOOTSTRAP', true),
'database' => env('UNIFIED_APPOINTMENTS_STARTUP_DATABASE', database_path('unified-appointments.sqlite')),
],
'connection' => env('UNIFIED_APPOINTMENTS_CONNECTION'),
'driver' => env('UNIFIED_APPOINTMENTS_DRIVER'),
'host' => env('UNIFIED_APPOINTMENTS_HOST'),
'username' => env('UNIFIED_APPOINTMENTS_USERNAME'),
'password' => env('UNIFIED_APPOINTMENTS_PASSWORD'),
'database' => env('UNIFIED_APPOINTMENTS_DATABASE'),
'port' => env('UNIFIED_APPOINTMENTS_PORT'),
'table_prefix' => 'ua_',
'app_timezone' => 'America/New_York',
'routes' => [
'enabled' => true,
'prefix' => 'unified-appointments',
'name_prefix' => 'unified-appointments.',
'middleware' => ['api'],
],
'ui' => [
'theme' => 'atlantic',
'allow_theme_switcher' => true,
'donationware_url' => env('CALIXY_DONATIONWARE_URL', 'https://github.com/sponsors/YOUR_ACCOUNT'),
'themes' => [
'studio' => [
'label' => 'Studio',
'description' => 'Custom brand theme for a polished booking dashboard.',
'css_variables' => [
'--ua-page-background' => 'linear-gradient(135deg, #f4efe5 0%, #ead9c2 45%, #d2b48c 100%)',
'--ua-card-background' => '#fffaf3',
'--ua-card-muted-background' => 'rgba(255, 255, 255, 0.58)',
'--ua-border' => 'rgba(120, 73, 28, 0.18)',
'--ua-text' => '#36210c',
'--ua-muted-text' => '#6b4a26',
'--ua-accent' => '#9f5f22',
'--ua-accent-contrast' => '#fffaf3',
'--ua-pill-background' => 'rgba(159, 95, 34, 0.12)',
'--ua-shadow' => '0 22px 46px rgba(100, 67, 30, 0.14)',
],
],
],
],
];Theme support is config-driven. Set a default theme:
UNIFIED_APPOINTMENTS_THEME=evergreen
CALIXY_DONATIONWARE_URL=https://github.com/sponsors/YOUR_ACCOUNTOr add custom named themes in config/unified-appointments.php.
The package now includes:
- auto-discovered service provider
Calixyfacade aliasUnifiedAppointmentsfacade alias- startup SQLite auto-bootstrap
- explicit install command for alternate databases
- package-level overrides for custom connections
- configurable API route registration
- JSON controllers for services, availability, appointments, and waitlists
- publishable views
php artisan aboutintegration
If you want Calixy to use Pro mode or a different database, override it explicitly:
UNIFIED_APPOINTMENTS_CONNECTION=sqlsrv
UNIFIED_APPOINTMENTS_DRIVER=mssql
UNIFIED_APPOINTMENTS_HOST=127.0.0.1
UNIFIED_APPOINTMENTS_PORT=1433
UNIFIED_APPOINTMENTS_DATABASE=unified_appointments
UNIFIED_APPOINTMENTS_USERNAME=unified_user
UNIFIED_APPOINTMENTS_PASSWORD=ChangeMeNow!Then run:
php artisan unified-appointments:installGET /unified-appointments/slotsPOST /unified-appointments/servicesPOST /unified-appointments/availability-rulesPOST /unified-appointments/availability-exceptionsPOST /unified-appointments/appointmentsPOST /unified-appointments/appointments/{appointment}/reschedulePOST /unified-appointments/appointments/{appointment}/cancelPOST /unified-appointments/waitlist
use UnifiedAppointments\DTO\SlotSearchData;
use UnifiedAppointments\Laravel\Facades\Calixy;
$slots = Calixy::findAvailableSlots(new SlotSearchData(
serviceId: 1,
windowStart: new DateTimeImmutable('2026-04-27 00:00:00', new DateTimeZone('America/New_York')),
windowEnd: new DateTimeImmutable('2026-04-27 23:59:59', new DateTimeZone('America/New_York')),
staffId: 'staff-1',
timezone: 'America/New_York',
));use UnifiedAppointments\Config\UnifiedAppointmentsConfig;
use UnifiedAppointments\Database\SchemaManager;
use UnifiedAppointments\Database\UnifiedDatabaseConnector;
use UnifiedAppointments\Repositories\AppointmentRepository;
use UnifiedAppointments\Services\AppointmentScheduler;
$config = UnifiedAppointmentsConfig::fromArray([
'database_library_path' => 'Unified Databases',
'driver' => 'sqlite',
'host' => __DIR__ . '/storage/appointments.sqlite',
'database' => __DIR__ . '/storage/appointments.sqlite',
]);
$connector = new UnifiedDatabaseConnector($config);
$schema = new SchemaManager($connector, $config);
$repository = new AppointmentRepository($connector, $config);
$scheduler = new AppointmentScheduler($repository, $schema);
$scheduler->install();Run the included smoke test from the package root:
php tests/smoke.php