Build a Luma alternative

Build a Luma alternative as an event page, an RSVP form, and a private guest list. Plus is $59 a month, rent you can cancel after one real event.

  • getting-started
  • vibe-coding
  • scope

You can build a Luma alternative as an event page, an RSVP form, and a private guest list. Luma is that product. The catalog line is “A date, a page, and who said yes.”

You pay $59 a month for Plus, billed annually. That is $708 a year. The basic replacement is 10 hours: an event page, an RSVP, and a guest list.

Ship this if you still rent an event tool to publish a meetup you already host. It is marked Weekend. The verdict on the card is “The event is a page”.

Last time I wrote about vibe coding your own PagerDuty. That was a teardown. This one is a regular backlog topic. Paid tickets, tax, SMS, and a marketplace stay on the skip row.

What you need to build a Luma alternative

The Luma page splits the work into three rows.

The first row is the one you want this weekend. One event with a title, a local start, and a place. A public page with an RSVP form. A guest list only you can open, with search and a CSV.

The second row is 3 days. A calendar of events, a capacity with a waitlist, reminder email, and a second event. Twenty seats stay twenty, and people hear from you the day before.

The third row is a month and up. Paid tickets, tax, SMS, and a marketplace. The table labels that row as the part you should skip.

If you tell an agent to “clone Luma”, it aims at the third row. Copy the prompt, then pin it to the first one.

The card lists Calendar, Event, Guest, and Rsvp. For these 10 hours, store Event, Guest, and Rsvp. The calendar arrives when you have two events worth listing.

An event has a title, a local start, a place, and a public or unlisted flag. A guest has a name and an email. An RSVP ties that guest to the event with a status. This weekend the status is going or canceled. Waitlisted arrives with capacity.

Store the start as the clock time you typed, plus a timezone name. The public page prints Thu 12 Nov 2026, 18:30, Europe/Rome for every guest. The card calls that field a local start.

Close is a field on the event. The page stays up, the form is replaced by the closed state, and a late submit is rejected. The guest count stays where it was.

How does a Luma alternative work

I am describing the catalog’s model of an event page. You publish one event, the server records each RSVP, and the guest list stays off the public URL.

Your browser talks to one Astro app. Node.js plus Astro is the catalog default. Use TanStack Start if React is your weekday language. The capability line on the card is Astro, HTMX, and D1.

The app saves the event on the request. D1 holds the rows. Publish mints a long random token and returns the public URL. An RSVP writes the guest and the RSVP in one request, then hands two messages to the email provider. Ada gets a confirmation. You get a short note. Capacity checks, waitlist rows, and reminder jobs wait on the 3-day row.

The public page is server-rendered. HTMX can swap the form for a thank-you without a second app. The route loads by token, so a guess at /events/1 returns an empty result. The event id stays off that URL.

Every host query is scoped by owner. A guessed event id from another account returns an empty guest list.

YOUR BROWSER Editor, public page, guest list Ada has the event link only ASTRO APP ON THE REQUEST Save event, accept RSVP Mint a token, close the page D1 HOLDS THE ROWS Event, Guest, Rsvp One row per event and email EMAIL PROVIDER Confirmation to Ada, note to you A retry sends the same pair CAPACITY AND CALENDAR LATER Waitlist, reminder, second event 3-day row, after one meetup Tickets, tax, SMS, marketplace stay on the month row
Publish mints a token and stores the RSVP. Seats and reminders wait three days.

The confirmation is part of the 10-hour row, because the integrations line already names transactional email. A reminder the morning of the meetup is the 3-day job, keyed to the event so a retry mails Ada once.

Screens of a Luma alternative

v1 needs the editor, the public page, and the guest list.

Event editor

The editor is a form. Title, local start, timezone, place, and a public or unlisted toggle. One button publishes and copies the link.

With no events yet, this form is the home screen. A calendar of upcoming and past events is the 3-day row. The public flag is stored now, and nothing lists the event until that calendar exists. Unlisted stays off it later. Public can appear on it.

Public event page

The public page shows the title, the clock time, the place, and the RSVP form. Name and email. A submit button. After a valid RSVP, the same page shows a thank-you and hides the form in that browser.

Names and emails stay on the host list. Remaining seats wait until you store a capacity. Until then, the page shows no seat count.

WIREFRAME · PUBLIC PAGE November writing meetup Thu 12 Nov 2026 · 18:30 Europe/Rome · Bootcamp.dev studio Name Email RSVP Thank-you replaces this form Guest names stay on the host list
The link shows one event and a form. The guest table is a different page.

Private guest list

The guest list is a host page. Each row has the name, the email, the status, and the time of the RSVP. Search filters that table. CSV downloads the same rows.

There is no public URL for this table. An embed of the event page leaves it out. A token that opens the event still cannot open the list.

