CodingIdeas.ai
← Browse All Ideas

Build Guide

How to Build a Calendar App

Calendar apps are deceptively hard — timezone handling alone has broken teams of senior engineers at Google and Microsoft.

Intermediate1–2 weeks

Building a calendar forces you to understand date/time arithmetic, recurring event logic, iCal format, conflict detection, and Google Calendar API OAuth — skills that appear in almost every enterprise SaaS.

Data model

The core tables you'll need before writing any UI.

Userid, email, timezone, google_calendar_token
Eventid, user_id, title, description, start_at (UTC), end_at (UTC), all_day (bool), recurrence_rule (RRULE string), google_event_id, color, created_at
Attendeeevent_id, email, status (accepted/declined/pending)

Build order

The sequence that minimises rewrites — build in this order.

1

Month view grid

Build a 7×5 CSS grid for the month view. Populate each cell with the day number. Show today highlighted. Use date-fns to calculate the first day of the month and pad with days from the previous month.

2

Create and show events

Add a click handler on each day cell that opens a modal to create an event. Store events with start_at and end_at as UTC ISO strings. Render event pills on the correct day cells.

3

Week and day views

Build a week view: 7 columns with hourly time slots. Position events as absolute divs based on their start time offset and height based on duration. Day view is the same with one column.

4

Timezone handling

All events are stored in UTC. Use date-fns-tz to convert to the user's timezone for display. When creating an event, convert the user's local time back to UTC before saving. Never store local times.

5

Recurring events

Store recurring events as RRULE strings (RFC 5545 standard). Use the rrule.js library to expand them into occurrences for the current view range. Never materialise all occurrences in the DB — generate them on the fly.

6

Google Calendar OAuth + sync

Register a Google OAuth app. Request the calendar.events scope. On connect: fetch all events from the Google Calendar API and import them. On new event creation in your app, create it via the Google API and store the google_event_id.

7

Invites and RSVP

On event create, allow adding attendee emails. Send invite emails via Resend with Accept/Decline links. Each link hits /api/rsvp/[token]?status=accepted which updates the attendee row and sends a confirmation.

Build it with AI — Architect Prompt

Paste this into Claude, Cursor, Windsurf, or any AI coding tool. It includes the full context of this guide — data model, build order, and pitfalls — so the AI starts with everything it needs.

ClaudeCursorWindsurfCopilotGemini
architect-prompt.txt
<context>
App: Calendar App
Difficulty: Intermediate
Estimated build time: 1–2 weeks

Data model:
  User: id, email, timezone, google_calendar_token
  Event: id, user_id, title, description, start_at (UTC), end_at (UTC), all_day (bool), recurrence_rule (RRULE string), google_event_id, color, created_at
  Attendee: event_id, email, status (accepted/declined/pending)

Recommended build order:
  1. Month view grid — Build a 7×5 CSS grid for the month view. Populate each cell with the day number. Show today highlighted. Use date-fns to calculate the first day of the month and pad with days from the previous month.
  2. Create and show events — Add a click handler on each day cell that opens a modal to create an event. Store events with start_at and end_at as UTC ISO strings. Render event pills on the correct day cells.
  3. Week and day views — Build a week view: 7 columns with hourly time slots. Position events as absolute divs based on their start time offset and height based on duration. Day view is the same with one column.
  4. Timezone handling — All events are stored in UTC. Use date-fns-tz to convert to the user's timezone for display. When creating an event, convert the user's local time back to UTC before saving. Never store local times.
  5. Recurring events — Store recurring events as RRULE strings (RFC 5545 standard). Use the rrule.js library to expand them into occurrences for the current view range. Never materialise all occurrences in the DB — generate them on the fly.
  6. Google Calendar OAuth + sync — Register a Google OAuth app. Request the calendar.events scope. On connect: fetch all events from the Google Calendar API and import them. On new event creation in your app, create it via the Google API and store the google_event_id.
  7. Invites and RSVP — On event create, allow adding attendee emails. Send invite emails via Resend with Accept/Decline links. Each link hits /api/rsvp/[token]?status=accepted which updates the attendee row and sends a confirmation.

Known pitfalls to avoid:
  - Materialising all recurring event occurrences in the database — a "repeat forever" event would generate infinite rows. Store the RRULE string and use rrule.js to expand it for the current view window only.
  - Comparing dates without timezone awareness — new Date("2026-04-09") in JavaScript treats the string as UTC midnight, which renders as the previous day in western timezones. Always use date-fns-tz for timezone-aware comparisons.
  - Fetching all events for all time on load — query only events within the current view range (month start to month end + padding). A user with 5 years of events should not have them all loaded on the first render.

