Multi-tenant school ERP. Built with Laravel and React.

School management as a platform. A console onboards and bills schools. Each school gets a full ERP. Demo tenants: “Generic Public School” and “Another Generic School”.

Live demo (opens in a new tab) Pick a demo login on the sign-in page (password: password). Platform console: erp-demo.chetan.cloud, admin@example.com. Resets nightly.

Stack
Laravel 13, React 19, Vite, Multi-tenant
Results
540 tests passing. Two demo tenants running side by side on one platform. Overdue fee tracking. The office sees who owes what without a spreadsheet.

Problem

Schools need one place for the daily work: who is enrolled, who teaches what and when, who was present, who owes fees. Each school’s data stays separate from every other school’s.

The platform onboards and bills a school with nobody touching a database by hand.

Built

  • API: Laravel 13, one database per tenant.
  • Frontend: React 19 + Vite.
  • Platform console: onboarding, billing, invoices.
  • Per school: students, staff, classes and sections, timetable, attendance, fees with overdue tracking, helpdesk.

Decisions

A database per tenant
Isolation is structural, not a where-clause someone has to remember. Backups, restores and exports work per school.
API plus a separate frontend
People use the ERP all day, unlike the CMS. A standalone React frontend over a clean API leaves room for a mobile app.
Onboarding as code
Creating a school provisions its database, runs migrations and seeds defaults in one step from the console. No manual setup.

Next time

Settle how a request finds its tenant (subdomain, header or path) on day one. Write it down before building screens on it.

Build offline-first attendance early. Classrooms do not always have good connectivity.

chetan@chetan.cloud