A 100% free, self-hosted, multi-user scheduling platform — a complete Calendly replacement.
No subscriptions, no monthly fees, no data leaving your control. Just PostgreSQL and a few serverless functions running on the free tier.
Get Started · Report a Bug · Contribute
- Free Forever — No paid tiers, no hidden costs. Runs entirely on free-tier Neon (PostgreSQL), Cloudflare Pages, and Brevo.
- Self-Hosted — Your data on your infrastructure. No third-party scheduling services processing your clients' information.
- Multi-User — Admin provisions hosts. Hosts configure their availability. Clients book meetings. All in one system.
- Passwordless Auth — Secure OTP codes via email. No passwords to manage or leak.
- Smart Scheduling — Configurable weekly hours, date-specific overrides, buffer times, and minimum notice.
- Double-Booking Protection — Real-time conflict detection. No external calendar API required.
- Client Auto-Registration — Clients are registered automatically on first booking. No signup forms.
- Role-Based Access — Admin and Host roles with appropriate permissions.
- Responsive — Desktop and mobile friendly.
| Component | Technology |
|---|---|
| Database | Neon (Serverless PostgreSQL) |
| API Layer | PostgREST (Auto-generated REST API) |
| Framework | Astro + React |
| Hosting | Cloudflare Pages |
| Brevo (Transactional) | |
| Auth | OTP + JWT + PostgreSQL Row-Level Security |
Browser → Cloudflare Pages (SSR) → PostgREST → Neon PostgreSQL
↓
RLS Policies
↓
JWT Auth
One database replaces Redis, Elasticsearch, RabbitMQ, and your entire custom API layer. PostgreSQL extensions handle JSONB (NoSQL), pg_trgm (fuzzy search), pgvector (embeddings), and SELECT ... FOR UPDATE SKIP LOCKED (job queues).
- Bun runtime
- A Neon PostgreSQL database (free tier)
- PostgREST installed locally (
brew install postgrest)
# Clone the repository
git clone https://github.com/SASS-Killers/OpenSchedule.git
cd open-calendar
# Install dependencies
bun install
# Copy and configure environment
cp .env.example .env
# Edit .env with your Neon database connection string
# Apply the database schema
psql $DATABASE_URL -f src/db/schema.sql
# Apply RLS policies and auth functions
psql $DATABASE_URL -f src/db/rls.sql
# Start the development server
bun run devThe app runs at http://127.0.0.1:6969. PostgREST starts automatically on port 6970.
After setup, hit /api/setup to create the initial admin account. Then navigate to /login and enter the admin email to receive a one-time code.
open-calendar/
├── prd/ # Product requirements documentation
├── src/
│ ├── components/ # React components (islands)
│ ├── db/ # Schema, migrations, Neon client
│ ├── layouts/ # Astro layouts
│ ├── lib/ # Auth, PostgREST client helpers
│ ├── pages/ # Routes and API endpoints
│ │ ├── [slug]/ # Public booking pages
│ │ ├── api/ # Thin API layer (session only)
│ │ ├── hosts/ # Host settings and public profiles
│ │ └── login.astro # Passwordless login
│ └── scripts/ # Schema application script
├── postgrest.conf # PostgREST configuration
└── astro.config.mjs # Astro configuration
"One battle-tested tool can cannibalize your entire architecture."
PostgreSQL with its extension ecosystem eliminates the need for:
- MongoDB →
JSONB+ GIN indexes - Redis/RabbitMQ →
SELECT ... FOR UPDATE SKIP LOCKED - Elasticsearch →
tsvector+pg_trgm - Pinecone →
pgvector+ HNSW indexes - Snowflake → Materialized views
- TimescaleDB → BRIN indexes + partitioning
- PostGIS → GiST indexes
One database. One source of truth. Zero sync problems.
MIT
