product
One place to describe, build and ship an app.
Yuzu is a chat, an editor, a database and a host. Here is what each part does, without the adjectives.
chat + build log
You talk. Yuzu shows its work.
Every step is written down as it happens: what Yuzu read, what it planned, which files it touched. If something looks wrong, say so and it backs up.
YUZU · clay-studio
A booking app for my pottery studio. Weekly classes, 8 seats each, Stripe deposits, and a reminder email the day before.
[✓] Read the prompt
[|] Planning the data model
Yuzu is thinking. This takes about as long as making tea.
Ask for a change…
Preview
Code
Versions
Deploy
clay-studio.yuzu.app
Clay & Co. Studio
Wheel throwing, hand building and glazing. Small classes, muddy hands.
Wheel basics
Tue 18:30 · 3 seats left
Book
Hand building
Thu 10:00 · full, 2 waiting
Waitlist
Glaze night
Fri 19:00 · 5 seats left
Book
Plan · data model
5 tables · 4 relations
classes
id
uuid · pk
title
text
starts_at
timestamp
capacity
int · 8
seats
id
uuid · pk
class_id
→ classes
number
int
held_until
timestamp
bookings
id
uuid · pk
seat_id
→ seats
user_id
→ users
status
enum
users
id
uuid · pk
text
name
text
stripe_id
text
payments
id
uuid · pk
booking_id
→ bookings
deposit
int · £10
stripe_ref
text
relations
seats
→ classes
bookings
→ seats
bookings
→ users
payments
→ bookings
// app/bookings/actions.ts
export async function bookSeat(classId: string) {
const user = await auth.require()
const cls = await db.classes.find(classId)
if (cls.seatsLeft === 0) return waitlist(user, cls)
const deposit = await stripe.checkout({
amount: cls.depositCents,
customer: user.stripeId,
})
await db.bookings.create({ user, cls, deposit })
await email.schedule(“reminder”, cls.startsAt - DAY)
}
Version history
14 versions
Added a waitlist when a class is full
v14 · bookings · 2 min ago
Current
Reminder email the day before
v13 · emails · 14 min ago
Restore
Stripe deposits, £10 per seat
v12 · payments · 31 min ago
Restore
First version: classes and bookings
v11 · setup · 48 min ago
Restore
Restoring makes a new version. Nothing gets thrown away.
● LIVE
Deployed in 41s · v14
✓
Domain connected
dns ok
✓
SSL issued
auto-renews
✓
Database ready
eu-west
✓
Preview link ready
v14
YUZU · clay-studio
A booking app for my pottery studio. Weekly classes, 8 seats each, Stripe deposits, and a reminder email the day before.
[✓] Read the prompt
[|] Planning the data model
Yuzu is thinking. This takes about as long as making tea.
Ask for a change…
Preview
Code
Versions
Deploy
Clay & Co. Studio
Wheel throwing, hand building and glazing. Small classes, muddy hands.
Wheel basics
Tue 18:30 · 3 seats left
Book
Hand building
Thu 10:00 · full, 2 waiting
Waitlist
Glaze night
Fri 19:00 · 5 seats left
Book
Plan · data model
5 tables · 4 relations
classes
id
uuid · pk
title
text
starts_at
timestamp
capacity
int · 8
seats
id
uuid · pk
class_id
→ classes
number
int
held_until
timestamp
bookings
id
uuid · pk
seat_id
→ seats
user_id
→ users
status
enum
users
id
uuid · pk
text
name
text
stripe_id
text
payments
id
uuid · pk
booking_id
→ bookings
deposit
int · £10
stripe_ref
text
relations
seats
→ classes
bookings
→ seats
bookings
→ users
payments
→ bookings
// app/bookings/actions.ts
export async function bookSeat(classId: string) {
const user = await auth.require()
const cls = await db.classes.find(classId)
if (cls.seatsLeft === 0) return waitlist(user, cls)
const deposit = await stripe.checkout({
amount: cls.depositCents,
customer: user.stripeId,
})
await db.bookings.create({ user, cls, deposit })
await email.schedule(“reminder”, cls.startsAt - DAY)
}
Version history
14 versions
Added a waitlist when a class is full
v14 · bookings · 2 min ago
Current
Reminder email the day before
v13 · emails · 14 min ago
Restore
Stripe deposits, £10 per seat
v12 · payments · 31 min ago
Restore
First version: classes and bookings
v11 · setup · 48 min ago
Restore
Restoring makes a new version. Nothing gets thrown away.
● LIVE
Deployed in 41s · v14
✓
Domain connected
dns ok
✓
SSL issued
auto-renews
✓
Database ready
eu-west
✓
Preview link ready
v14
YUZU · clay-studio
A booking app for my pottery studio. Weekly classes, 8 seats each, Stripe deposits, and a reminder email the day before.
[✓] Read the prompt
[|] Planning the data model
Yuzu is thinking. This takes about as long as making tea.
Ask for a change…
code
Readable code, in a stack you know.
Next.js, TypeScript, Postgres and Tailwind. No proprietary runtime. Open any file, edit it by hand, and Yuzu keeps up.
YUZU · clay-studio
A booking app for my pottery studio. Weekly classes, 8 seats each, Stripe deposits, and a reminder email the day before.
[✓] Read the prompt
[✓] Planned 5 tables: classes, seats, bookings…
[✓] Set up auth with magic links
[✓] Connected Stripe (test mode)
[✓] Wrote 23 files
[—] Writing the booking flow
Yuzu is thinking. This takes about as long as making tea.
Ask for a change…
Preview
Code
Versions
Deploy
clay-studio.yuzu.app
Clay & Co. Studio
Wheel throwing, hand building and glazing. Small classes, muddy hands.
Wheel basics
Tue 18:30 · 3 seats left
Book
Hand building
Thu 10:00 · full, 2 waiting
Waitlist
Glaze night
Fri 19:00 · 5 seats left
Book
Plan · data model
5 tables · 4 relations
classes
id
uuid · pk
title
text
starts_at
timestamp
capacity
int · 8
seats
id
uuid · pk
class_id
→ classes
number
int
held_until
timestamp
bookings
id
uuid · pk
seat_id
→ seats
user_id
→ users
status
enum
users
id
uuid · pk
text
name
text
stripe_id
text
payments
id
uuid · pk
booking_id
→ bookings
deposit
int · £10
stripe_ref
text
relations
seats
→ classes
bookings
→ seats
bookings
→ users
payments
→ bookings
// app/bookings/actions.ts
export async function bookSeat(classId: string) {
const user = await auth.require()
const cls = await db.classes.find(classId)
if (cls.seatsLeft === 0) return waitlist(user, cls)
const deposit = await stripe.checkout({
amount: cls.depositCents,
customer: user.stripeId,
})
await db.bookings.create({ user, cls, deposit })
await email.schedule(“reminder”, cls.startsAt - DAY)
}
Version history
14 versions
Added a waitlist when a class is full
v14 · bookings · 2 min ago
Current
Reminder email the day before
v13 · emails · 14 min ago
Restore
Stripe deposits, £10 per seat
v12 · payments · 31 min ago
Restore
First version: classes and bookings
v11 · setup · 48 min ago
Restore
Restoring makes a new version. Nothing gets thrown away.
● LIVE
Deployed in 41s · v14
✓
Domain connected
dns ok
✓
SSL issued
auto-renews
✓
Database ready
eu-west
✓
Preview link ready
v14
Preview
Code
Versions
Deploy
clay-studio.yuzu.app
Clay & Co. Studio
Wheel throwing, hand building and glazing. Small classes, muddy hands.
Wheel basics
Tue 18:30 · 3 seats left
Book
Hand building
Thu 10:00 · full, 2 waiting
Waitlist
Glaze night
Fri 19:00 · 5 seats left
Book
Plan · data model
5 tables · 4 relations
classes
id
uuid · pk
title
text
starts_at
timestamp
capacity
int · 8
seats
id
uuid · pk
class_id
→ classes
number
int
held_until
timestamp
bookings
id
uuid · pk
seat_id
→ seats
user_id
→ users
status
enum
users
id
uuid · pk
text
name
text
stripe_id
text
payments
id
uuid · pk
booking_id
→ bookings
deposit
int · £10
stripe_ref
text
relations
seats
→ classes
bookings
→ seats
bookings
→ users
payments
→ bookings
// app/bookings/actions.ts
export async function bookSeat(classId: string) {
const user = await auth.require()
const cls = await db.classes.find(classId)
if (cls.seatsLeft === 0) return waitlist(user, cls)
const deposit = await stripe.checkout({
amount: cls.depositCents,
customer: user.stripeId,
})
await db.bookings.create({ user, cls, deposit })
await email.schedule(“reminder”, cls.startsAt - DAY)
}
Version history
14 versions
Added a waitlist when a class is full
v14 · bookings · 2 min ago
Current
Reminder email the day before
v13 · emails · 14 min ago
Restore
Stripe deposits, £10 per seat
v12 · payments · 31 min ago
Restore
First version: classes and bookings
v11 · setup · 48 min ago
Restore
Restoring makes a new version. Nothing gets thrown away.
● LIVE
Deployed in 41s · v14
✓
Domain connected
dns ok
✓
SSL issued
auto-renews
✓
Database ready
eu-west
✓
Preview link ready
v14
Preview
Code
Versions
Deploy
Clay & Co. Studio
Wheel throwing, hand building and glazing. Small classes, muddy hands.
Wheel basics
Tue 18:30 · 3 seats left
Book
Hand building
Thu 10:00 · full, 2 waiting
Waitlist
Glaze night
Fri 19:00 · 5 seats left
Book
Plan · data model
5 tables · 4 relations
classes
id
uuid · pk
title
text
starts_at
timestamp
capacity
int · 8
seats
id
uuid · pk
class_id
→ classes
number
int
held_until
timestamp
bookings
id
uuid · pk
seat_id
→ seats
user_id
→ users
status
enum
users
id
uuid · pk
text
name
text
stripe_id
text
payments
id
uuid · pk
booking_id
→ bookings
deposit
int · £10
stripe_ref
text
relations
seats
→ classes
bookings
→ seats
bookings
→ users
payments
→ bookings
// app/bookings/actions.ts
export async function bookSeat(classId: string) {
const user = await auth.require()
const cls = await db.classes.find(classId)
if (cls.seatsLeft === 0) return waitlist(user, cls)
const deposit = await stripe.checkout({
amount: cls.depositCents,
customer: user.stripeId,
})
await db.bookings.create({ user, cls, deposit })
await email.schedule(“reminder”, cls.startsAt - DAY)
}
Version history
14 versions
Added a waitlist when a class is full
v14 · bookings · 2 min ago
Current
Reminder email the day before
v13 · emails · 14 min ago
Restore
Stripe deposits, £10 per seat
v12 · payments · 31 min ago
Restore
First version: classes and bookings
v11 · setup · 48 min ago
Restore
Restoring makes a new version. Nothing gets thrown away.
● LIVE
Deployed in 41s · v14
✓
Domain connected
dns ok
✓
SSL issued
auto-renews
✓
Database ready
eu-west
✓
Preview link ready
v14
versions
Every change is a version you can restore.
Plain-language notes for each change, grouped by feature. One click takes you back to how things were at lunchtime.
YUZU · clay-studio
A booking app for my pottery studio. Weekly classes, 8 seats each, Stripe deposits, and a reminder email the day before.
[✓] Read the prompt
[✓] Planned 5 tables: classes, seats, bookings…
[✓] Set up auth with magic links
[✓] Connected Stripe (test mode)
[✓] Wrote 23 files
[✓] Saved version 14
Ask for a change…
Preview
Code
Versions
Deploy
clay-studio.yuzu.app
Clay & Co. Studio
Wheel throwing, hand building and glazing. Small classes, muddy hands.
Wheel basics
Tue 18:30 · 3 seats left
Book
Hand building
Thu 10:00 · full, 2 waiting
Waitlist
Glaze night
Fri 19:00 · 5 seats left
Book
Plan · data model
5 tables · 4 relations
classes
id
uuid · pk
title
text
starts_at
timestamp
capacity
int · 8
seats
id
uuid · pk
class_id
→ classes
number
int
held_until
timestamp
bookings
id
uuid · pk
seat_id
→ seats
user_id
→ users
status
enum
users
id
uuid · pk
text
name
text
stripe_id
text
payments
id
uuid · pk
booking_id
→ bookings
deposit
int · £10
stripe_ref
text
relations
seats
→ classes
bookings
→ seats
bookings
→ users
payments
→ bookings
// app/bookings/actions.ts
export async function bookSeat(classId: string) {
const user = await auth.require()
const cls = await db.classes.find(classId)
if (cls.seatsLeft === 0) return waitlist(user, cls)
const deposit = await stripe.checkout({
amount: cls.depositCents,
customer: user.stripeId,
})
await db.bookings.create({ user, cls, deposit })
await email.schedule(“reminder”, cls.startsAt - DAY)
}
Version history
14 versions
Added a waitlist when a class is full
v14 · bookings · 2 min ago
Current
Reminder email the day before
v13 · emails · 14 min ago
Restore
Stripe deposits, £10 per seat
v12 · payments · 31 min ago
Restore
First version: classes and bookings
v11 · setup · 48 min ago
Restore
Restoring makes a new version. Nothing gets thrown away.
● LIVE
Deployed in 41s · v14
✓
Domain connected
dns ok
✓
SSL issued
auto-renews
✓
Database ready
eu-west
✓
Preview link ready
v14
Preview
Code
Versions
Deploy
clay-studio.yuzu.app
Clay & Co. Studio
Wheel throwing, hand building and glazing. Small classes, muddy hands.
Wheel basics
Tue 18:30 · 3 seats left
Book
Hand building
Thu 10:00 · full, 2 waiting
Waitlist
Glaze night
Fri 19:00 · 5 seats left
Book
Plan · data model
5 tables · 4 relations
classes
id
uuid · pk
title
text
starts_at
timestamp
capacity
int · 8
seats
id
uuid · pk
class_id
→ classes
number
int
held_until
timestamp
bookings
id
uuid · pk
seat_id
→ seats
user_id
→ users
status
enum
users
id
uuid · pk
text
name
text
stripe_id
text
payments
id
uuid · pk
booking_id
→ bookings
deposit
int · £10
stripe_ref
text
relations
seats
→ classes
bookings
→ seats
bookings
→ users
payments
→ bookings
// app/bookings/actions.ts
export async function bookSeat(classId: string) {
const user = await auth.require()
const cls = await db.classes.find(classId)
if (cls.seatsLeft === 0) return waitlist(user, cls)
const deposit = await stripe.checkout({
amount: cls.depositCents,
customer: user.stripeId,
})
await db.bookings.create({ user, cls, deposit })
await email.schedule(“reminder”, cls.startsAt - DAY)
}
Version history
14 versions
Added a waitlist when a class is full
v14 · bookings · 2 min ago
Current
Reminder email the day before
v13 · emails · 14 min ago
Restore
Stripe deposits, £10 per seat
v12 · payments · 31 min ago
Restore
First version: classes and bookings
v11 · setup · 48 min ago
Restore
Restoring makes a new version. Nothing gets thrown away.
● LIVE
Deployed in 41s · v14
✓
Domain connected
dns ok
✓
SSL issued
auto-renews
✓
Database ready
eu-west
✓
Preview link ready
v14
Preview
Code
Versions
Deploy
Clay & Co. Studio
Wheel throwing, hand building and glazing. Small classes, muddy hands.
Wheel basics
Tue 18:30 · 3 seats left
Book
Hand building
Thu 10:00 · full, 2 waiting
Waitlist
Glaze night
Fri 19:00 · 5 seats left
Book
Plan · data model
5 tables · 4 relations
classes
id
uuid · pk
title
text
starts_at
timestamp
capacity
int · 8
seats
id
uuid · pk
class_id
→ classes
number
int
held_until
timestamp
bookings
id
uuid · pk
seat_id
→ seats
user_id
→ users
status
enum
users
id
uuid · pk
text
name
text
stripe_id
text
payments
id
uuid · pk
booking_id
→ bookings
deposit
int · £10
stripe_ref
text
relations
seats
→ classes
bookings
→ seats
bookings
→ users
payments
→ bookings
// app/bookings/actions.ts
export async function bookSeat(classId: string) {
const user = await auth.require()
const cls = await db.classes.find(classId)
if (cls.seatsLeft === 0) return waitlist(user, cls)
const deposit = await stripe.checkout({
amount: cls.depositCents,
customer: user.stripeId,
})
await db.bookings.create({ user, cls, deposit })
await email.schedule(“reminder”, cls.startsAt - DAY)
}
Version history
14 versions
Added a waitlist when a class is full
v14 · bookings · 2 min ago
Current
Reminder email the day before
v13 · emails · 14 min ago
Restore
Stripe deposits, £10 per seat
v12 · payments · 31 min ago
Restore
First version: classes and bookings
v11 · setup · 48 min ago
Restore
Restoring makes a new version. Nothing gets thrown away.
● LIVE
Deployed in 41s · v14
✓
Domain connected
dns ok
✓
SSL issued
auto-renews
✓
Database ready
eu-west
✓
Preview link ready
v14
deploy
Live on your domain in under a minute.
SSL, redirects and a database in the region you pick. Preview links for every version, so you can show people before you ship.
YUZU · clay-studio
A booking app for my pottery studio. Weekly classes, 8 seats each, Stripe deposits, and a reminder email the day before.
[✓] Read the prompt
[✓] Planned 5 tables: classes, seats, bookings…
[✓] Set up auth with magic links
[✓] Connected Stripe (test mode)
[✓] Wrote 23 files
[✓] Deployed to clayandco.studio
Done. Go make a cup of tea anyway.
Ask for a change…
Preview
Code
Versions
Deploy
clay-studio.yuzu.app
Clay & Co. Studio
Wheel throwing, hand building and glazing. Small classes, muddy hands.
Wheel basics
Tue 18:30 · 3 seats left
Book
Hand building
Thu 10:00 · full, 2 waiting
Waitlist
Glaze night
Fri 19:00 · 5 seats left
Book
Plan · data model
5 tables · 4 relations
classes
id
uuid · pk
title
text
starts_at
timestamp
capacity
int · 8
seats
id
uuid · pk
class_id
→ classes
number
int
held_until
timestamp
bookings
id
uuid · pk
seat_id
→ seats
user_id
→ users
status
enum
users
id
uuid · pk
text
name
text
stripe_id
text
payments
id
uuid · pk
booking_id
→ bookings
deposit
int · £10
stripe_ref
text
relations
seats
→ classes
bookings
→ seats
bookings
→ users
payments
→ bookings
// app/bookings/actions.ts
export async function bookSeat(classId: string) {
const user = await auth.require()
const cls = await db.classes.find(classId)
if (cls.seatsLeft === 0) return waitlist(user, cls)
const deposit = await stripe.checkout({
amount: cls.depositCents,
customer: user.stripeId,
})
await db.bookings.create({ user, cls, deposit })
await email.schedule(“reminder”, cls.startsAt - DAY)
}
Version history
14 versions
Added a waitlist when a class is full
v14 · bookings · 2 min ago
Current
Reminder email the day before
v13 · emails · 14 min ago
Restore
Stripe deposits, £10 per seat
v12 · payments · 31 min ago
Restore
First version: classes and bookings
v11 · setup · 48 min ago
Restore
Restoring makes a new version. Nothing gets thrown away.
● LIVE
Deployed in 41s · v14
✓
Domain connected
dns ok
✓
SSL issued
auto-renews
✓
Database ready
eu-west
✓
Preview link ready
v14
Preview
Code
Versions
Deploy
clay-studio.yuzu.app
Clay & Co. Studio
Wheel throwing, hand building and glazing. Small classes, muddy hands.
Wheel basics
Tue 18:30 · 3 seats left
Book
Hand building
Thu 10:00 · full, 2 waiting
Waitlist
Glaze night
Fri 19:00 · 5 seats left
Book
Plan · data model
5 tables · 4 relations
classes
id
uuid · pk
title
text
starts_at
timestamp
capacity
int · 8
seats
id
uuid · pk
class_id
→ classes
number
int
held_until
timestamp
bookings
id
uuid · pk
seat_id
→ seats
user_id
→ users
status
enum
users
id
uuid · pk
text
name
text
stripe_id
text
payments
id
uuid · pk
booking_id
→ bookings
deposit
int · £10
stripe_ref
text
relations
seats
→ classes
bookings
→ seats
bookings
→ users
payments
→ bookings
// app/bookings/actions.ts
export async function bookSeat(classId: string) {
const user = await auth.require()
const cls = await db.classes.find(classId)
if (cls.seatsLeft === 0) return waitlist(user, cls)
const deposit = await stripe.checkout({
amount: cls.depositCents,
customer: user.stripeId,
})
await db.bookings.create({ user, cls, deposit })
await email.schedule(“reminder”, cls.startsAt - DAY)
}
Version history
14 versions
Added a waitlist when a class is full
v14 · bookings · 2 min ago
Current
Reminder email the day before
v13 · emails · 14 min ago
Restore
Stripe deposits, £10 per seat
v12 · payments · 31 min ago
Restore
First version: classes and bookings
v11 · setup · 48 min ago
Restore
Restoring makes a new version. Nothing gets thrown away.
● LIVE
Deployed in 41s · v14
✓
Domain connected
dns ok
✓
SSL issued
auto-renews
✓
Database ready
eu-west
✓
Preview link ready
v14
Preview
Code
Versions
Deploy
Clay & Co. Studio
Wheel throwing, hand building and glazing. Small classes, muddy hands.
Wheel basics
Tue 18:30 · 3 seats left
Book
Hand building
Thu 10:00 · full, 2 waiting
Waitlist
Glaze night
Fri 19:00 · 5 seats left
Book
Plan · data model
5 tables · 4 relations
classes
id
uuid · pk
title
text
starts_at
timestamp
capacity
int · 8
seats
id
uuid · pk
class_id
→ classes
number
int
held_until
timestamp
bookings
id
uuid · pk
seat_id
→ seats
user_id
→ users
status
enum
users
id
uuid · pk
text
name
text
stripe_id
text
payments
id
uuid · pk
booking_id
→ bookings
deposit
int · £10
stripe_ref
text
relations
seats
→ classes
bookings
→ seats
bookings
→ users
payments
→ bookings
// app/bookings/actions.ts
export async function bookSeat(classId: string) {
const user = await auth.require()
const cls = await db.classes.find(classId)
if (cls.seatsLeft === 0) return waitlist(user, cls)
const deposit = await stripe.checkout({
amount: cls.depositCents,
customer: user.stripeId,
})
await db.bookings.create({ user, cls, deposit })
await email.schedule(“reminder”, cls.startsAt - DAY)
}
Version history
14 versions
Added a waitlist when a class is full
v14 · bookings · 2 min ago
Current
Reminder email the day before
v13 · emails · 14 min ago
Restore
Stripe deposits, £10 per seat
v12 · payments · 31 min ago
Restore
First version: classes and bookings
v11 · setup · 48 min ago
Restore
Restoring makes a new version. Nothing gets thrown away.
● LIVE
Deployed in 41s · v14
✓
Domain connected
dns ok
✓
SSL issued
auto-renews
✓
Database ready
eu-west
✓
Preview link ready
v14
Works with the tools you already pay for.
Supabase, Stripe, GitHub, Resend and a dozen more. Connect once, Yuzu wires them in.