Wedding 3D Invite
A mobile-first digital wedding invitation: a lace envelope in Three.js that opens at a tap, then the day told in eleven slides, with RSVP and offline support.
Designed and built on my own in 2026, for the wedding of two friends.
- React
- TypeScript
- Three.js
- Tailwind CSS
- Vite

Context
Two friends of mine wanted their paper wedding invitation, in lace and pearls, rebuilt for the phone their guests already hold. It has to feel like opening a real envelope, then answer every practical question: when, where, how to get there, what to wear, and whether you are coming.
How it is built
- A React and TypeScript single-page app built with Vite and styled with Tailwind CSS, mobile first; on a desktop the invitation sits in a phone-sized frame.
- The envelope is a Three.js scene: lace flaps that open, a wax seal that lifts away and pearls with physically based materials.
- Eleven full-screen slides with CSS scroll snap: countdown, calendar export, maps, programme, dress code, transport and RSVP.
- RSVP answers go to a Google Sheet through Google Apps Script, so there is no server to run; a service worker keeps the invitation working offline as a PWA.
Key decisions
Every word of the invitation in one config file
Names, date, places, programme and RSVP live in a typed config, so the demo runs on sample names while the real invitation keeps its own. Title, Open Graph tags, event JSON-LD, manifest and service worker are generated from the same config.
The 3D scene stops once the envelope is open
After the opening animation the render loop freezes, so reading the invitation costs no GPU time and no battery. A button in the footer plays the opening again.
One palette, with contrast under test
The burgundy and ivory palette is defined once and flows into Tailwind, Three.js, the manifest and the icons. A unit test fails the build on any combination below WCAG AA contrast.
Outcome
The real invitation belongs to my friends and stays private; the public demo on Vercel shows the same invitation with sample names.