WIREFRAME · GUEST LIST Guest list · host only Ada Rossi · going [email protected] · 12 Nov, 09:14 Jordan Lee · canceled [email protected] · 12 Nov, 11:02 Search CSV No public URL for this table
Search and CSV use the same rows. The public page never joins them.

How an RSVP on a Luma alternative works

You create “November writing meetup” for Thursday 12 November 2026 at 18:30, Europe/Rome, at the Bootcamp.dev studio. Publish returns a token. You send that link to the people you already email.

Ada Rossi opens it on her phone, types her name and email, and submits. The server writes one Guest and one Rsvp with status going. She gets a confirmation. You get a note. The guest list shows Ada as going.

She submits the same email an hour later. The rule on the card is one guest row per event and email. The second submit returns the existing row and leaves the seat count alone. Rate limiting sits on that public route so a script cannot fill the table.

You close the event on Friday morning. A later submit is rejected, and the public page shows the closed state. The guest count stays at the people already stored.

CREATE THE EVENT 12 Nov 2026, 18:30, Europe/Rome PUBLISH MINTS A TOKEN The event id stays off the URL MAIL THE LINK events.flaviocopes.com and the token ADA SUBMITS Name and email, on her phone ONE GOING ROW Same email returns the same guest TWO EMAILS, ONE LIST Ada confirmed, you see her as going CLOSE REJECTS A LATE YES Count stays on the stored guests
The 10-hour loop ends when Ada is on your list and a late submit fails.

The public route reads Event by token. The guest table stays out of that HTML.

Who a Luma alternative is for

The audience on the page is a host publishing a few public events on one calendar. The goal is an event page, RSVPs, and a list of who is coming.

This weekend is one page and that list, sent to people who already know the meetup. The calendar of several events is the next row. A discovery marketplace stays on the month row.

Leave tickets off a Luma alternative

Paid tickets, tax, and SMS stay on the month row. The non-goal on the page already names them. Paste it back when the agent starts a checkout or a text message.

A card form on the RSVP is ticket sales. The 10-hour row ends when Ada is on your list and the public page still hides everyone else. The card also lists Partiful and Meetup as apps this scope can stand in for.

A Luma alternative or an RSVPify list

Capacity, the waitlist, reminders, and a second event sit on day three.

RSVPify is $24–$409 a month, about 12 hours for an invite list, an RSVP form, and guest totals. The catalog line is “Know who is coming before ordering the food.” That card starts from private invitation tokens. This first row is a page you publish, and people who have the link can say yes.

Bookwhen is $16–$59 a month, about 3 days for a class timetable, capacity, and reservations. The catalog line is “One class timetable. No spreadsheet full of maybes.” Use Bookwhen for recurring sessions with a seat count. Use this card for one meetup page.

A 30-minute slot on your own calendar is Calendly, $12–$20 a person a month, about 6 hours. I wrote that up as vibe code your own Calendly. Calendly offers open times. This clone offers one start time and a yes.

A poll to pick the date is the Doodle guide. Doodle is $7–$9 a person a month, about 3 hours. Pick the date there, then publish it here. The first-project post still points at a tonight card if you have not shipped a small tool yet.

The 3-day row, after one real event

Publish the page for a meetup you would host. Then use the second estimate: a calendar, capacity, reminders, and a second event.

The first mini-prompt is the capacity transaction. You store an integer capacity, 20 for the writing meetup. The RSVP insert checks that number inside the same database transaction. The twentieth going guest succeeds. The twenty-first becomes waitlisted, or is rejected if the waitlist is still unbuilt. Two submits at the same moment still produce one success and one waitlist. The prompt scenario on the card says that outright.

The second mini-prompt is the reminder. A scheduled job finds events whose local start is tomorrow and whose reminder is unsent. It records the send, then mails going guests once. Waitlisted guests wait until a seat opens.

The calendar lists upcoming events and folds past ones away. Public events can appear on it. Unlisted events stay on the link only. Passing the stored local start rejects a new RSVP and leaves the count unchanged.

The scope post is the same three-row table. The prompt post is the line that keeps the ticket checkout out of the weekend.

Host it, publish one event, cancel

This one wants Astro, HTMX, and D1, because that is the stack on the card. Take a backup of the guest rows before you delete the paid account.

Put the page on a hostname you already own, events.flaviocopes.com. Create the November writing meetup. Open the link in a private window. Submit Ada. The guest list should show her, and the public page should leave her name off.

Close the event and submit again. The second submit should fail, and the count should stay put.

Then cancel Luma.

Start now

Go to Build your own Luma. Copy the Astro prompt, or TanStack Start if that is what you write.

Tell the agent the first estimate only: event page, RSVP, guest list. Ten hours.

Publish one real meetup this weekend, and keep the guest list on a page only you can open.

Keep reading

Read all articles →