Open-source project
alextselegidis/easyappointments avatar
alextselegidis/easyappointments

Easy!Appointments: Self-Hosted Appointment Scheduling on PHP and MySQL

:date: Easy!Appointments - Self Hosted Appointment Scheduler

4,397 stars1,571 forksPHPGPL-3.0

At a glance

What is it?
Easy!Appointments is a GPL-3.0 scheduling platform you run on your own server, with a setup wizard, a REST API described in openapi.yml, and Google Calendar synchronization. It suits teams that want booking data in their own MySQL database and accept a PHP 8.2 deployment.
Who is it for?
Adopt Easy!Appointments if you need booking data inside your own MySQL instance and can run PHP 8.2 behind Apache or Nginx. Skip it if you want a managed service with no server to patch, or if you need a stable release line, since the newest tags are 1.6.1-alpha.1 and 1.6.1-beta.1.
Can I use it commercially?
Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 5 days ago.
What is it written in?
Mainly PHP, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The scheduling problem Easy!Appointments solves, and for whom

Most booking tools are hosted services: the calendar, the customer list and the reminder emails live on someone else's infrastructure, and the export path is whatever the vendor offers. Easy!Appointments takes the opposite position. The README describes it as a self-hosted scheduling system that gives you control over your booking workflow, and the feature list is organized around that: appointment and customer management, service and provider organization, working plans and booking rules, Google Calendar synchronization, and an email notification system. The data sits in a MySQL database you create and administer.

The audience is narrow but real. It fits a clinic, a studio, a repair shop or an internal IT desk that already runs PHP and MySQL, wants a booking page embedded in an existing site, and has someone who can patch a server. It is a poor fit for a solo operator who has no hosting and no interest in maintaining one. The README's own framing, that the platform is built for flexibility and adapts to your business, is the honest summary: the project expects you to configure services, providers and working plans before it does anything useful.

How the PHP application, MySQL schema and REST API fit together

The repository layout shows a CodeIgniter-style PHP application. The application/ directory holds the app code, system/ holds the framework, index.php is the front controller, and storage/ is the writable area for generated files. Configuration is read from config.php, which you create by renaming config-sample.php, so the database credentials and base URL are file-based rather than environment-based in a standard install.

On the client side, package.json lists jQuery, Bootstrap 5, FullCalendar 6, flatpickr, moment-timezone and select2. The build pipeline is Gulp: gulpfile.js plus Babel and Sass devDependencies compile and minify assets through npm run build. That means a source checkout needs a Node toolchain before the front end is usable, while the production install described in the README ships the built assets.

The integration surface is documented rather than implied. openapi.yml sits at the repository root and the Docker Compose file mounts it into a swagger-ui container, which is how the project exposes the REST API for inspection. The topics list on the repository includes rest-api and google-calendar, and the README lists Google Calendar synchronization as a feature. The README does not describe the sync direction, conflict resolution, or what happens when a token expires, so treat calendar sync as something to test against your own account before relying on it.

Installing Easy!Appointments with Docker Compose and running the first booking

The Quick Start section of the README is aimed at development and is the fastest way to see the application running. It clones the repository, enters the directory, and starts the Compose stack:

bash
git clone https://github.com/alextselegidis/easyappointments.git
cd easyappointments
docker compose up

The Compose file defines php-fpm, nginx, mysql, phpmyadmin, mailpit, swagger-ui, baikal and openldap. Nginx publishes port 80 by default, controlled by NGINX_PORT, and MySQL publishes 3306, controlled by MYSQL_PORT. The MySQL service is created with the database easyappointments, the user user and the password password, and the root password is secret. Those are development defaults, not production credentials.

With the stack up, the README opens a second terminal into the application container and installs dependencies:

bash
docker compose exec app bash
npm install && composer install
npm start

npm start runs Gulp, which watches and rebuilds the front-end assets; npm run build produces the production bundle. Note that the README's shell command names the service app, while docker-compose.yml defines the PHP service as php-fpm. Confirm the actual service name with docker compose ps before running that command.

For a production install the README gives a different path with no Docker. Requirements are Apache or Nginx, PHP 8.2 or newer, and MySQL. You create a database, upload the easyappointments folder, make the storage directory writable, rename config-sample.php to config.php, update the values, and open the application in a browser to complete the setup wizard. After the wizard, the first real use is administrative: create at least one service and one provider, attach a working plan, and only then share the booking page. Mailpit on port 8025 in the Compose stack is where notification emails land during development, which is how you check that the email system is configured before customers see it.

Where Easy!Appointments gets in your way

The release line is the first thing to weigh. The most recent tags are 1.6.1-beta.1 from 2026-09-07 and 1.6.1-alpha.1 from 2026-08-19, with the last stable release, 1.6.0, dated 2026-05-27. A team that wants a stable version should pin to 1.6.0 and ignore the pre-release tags, because the README does not document an upgrade or rollback procedure for moving between them. The README's installation section also does not document migration steps between releases, so database schema changes across versions are something you have to establish from the CHANGELOG.md in the repository before upgrading a live instance.