Tech stack (intermediate): Next.js + Supabase + FullCalendar + Google Calendar API + date-fns-tz
</context>

<role>
You are a Senior Full-Stack Engineer and product architect who has shipped production Calendar Apps before. You know exactly where developers get stuck and how to structure the project to avoid rewrites.
</role>

<task id="step-1-clarify">
Before writing any code or spec, ask me 3–5 clarifying questions that will meaningfully change the architecture. Focus on: scale expectations, auth requirements, platform (web / mobile / both), must-have vs nice-to-have features for the MVP, and any hard constraints (budget, deadline, existing infrastructure).

<example>
BAD: "What tech stack do you want to use?" — too broad, doesn't change architecture decisions.
GOOD: "Do you need real-time sync across devices, or is single-device with periodic refresh acceptable? This decides whether we use WebSockets or simple REST polling and significantly affects infrastructure complexity."
</example>
</task>

<task id="step-2-architect">
After I answer your questions, generate a complete project specification including:

1. Final tech stack with version numbers
2. Full file and folder structure
3. Complete database schema — every table, column, type, index, and foreign key
4. All API routes with request/response shapes and auth requirements
5. Component tree with TypeScript props interfaces
6. Auth and authorisation flow (who can do what)
7. Step-by-step implementation plan in the exact build order from <context> above
8. All environment variables with descriptions

<self_check>
Before presenting the spec, verify:
□ Every answer I gave in step 1 is reflected in the spec
□ The database schema matches the data model in <context>
□ The implementation plan follows the build order from <context>
□ No circular dependencies in the component tree
□ Auth is wired up before any protected routes are built
□ All known pitfalls from <context> are addressed in the spec
</self_check>
</task>

<task id="step-2.5-agents-md">
Generate an AGENTS.md file at the project root. This file is read automatically by Claude Code, Cursor, Windsurf, Sourcegraph Cody, and all major AI coding tools at the start of every session.

Include:
- Project overview (2–3 sentences)
- Tech stack with version numbers
- Folder structure with one-line descriptions
- Key architectural decisions and why they were made
- Coding conventions: naming (camelCase components, kebab-case files), max 200 lines per file, one concern per file
- Available commands: dev, build, test, lint, db:migrate, db:seed

Note in the file: "Cursor users can symlink .cursorrules → AGENTS.md. Claude Code users can symlink CLAUDE.md → AGENTS.md."
</task>

<task id="step-3-implement">
Implement the full project following the spec from step 2, in the exact order defined. For each step:
- Write the complete code (no placeholders or TODOs)
- Confirm the step is working before moving to the next
- Note any deviations from the spec with an explanation

<constraints>
- Max 200 lines per file. WHY: every file must fit in one AI context window for easy review and editing.
- One concern per file. WHY: mixing auth logic into API routes makes it impossible to reuse — extract to lib/auth.ts.
- TypeScript strict mode, no `any` types. WHY: catches data shape mismatches at compile time, not in production at 2am.
- All database queries in server components or API routes only. WHY: keeps credentials server-side, prevents accidental client-side exposure.
- All environment variables documented in .env.example. WHY: the next developer (or your future self) should be able to set up the project in under 5 minutes.
- Comment every non-obvious decision. WHY: AI tools read your comments to understand intent — without them, the next edit will break the pattern you established.
</constraints>
</task>

How to use this prompt

  1. 1.Copy the prompt above
  2. 2.Open Claude, Cursor (Cmd+L), or Windsurf
  3. 3.Paste the prompt and send — the AI will ask 3–5 clarifying questions
  4. 4.Answer the questions, then it generates your full project spec
  5. 5.Continue in the same session to implement step by step

Common mistakes

What trips up most developers building this for the first time.

⚠️

Materialising all recurring event occurrences in the database — a "repeat forever" event would generate infinite rows. Store the RRULE string and use rrule.js to expand it for the current view window only.

⚠️

Comparing dates without timezone awareness — new Date("2026-04-09") in JavaScript treats the string as UTC midnight, which renders as the previous day in western timezones. Always use date-fns-tz for timezone-aware comparisons.

⚠️

Fetching all events for all time on load — query only events within the current view range (month start to month end + padding). A user with 5 years of events should not have them all loaded on the first render.

Recommended tech stack

Pick the level that matches your experience.

Beginner

React + FullCalendar.js — full calendar UI in an afternoon with a pre-built component

Intermediate

Next.js + Supabase + FullCalendar + Google Calendar API + date-fns-tz

