/how-to-build-lovable

How to build Recipe app with Lovable?

Step-by-step guide to build a feature-rich Recipe app with Lovable, covering design, data storage, search, user profiles and deployment tips plus.

Book a free  consultation
4.9
Clutch rating 🌟
600+
Happy partners
17+
Countries served
190+
Team members
Matt Graham, CEO of Rapid Developers

Book a call with an Expert

Starting a new venture? Need to upgrade your web app? RapidDev builds application with your growth in mind.

Book a free No-Code consultation

How to build Recipe app with Lovable?

You can build a simple Recipe CRUD app fully inside Lovable using Chat Mode edits, Preview, and Publish. I recommend a front-end React app that uses Supabase (client-only) for storage; configure Supabase keys in Lovable Cloud Secrets. You’ll never run a terminal inside Lovable — use Chat Mode to create files, Preview to test, and Publish (or GitHub sync) to deploy. Below are exact Lovable prompts to paste into Chat Mode so Lovable edits files and wiring for you.

 

What we’re building / changing (plain English)

 

A small single-page React app (src/) that lists recipes, lets you add/edit/delete recipes, and stores data in Supabase. Front-end only: the Supabase JS client talks directly to your database using keys stored in Lovable Secrets.

 

Lovable-native approach

 

We will use Chat Mode to create files and edits, Preview to run the app in the Lovable preview environment, Lovable Cloud Secrets UI to add SUPABASE_URL and SUPABASE_ANON\_KEY, and Publish to publish the site. No terminal needed. If you want server-side functions or to run migrations, you’ll use GitHub export/sync and run CLI outside Lovable (instructions flagged as outside Lovable).

 

Meta-prompts to paste into Lovable

 

Prompt 1 — Scaffold app and basic UI

Goal: Create a minimal React app that shows a recipe list and a form to add recipes.

Files to create/modify:

  • create index.html at root
  • create src/main.jsx
  • create src/App.jsx
  • create src/components/RecipeList.jsx
  • create src/components/RecipeForm.jsx
  • create package.json (minimal for Preview)

Acceptance criteria (done when…): App loads in Preview and shows a static “No recipes yet” message and an input form that accepts name & description and calls a placeholder addRecipe function.

Secrets/integrations: none yet.

Prompt text to paste into Chat Mode:

// Create files for a minimal React SPA
// index.html
// // minimal HTML with a div#root and script to load /src/main.jsx (Lovable Preview will serve it)
create file index.html with content:
<!doctype html>
<html>
  <head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Recipes</title></head>
  <body><div id="root"></div><script type="module" src="/src/main.jsx"></script></body>
</html>

// src/main.jsx
create file src/main.jsx with content:
// bootstraps React
import React from 'react';
import { createRoot } from 'react-dom/client';
import App from './App.jsx';
const root = createRoot(document.getElementById('root'));
root.render(<App />);

// src/App.jsx
create file src/App.jsx with content:
import React, { useState } from 'react';
import RecipeList from './components/RecipeList.jsx';
import RecipeForm from './components/RecipeForm.jsx';
export default function App(){
  const [recipes, setRecipes] = useState([]);
  function addRecipe(r){ setRecipes([r, ...recipes]); }
  return (
    <div style={{padding:20,fontFamily:'sans-serif'}}>
      <h1>Recipes</h1>
      <RecipeForm onAdd={addRecipe}/>
      <RecipeList recipes={recipes}/>
    </div>
  );
}

// src/components/RecipeForm.jsx
create file src/components/RecipeForm.jsx with content:
import React, {useState} from 'react';
export default function RecipeForm({onAdd}){
  const [name,setName]=useState('');
  const [desc,setDesc]=useState('');
  function submit(e){ e.preventDefault(); if(!name) return; onAdd({id:Date.now(),name,desc}); setName(''); setDesc(''); }
  return (
    <form onSubmit={submit} style={{marginBottom:20}}>
      <input placeholder="Recipe name" value={name} onChange={e=>setName(e.target.value)} />
      <input placeholder="Description" value={desc} onChange={e=>setDesc(e.target.value)} />
      <button type="submit">Add</button>
    </form>
  );
}

// src/components/RecipeList.jsx
create file src/components/RecipeList.jsx with content:
import React from 'react';
export default function RecipeList({recipes}){
  if(recipes.length===0) return <div>No recipes yet</div>;
  return (
    <ul>
      {recipes.map(r=>(
        <li key={r.id}><strong>{r.name}</strong>: {r.desc}</li>
      ))}
    </ul>
  );
}

// package.json
create file package.json with content:
{
  "name":"lovable-recipes",
  "private":true,
  "type":"module"
}

 

Prompt 2 — Add Supabase client wiring & Secrets

Goal: Wire Supabase client and replace the in-memory add/list with Supabase calls. Create a small data adapter file that reads environment from Lovable Secrets.

Files to modify/create:

  • modify src/App.jsx to load data from src/supabase/client.js and call real CRUD functions
  • create src/supabase/client.js

Acceptance criteria: Preview shows recipes fetched from Supabase (or empty list). Adding via form inserts into Supabase and appears in the list.