Operationally, the production path is manual. There is no documented package manager install, no signed release artifact described in the README, and no documented backup or restore command. You upload files and edit config.php. That is fine for a team with server habits and awkward for one without.

The licensing is a second constraint. The code is GPL-3.0 and the content is CC BY 3.0, per the README. GPL-3.0 is a copyleft licence, so if you modify the application and distribute it, the licence terms apply to that distribution. Running it as a service for your own customers is a different question, and the README does not discuss it. Take advice from a lawyer if the boundary matters to your business.

Finally, the README does not document rate limiting, audit logging, or how the REST API authenticates. Those are the questions to answer from openapi.yml and the application code, not from the README.

Easy!Appointments compared with Cal.com and hosted schedulers

The comparison people actually search for is Easy!Appointments versus Cal.com. Both are open source and both can be self-hosted, but they are built on different stacks and carry different operational weight. Easy!Appointments is PHP, CodeIgniter and MySQL, with a Gulp and Babel front-end build and a config.php file that holds deployment settings. Cal.com is a TypeScript and Node application. If your team already runs PHP and MySQL, Easy!Appointments adds no new runtime; if your team runs Node, the reverse is true.

The second difference is scope. Easy!Appointments centers on services, providers and working plans, and its README lists Google Calendar synchronization and email notifications as the integrations. Cal.com covers a broader set of calendar and video integrations. Neither is strictly better; the deciding question is which stack your on-call person can debug at 2am.

Hosted schedulers occupy a different position entirely. They remove the server, the database and the upgrade path from your plate, and in exchange your booking data and customer records live with the vendor. Easy!Appointments exists precisely because some organizations cannot accept that trade, whether for data residency, procurement rules, or the need to join bookings against an existing internal database. If none of those apply to you, a hosted tool is less work, and choosing Easy!Appointments anyway is a decision to maintain a PHP application indefinitely.

Maintenance, upgrades and what the repository does not tell you

The last push to the main branch was on 2026-09-14, and the repository is not archived. That is recent enough that the project is clearly being worked on, and the 1.6.1 pre-release tags in August and September 2026 are consistent with ongoing development. It does not tell you anything about support response times or the size of the maintainer group.

Upgrade cost is where the documentation is thinnest. The README's installation steps end at the setup wizard and say nothing about applying a later version to an existing install. There is no documented command for backing up the database or the storage directory, and no documented rollback. A team adopting this should decide its own procedure before the first upgrade: dump the MySQL database, copy the storage directory, and read CHANGELOG.md for the target version. That is general practice, not a project-specific feature, and the project does not provide a shortcut.

The front-end toolchain is a recurring cost rather than a one-time one. package.json pins a long list of Gulp plugins, Babel packages and Sass, and the README's development flow depends on npm install and composer install inside the container. Anyone rebuilding assets from source has to keep that toolchain working, though a production install that uses the shipped assets avoids it.

On licensing, the README states GPL v3.0 for code and CC BY 3.0 for content. Copyleft obligations attach to distribution of modified code. Whether your specific deployment counts as distribution is a legal question, and the repository does not answer it.

Editorial conclusion

Adopt Easy!Appointments if you need booking data inside your own MySQL instance and can run PHP 8.2 behind Apache or Nginx. Skip it if you want a managed service with no server to patch, or if you need a stable release line, since the newest tags are 1.6.1-alpha.1 and 1.6.1-beta.1. Verify first that the storage directory is writable and that config.php matches your database, because the setup wizard depends on both.

Frequently asked questions

How do I install Easy!Appointments on a server?

The README requires Apache or Nginx, PHP 8.2 or newer, and MySQL. You create a database, upload the easyappointments folder, make the storage directory writable, rename config-sample.php to config.php, update the values, and finish in the browser with the setup wizard.

How do I use Easy!Appointments after the setup wizard?

The README lists appointment and customer management, service and provider organization, and working plans and booking rules as the core features. In practice you create services and providers and attach working plans before sharing a booking page.

How does Easy!Appointments compare with Cal.com?

Both are open source and can be self-hosted, but Easy!Appointments is PHP and MySQL with a config.php deployment file and a Gulp front-end build, while Cal.com is a TypeScript and Node application. The README lists Google Calendar synchronization and email notifications as the integrations for Easy!Appointments.

What is a self-hosted alternative to hosted appointment schedulers?

Easy!Appointments is one: the README describes it as fully self-hosted, so your data stays under your control, and it is free for personal and commercial use. The trade is that you run and patch the PHP and MySQL stack yourself.

What is the most commonly used appointment scheduling system?

There is no usage data in the repository to answer that. What the README does state is that Easy!Appointments is open source, self-hosted, and free for personal and commercial use, so the choice depends on your hosting and data requirements rather than on popularity.

Official sources

  1. alextselegidis/easyappointments on GitHub
  2. License: GPL-3.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/alextselegidis-easyappointments.svg)](https://hysenlabs.com/projects/alextselegidis-easyappointments)