Advanced

Next.js + Supabase + custom calendar renderer + CalDAV server + conflict detection

Take it further — related ideas

Each comes with revenue math, a full build guide, and a prompt to paste into Claude or Cursor.

9 ideas in the archive

Ship in:
intermediateMCP & Integrations

ReplayIQ - MCP Server That Injects Live PostHog Session Replay Context Into Claude for Instant UX Diagnosis

You can watch session replays in PostHog all day but Claude has no idea what your users are actually doing. ReplayIQ is an MCP server that pulls live PostHog session replay metadata, event sequences, and rage-click hotspots into Claude's context so you can ask it to diagnose UX failures in plain English. It's like giving Claude eyes on your product.

Time to ship2 weeks
DemandHigh
Revenue7/10
AI quality score8/10
View Details →
beginnerBusiness Automation

ContractPulse - Vendor Renewal and Health Monitor for Bootstrapped SaaS Teams

Small SaaS teams routinely lose money on zombie vendor contracts because no one owns the renewal calendar. ContractPulse ingests your vendor invoices and emails, surfaces upcoming renewals, flags price drift, and sends Slack alerts 30 days out. It's the CFO dashboard you couldn't afford to hire.

Time to ship2 weeks
DemandHigh
Revenue7/10
AI quality score6/10
View Details →
beginnerRestaurant Tech

MenuMap - Drag-and-Drop Menu Builder With QR Code Ordering for Independent Restaurants

Independent restaurant owners are still updating PDF menus by emailing their web developer cousin. MenuMap is a no-code drag-and-drop menu builder that generates a live QR code menu, handles item availability toggles in real time, and optionally accepts orders — all without touching a line of code.

Time to ship2 weeks
DemandVery High
Revenue8/10
AI quality score7/10
View Details →
intermediateGig Economy

PawRoute - White-Label Booking App for Independent Dog Walkers

Independent dog walkers are hemorrhaging clients to Rover's 30% commission cut while managing everything via PayPal.me links and texts. PawRoute gives every solo pet care pro their own branded booking page, live GPS walk tracking for anxious owners, and Stripe-powered invoicing.

Time to ship3 weeks
DemandHigh
Revenue8/10
AI quality score8/10
View Details →
beginnerGig Economy

CoachSlot - Mobile Booking and Payments for Solo Fitness Coaches

Solo yoga teachers and PTs are running $5k/month businesses on WhatsApp and bank transfers like it's 2009. CoachSlot gives every solo fitness coach a personal booking link, Stripe card payments, and automatic cancellation fee enforcement — no more ghost clients.

Time to ship2 weeks
DemandVery High
Revenue8/10
AI quality score7/10
View Details →
advancedNLP & Text AI

ChurnVision - NLP Session Replay Tagger That Predicts Drop-Off Before It Happens

FullStory shows you the replay. Nobody tells you which replays predict churned users. ChurnVision is an NLP pipeline that ingests session event logs, tags behavioral sequences with churn-risk labels, and surfaces the exact UX moments where users disengage — before they cancel.

Time to ship3 weeks
DemandHigh
Revenue8/10
AI quality score7/10
View Details →
intermediateSaaS

ShiftFill - Self-Service Shift Swap Marketplace for Hourly Retail and Hospitality Teams

Shift managers at retail and restaurant chains spend 2 hours every Sunday texting staff to fill open shifts because their scheduling software has no self-service swap layer. ShiftFill is a mobile-first marketplace where employees post and claim open shifts in real time with manager approval in one tap.

Time to ship3 weeks
DemandVery High
Revenue8/10
AI quality score7/10
View Details →
intermediateBusiness Automation

TimeSync - Real-Time Monday.com to Toggl and Harvest Bridge With Full Task Context

Monday.com passes 'Monday App' as the project name to every time tracking tool, making billable hours useless for client invoicing. TimeSync listens to Monday board events and auto-creates Toggl and Harvest entries with the actual task name, board, and assignee so your timesheet actually matches your work.

Time to ship2 weeks
DemandHigh
Revenue7/10
AI quality score6/10
View Details →
intermediateBusiness Automation

VenueYield - Dynamic Seat Pricing Engine for Independent Event Venues

Independent music venues and comedy clubs are still pricing tickets in spreadsheets while StubHub scalpers print money on the delta. VenueYield is a plug-and-play dynamic pricing engine that watches demand signals and automatically adjusts ticket prices to maximize revenue without alienating regulars.

Time to ship3 weeks
DemandHigh
Revenue8/10
AI quality score6/10
View Details →