Secrets/integrations: Add two Secrets in Lovable Cloud Secrets UI: SUPABASE_URL and SUPABASE_ANON\_KEY.

Prompt text to paste into Chat Mode:

// Add Supabase client adapter and wire App to use it
// src/supabase/client.js
create file src/supabase/client.js with content:
// load keys from environment (Lovable Secrets will map to process.env)
import { createClient } from 'https://cdn.jsdelivr.net/npm/@supabase/supabase-js/+esm';
const url = process.env.SUPABASE_URL;
const key = process.env.SUPABASE_ANON_KEY;
if(!url || !key) {
  console.warn('Supabase keys missing. Add SUPABASE_URL and SUPABASE_ANON_KEY in Lovable Secrets.');
}
export const supabase = createClient(url || '', key || '');
export async function listRecipes(){
  const { data, error } = await supabase.from('recipes').select('*').order('id',{ascending:false});
  if(error) throw error;
  return data || [];
}
export async function insertRecipe(r){
  const { data, error } = await supabase.from('recipes').insert([{name:r.name,description:r.desc}]).select();
  if(error) throw error;
  return data[0];
}

// modify src/App.jsx to use these functions
update src/App.jsx replacing content with:
import React, { useEffect, useState } from 'react';
import RecipeList from './components/RecipeList.jsx';
import RecipeForm from './components/RecipeForm.jsx';
import { listRecipes, insertRecipe } from './supabase/client.js';
export default function App(){
  const [recipes, setRecipes] = useState([]);
  useEffect(()=>{ (async()=>{ try{ const rows = await listRecipes(); setRecipes(rows); }catch(e){ console.error(e); } })(); },[]);
  async function addRecipe(r){
    try{ const created = await insertRecipe(r); setRecipes([created, ...recipes]); }catch(e){ console.error(e); }
  }
  return (
    <div style={{padding:20,fontFamily:'sans-serif'}}>
      <h1>Recipes</h1>
      <RecipeForm onAdd={addRecipe}/>
      <RecipeList recipes={recipes}/>
    </div>
  );
}

 

Prompt 3 — Secrets setup instructions (Manual step in Lovable UI)

Goal: Add Supabase keys to Lovable Cloud Secrets so the Preview environment has them.

Files: none.

Acceptance criteria: process.env.SUPABASE_URL and process.env.SUPABASE_ANON\_KEY are available in Preview and Console logs show client initialized.

Secrets setup steps (to perform in Lovable Cloud UI):

  • Open Lovable Cloud Secrets
  • Create a secret named SUPABASE\_URL with your project URL
  • Create a secret named SUPABASE_ANON_KEY with your anon key

Prompt text to paste into Chat Mode (to add a short README in repo reminding about Secrets):

// create README_SUPABASE.md
create file README_SUPABASE.md with content:
// Reminder: set these in Lovable Secrets
SUPABASE_URL — set in Lovable Cloud Secrets
SUPABASE_ANON_KEY — set in Lovable Cloud Secrets

```

 

How to verify in Lovable Preview

 

  • Open Preview; app should load. If you see a warning about missing Supabase keys, go add Secrets.
  • Add a recipe in the form. On success, it should appear in the list and persist after reload (reads from Supabase).
  • Check the Preview Console for network/errors if something fails.

 

How to Publish / re-publish

 

  • Use Lovable Publish button to publish the site. Publish uses the same Secrets you set in Lovable Cloud.
  • If you want to deploy via GitHub or configure migrations, use Lovable’s GitHub sync/export and follow outside-Lovable CLI steps (labelled when necessary).

 

Common pitfalls in Lovable (and how to avoid them)

 

  • Missing Secrets: Preview will run but Supabase calls will fail. Add SUPABASE_URL and SUPABASE_ANON\_KEY in Lovable Secrets UI.
  • Database table missing: Ensure you created a recipes table (id serial, name text, description text). Creating tables requires Supabase UI or CLI outside Lovable.
  • Assuming a terminal: You can’t run migrations inside Lovable. If you need to run SQL or migrations, export to GitHub and run psql/supabase CLI outside Lovable (this is outside Lovable — do it locally or CI).
  • Third-party CDN modules: We used the ESM CDN import for @supabase/supabase-js to avoid a build step inside Lovable Preview. If you switch to a bundler, move to npm and GitHub sync.

 

Validity bar

 

This workflow uses only Lovable Chat Mode edits, Preview, Publish, and the Lovable Cloud Secrets UI. Anything requiring terminal work (database creation/migrations or custom build pipelines) must be handled via GitHub export/sync and executed outside Lovable; I flagged those steps above.

Want to explore opportunities to work with us?

Connect with our team to unlock the full potential of no-code solutions with a no-commitment consultation!

Book a Free Consultation

How to enrich recipe nutrition with Lovable

This prompt helps an AI assistant understand your setup and guide to build the feature

AI AI Prompt

How to add ingredient substitution suggestions

This prompt helps an AI assistant understand your setup and guide to build the feature

AI AI Prompt

How to add Recipe Versioning & Undo in Lovable

This prompt helps an AI assistant understand your setup and guide to build the feature

AI AI Prompt

Want to explore opportunities to work with us?

Connect with our team to unlock the full potential of no-code solutions with a no-commitment consultation!

Book a Free Consultation
Matt Graham, CEO of Rapid Developers

Book a call with an Expert

Starting a new venture? Need to upgrade your web app? RapidDev builds application with your growth in mind.

Book a free No-Code consultation

Best Practices for Building a Recipe app with AI Code Generators

A recipe app built with Lovable should be organized for iterative, chat-driven edits: keep backend integrations (Supabase or similar) behind Secrets, use Lovable's Preview to validate UI changes, and export to GitHub only when you need CLI-level work (migrations, custom builds). Use small, focused AI code-generator prompts to produce components and API routes, always run them in Preview, and push to GitHub for anything requiring terminal commands.

 

Project Architecture & Planning

 

  • Keep concerns separate: UI (React components), API routes (server functions), and data (Supabase tables) — this makes AI code generation targets small and testable.
  • Decide where logic lives: Put auth and DB queries server-side (API route) so you can hide keys in Lovable Secrets.
  • Start with minimal schema: recipes(id, title, ingredients JSON, steps, owner_id, public_flag) — iterate as you preview.

 

Using Lovable-native workflow

 

  • Chat Mode edits and patches: Ask the AI to create or modify single files (component or API route). Keep diffs small so Preview highlights exact changes.
  • Preview: Use it constantly. Preview is your local runtime — test endpoints and components here before publishing.
  • Secrets UI: Store SUPABASE_URL and SUPABASE_KEY here. Never hardcode keys in files.
  • Publish / GitHub sync: Export only when you must run DB migrations or CI jobs outside Lovable.

 

Supabase integration & migrations

 

  • Create tables in Supabase UI (since Lovable has no CLI). Use Supabase SQL editor for migrations and keep SQL files in repo for tracking.
  • Use Secrets for credentials and initialize the client in server code.

 

// server/api/getRecipes.js
import { createClient } from '@supabase/supabase-js'

// initialize from Lovable Secrets mapped to process.env
const supabase = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_KEY)

export default async function handler(req, res) {
  // GET /api/getRecipes
  const { data, error } = await supabase.from('recipes').select('*')
  if (error) return res.status(500).json({ error: error.message })
  res.status(200).json(data)
}

 

AI Code Generator best practices

 

  • Prompt narrowly: Ask for one component or route. Provide props/types and sample data.
  • Include tests or examples: Ask the generator to include a small usage snippet you can paste into Preview.
  • Iterate: Apply patches, run Preview, then refine — avoid big, multi-file rewrites in one go.

 

Security, Performance, and UX

 

  • Auth: Use Supabase auth server-side or pass JWTs from client to API routes, stored in Secrets during server use.
  • Rate-limits & validation: Validate recipe payloads server-side to avoid malformed data.
  • Optimizations: Paginate recipe lists, store ingredients as normalized JSON for fast queries.

 

When to sync to GitHub

 

  • Need migrations, CI, or custom builds — export to GitHub and run scripts externally (Supabase migrations, npm build).
  • Keep SQL migration files in repo so your production DB can be reproduced from GitHub CI.


Recognized by the best

Trusted by 600+ businesses globally

From startups to enterprises and everything in between, see for yourself our incredible impact.

RapidDev was an exceptional project management organization and the best development collaborators I've had the pleasure of working with.

They do complex work on extremely fast timelines and effectively manage the testing and pre-launch process to deliver the best possible product. I'm extremely impressed with their execution ability.

Arkady
CPO, Praction
Working with Matt was comparable to having another co-founder on the team, but without the commitment or cost.

He has a strategic mindset and willing to change the scope of the project in real time based on the needs of the client. A true strategic thought partner!

Donald Muir
Co-Founder, Arc
RapidDev are 10/10, excellent communicators - the best I've ever encountered in the tech dev space.

They always go the extra mile, they genuinely care, they respond quickly, they're flexible, adaptable and their enthusiasm is amazing.

Mat Westergreen-Thorne
Co-CEO, Grantify
RapidDev is an excellent developer for custom-code solutions.

We’ve had great success since launching the platform in November 2023. In a few months, we’ve gained over 1,000 new active users. We’ve also secured several dozen bookings on the platform and seen about 70% new user month-over-month growth since the launch.

Emmanuel Brown
Co-Founder, Church Real Estate Marketplace
Matt’s dedication to executing our vision and his commitment to the project deadline were impressive. 

This was such a specific project, and Matt really delivered. We worked with a really fast turnaround, and he always delivered. The site was a perfect prop for us!

Samantha Fekete
Production Manager, Media Production Company
The pSEO strategy executed by RapidDev is clearly driving meaningful results.

Working with RapidDev has delivered measurable, year-over-year growth. Comparing the same period, clicks increased by 129%, impressions grew by 196%, and average position improved by 14.6%. Most importantly, qualified contact form submissions rose 350%, excluding spam.

Appreciation as well to Matt Graham for championing the collaboration!

Michael W. Hammond
Principal Owner, OCD Tech

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We’ll discuss your project and provide a custom quote at no cost.