Using Lovable with Claude Code or Codex, without the merge hell
Using Lovable with Claude Code or Codex: wire up git sync, clone locally, and adopt the branch discipline that stops two agents fighting over one branch.
11 min read
Keep Lovable for the things it is genuinely fast at (scaffolding, UI iteration against a live preview, and its managed backend wiring) and do the bulk code work against the Claude Code or Codex subscription you are already paying for. Git sync is the bridge. It is two-way, which is the good news, and it carries exactly one branch, which is the reason most people who try this end up in merge hell within a fortnight.
This is the setup, then the hazards. The hazards are the useful part.
The short version
| Do it in Lovable | Do it in Claude Code / Codex | |
|---|---|---|
| First version of a screen | Yes: live preview is the whole point | No |
| Nudging spacing, copy, a button style | Yes, if it’s one or two things | Yes, if it’s twenty things |
| Backend wiring (auth, tables, storage, edge functions) | Yes: the Cloud editor is right there | Only if you’ve left Cloud |
| Bulk refactor across 40 files | No | Yes |
| Test suite | No | Yes |
| Twenty near-identical content pages | No | Yes |
| Chasing a bug it already failed to fix twice | No | Yes |
| Publishing and hosting | Yes: publishing only happens in Lovable | No |
Two facts back up that table. Credits are billed per message, however many files it touches. Lovable’s credits docs put a typical Build-mode message at roughly 0.50 to 2.00+ credits and Plan-mode messages at 1 credit each plus any research the agent does on top, so twenty small requests cost twenty charges while one well-scoped local session costs nothing extra. And a local agent reads the whole repository at once, which is exactly the view Lovable’s chat does not give you when a bug spans several files.
If you want the wider map of how Lovable connects to outside tools, start with the Lovable integrations overview. This post is only about the code loop.
Step 1: connect git sync (the button is “Connect”)
Inside Lovable, the action is Connect, and the git sync docs describe it as “export and two-way sync”. There is no “Export to GitHub” button, if a tutorial tells you to click one, it was written from memory. First-time setup on github.com adds an account, opens a GitHub popup, lets you choose the account or organization and whether to grant all repositories or selected ones, then installs and authorizes. Lovable registers that as a reusable workspace connection.
Three things to get right before you click, because two of them are effectively permanent:
- Pick the final owner now. Connecting always creates a new repository: importing an existing repo is explicitly unsupported on GitHub, GitLab and Bitbucket Cloud alike. So the org you connect to is the org you’re stuck with.
- Know what breaks it. Renaming the repository is safe; Lovable detects the rename and updates the connection. Transferring the repo to another owner or organization breaks sync and needs a support ticket to re-attach. Renaming your GitHub username or organization breaks the connection entirely, and reverting the name restores it. Deleting the repo breaks the connection, and restoring it on GitHub resumes syncing.
- Disconnect is not a reset. Reconnecting to the same repository after disconnecting is on the unsupported list: Lovable creates a new repo with the current project state, orphaning the original and its history.
The GitHub App requests Contents (write), Metadata (read), Pull requests (write), Workflows (write) and Administration (write). Administration:write is what lets it create repositories; if you’re installing this into a company org, that is the permission your security reviewer will ask about. Commits arrive authored by lovable-dev[bot] and co-attributed to whoever triggered the sync, so git blame stays readable.
Step 2: clone it and find out which stack you’re on
Before you write anything, establish which of the two Lovable stacks you have. On 13 May 2026 Lovable changed the default for new projects from React + Vite to TanStack Start with SSR on Cloudflare Workers. Existing projects were not migrated.
git clone git@github.com:<you>/<your-lovable-repo>.git
cd <your-lovable-repo>
# Which stack?
grep -E '"(@tanstack/react-start|@tanstack/react-router|react-router-dom)"' package.json
@tanstack/react-start means the new stack. Lovable’s docs say every request returns fully rendered HTML. In practice Lovable’s generated pages still query Cloud or Supabase from a hook after hydration, so your shell is in the response and your data usually is not. Check a page with dynamically loaded content (CMS posts, product pages, directory listings: anything that isn’t written into the page’s source code), never the homepage:
curl -sS https://yourdomain.com/products | grep -c 'product-card'
# Compare that against what you count in the browser. A gap is the whole problem.
react-router-dom alone means you’re on the older client-rendered stack, where Lovable serves on-request pre-rendered HTML to verified crawlers only, on its own deployed URLs. Either way, that difference decides how the content pages you’re about to generate get seen.
Then get it running. On the Vite branch, client-side environment variables must carry the VITE_ prefix or they never reach the browser: an unprefixed variable produces a silent blank screen rather than an error. The generated Supabase client typically expects a URL, a publishable key and a project id in that prefixed form; copy the exact names out of the client file rather than guessing.
npm install
npm run dev
# 'vite: not found' after a clone is almost always a stale/partial install:
rm -rf node_modules package-lock.json && npm install
Step 3: brief the agent once, properly
Both Claude Code and Codex read a repo-level instructions file (CLAUDE.md and AGENTS.md respectively; keeping one and symlinking the other works fine). Write it once and you stop re-explaining the same constraints every session. The four things worth putting in it:
## Stack
TypeScript, Tailwind CSS, shadcn/ui. Router: TanStack Router (SSR): check
package.json before assuming. This repo is synced two-way with Lovable.
## Branch rule
`main` is Lovable's branch. Never commit to it. Work on `local/<task>`,
open a PR, and let a human merge while Lovable is idle.
## Don't touch
- Existing migration files. Write new ones.
- Lovable's generated backend client file.
- package.json dependency bumps unless the task is a dependency bump.
## House style
Match the existing shadcn/ui component usage. No new UI libraries.
The “don’t touch” list is not bureaucracy. Overlapping edits between the two agents cluster in a predictable set of files (package.json, route files, generated components and configuration) so telling the local agent to stay out of them removes most conflicts before they exist.
Branch discipline, which is the whole ball game
Here is the constraint everything else follows from: Lovable edits and syncs one branch at a time, by default the repository’s default branch, and only the synced branch flows back into Lovable. You can switch branches or create new ones from Lovable’s branch picker, but not while Lovable is actively editing the project, and a new branch is cut from the currently active branch.
So if Lovable and your local agent both commit to main, you have two independent writers on one branch with no coordination and no locking. That is not a workflow, it is a queue of conflicts waiting for a week when you’re busy.
Pick one of these two disciplines and actually hold to it.
Discipline A: Lovable owns main (recommended)
Best when you’re still doing real UI work in Lovable.
# Start of every local session: no exceptions.
git checkout main
git fetch origin
git reset --hard origin/main # main is Lovable's; never keep local commits on it
git checkout -b local/pricing-pages
# ... Claude Code or Codex works here ...
git push -u origin local/pricing-pages
Then merge deliberately, in one direction, with Lovable idle:
# Confirm no Lovable message is mid-flight, then:
git checkout main
git pull --ff-only
git merge --no-ff local/pricing-pages
git push origin main # Lovable pulls this back into the project
git branch -d local/pricing-pages
The git reset --hard origin/main at the top is the important line. If you ever leave local commits sitting on main, the next Lovable push and your next git pull will collide on files neither side knows the other edited.
Discipline B: graduate the project
Best when Lovable has done its job and you mostly want the hosting.
Point Lovable’s branch picker at a dedicated branch (lovable/ui, say) and keep main as yours. Lovable then only ever writes to lovable/ui, you merge that into main when you want its work, and your local agent never has to care about timing. Remember the trap: create that branch from Lovable’s picker while the current branch is the one you actually want to fork from, because new branches are cut from the active branch.
One more coordination note: Lovable’s September 2026 changelog added Drafts (separate project copies for testing changes before merging into the main version) and follow-ups (sending messages while Lovable is still working). Both make it easier to have a Lovable message in flight when you thought the editor was idle. Check before you merge.
Pushing commits does not update your live site
This catches almost everyone once. Lovable’s git sync docs say plainly that publishing your site happens separately, and pushing commits doesn’t automatically update the live site. The hosting docs add that publishing creates a snapshot (changes made after publishing don’t reach the live site until you republish) and that the editor preview is not the published site. There is no separate staging environment; the flow is build, preview in the editor, publish.
So the end of your loop has four steps: merge, confirm Lovable picked up the change, check the preview, publish. Skip the fourth and you’ll spend an afternoon wondering why production still shows last week’s copy.
Moving your editing out does not zero your Lovable bill
Be honest with yourself about the money, because the popular version of this advice overstates the saving.
Lovable runs one credit pool across three kinds of usage:
- Build usage: messages you send to Lovable’s agent to plan, generate or edit the app.
- Cloud usage: database, network, storage, compute and realtime in your deployed app.
- AI Gateway usage: model calls your deployed app makes at runtime.
Working locally eliminates the first one. It does nothing at all to the second and third. A published app on Lovable Cloud with real traffic keeps drawing credits from the same pool on a month where you sent zero messages. The monthly grants are small and don’t roll over (20 Cloud credits and 4 AI credits a month, alongside 5 build credits a day) so a busy app sits on general credits or top-ups regardless of where you write code. Top-ups are $0.30 per credit on Pro and $0.60 on Business, as of September 2026; several third-party pricing posts quote $0.25 and $0.50, which contradicts Lovable’s own docs.
Cutting the Cloud line means leaving Cloud, and there is no one-click migration in either direction: the documented path to your own Supabase is manual, and it involves creating a new Lovable project rather than swapping the backend in place. Don’t assume that’s a weekend job. For in-platform savings that don’t require any of this, cutting Lovable credit burn is the cheaper first move.
Worked example: twenty content pages
This is the case where the split pays for itself in a single afternoon.
The Lovable way. Twenty messages, each one describing a page, each one re-establishing context, each one billed. At a typical 0.50–2.00+ credits per Build-mode message that’s a real number, and the failure mode is worse than the cost: by page twelve the agent has drifted from the template it used on page three, and you’re now sending correction messages that also cost credits.
Doing it locally. One session, one commit, no drift:
git checkout main && git fetch origin && git reset --hard origin/main
git checkout -b local/location-pages
claude # or: codex
Then a single brief, roughly:
Read
src/routes/solutions/crm.tsxand treat it as the template. Createsrc/data/locations.tsexporting an array of 20 objects withslug,city,headline,intro,faqs. Generate one route file per entry using the same layout and the same shadcn/ui components as the template, with a per-page title, meta description and canonical. Don’t touchpackage.json. Show me the data file first; I’ll edit the copy before you generate the routes.
That last sentence matters. Review the data file, fix the copy while it’s twenty rows in one file rather than twenty scattered components, then let the agent fan it out. Run the dev server, walk three of the pages, commit, push, merge, publish.
Two follow-ups specific to Lovable. First, per-route titles and descriptions are the thing Lovable most reliably gets wrong at volume, and generating them from a data file is how you avoid twenty pages sharing one meta description. Second, Lovable auto-generates sitemap.xml and robots.txt but its docs hedge that they’re “not always generated up front”, so after the merge, fetch your sitemap and confirm the twenty new URLs are actually in it (why Lovable sitemaps drift).
What about driving Lovable’s agent from Claude Code?
Lovable’s connector model has a documented place for MCP: chat connectors are MCP servers that give Lovable’s agent build-time context (for example Encited’s SEO MCP), and custom MCP servers can be added as user-provided tools. That direction, tools into Lovable’s chat, is the documented one, and it’s worth setting up if your agent needs to read your issue tracker or design system while it builds. Lovable MCP servers goes through it.
What it doesn’t change is the billing. Build usage is defined as sending messages to Lovable’s agent, so a message costs credits whichever surface you send it from. Only editing the synced repository directly is free of Build usage. If your reason for reaching for MCP is cost, the git loop is the answer instead.
One more rule worth adopting: the two-strike circuit breaker
When Lovable fails to fix a bug twice, stop paying it to guess. Switch to chat/plan mode and ask it to describe the symptom, the files involved and the fixes it has already tried. Copy that description into your local agent against the cloned repo, where it can read every file at once instead of guessing which three to open. A local agent with full repository context can find the repeated version of a bug (the same mistake made in several functions) that a chat-window agent keeps patching one instance at a time.
If you’re still deciding whether to run this split at all or move wholesale, Lovable vs Cursor frames the same decision from the other end.
What to do next
- Connect git sync to the account or organization that should own the repo permanently. You do not get a second chance at this one.
- Clone, run
grep -E '"(@tanstack/react-start|@tanstack/react-router|react-router-dom)"' package.json, and write down which stack you’re on. Then curl a page with dynamically loaded content and count what’s actually in the HTML: Lovable’s pre-rendering behavior explains what to do about the gap. - Get
npm run devworking and walk your three most important user flows locally before you change anything: running an exported Lovable app locally covers the rest of that first hour. - Write the
CLAUDE.md/AGENTS.mdfile with the branch rule in it. - Pick Discipline A or B and put the merge command sequence in that same file, so neither you nor the agent has to remember it.
- Run one low-stakes task end to end (merge, confirm in the editor, publish) before you trust the loop with anything that matters.
Frequently asked questions
- Does editing my Lovable project in Claude Code save credits?
- It removes one of three things credits pay for. Lovable's docs describe a single credit pool covering Build usage (messages you send to Lovable's agent), Cloud usage (database, network, storage, compute and realtime in your deployed app) and AI Gateway usage (model calls your deployed app makes at runtime). Working in a local agent removes Build usage only. A deployed app on Lovable Cloud keeps drawing from the same pool whether you send messages or not.
- Can I connect Lovable to a GitHub repo I already have?
- No. Lovable's GitHub docs list importing existing repositories as unsupported: you can only export from Lovable to GitHub, and connecting a project always creates a brand-new repository. There is no bring-your-own-repo path on GitHub, GitLab or Bitbucket Cloud, so plan to start the project in Lovable and let it create the repo.
- Will pushing commits to GitHub update my live Lovable site?
- No. Lovable's git sync docs state that publishing your site is a separate action and that pushing commits does not automatically update the live site. Publishing takes a snapshot, so anything you merge after that last publish sits in the editor preview until you publish again.
- How do I stop Lovable and Claude Code producing merge conflicts?
- Give each one its own branch and never let both write to the same one. Lovable edits and syncs exactly one branch at a time, and only that branch flows back into the editor. Keep local agent work on short-lived branches, merge into the synced branch in one direction while Lovable is idle, and pull before every local session.
- Where does my code go if Lovable's push fails?
- Lovable's GitHub docs note that when a push cannot be applied (because of branch protection or a conflict) Lovable pushes to a branch named lovable-sync instead. If work seems to have vanished from Lovable, check for that branch on the remote before assuming the change was lost.
- Do I need a paid Lovable plan to work on the code locally?
- Lovable's subscription docs state the Free plan has no code editing, no custom domains and no code downloads; code editing and code download start on Pro. The docs do not state whether git sync itself requires a paid plan. As of September 2026, check your own plan's feature list before planning a local editing loop around it.
Read next
Keep going
-
How to spend fewer credits on Lovable
Save Lovable credits by understanding what a credit actually buys: per-message billing, three kinds of usage in one pool, and the rollover rules.
-
Lovable GitHub sync: how it really works
Lovable GitHub sync is two-way but only one branch at a time, and it can never import an existing repo. Every rule, limit and failure mode.
-
Lovable vs Cursor: which to use when
Lovable vs Cursor decided on the axes that matter: what you're building, how you pay, who wires the backend, and how to run both on one repo safely.
-
Lovable MCP and chat connectors, explained
Lovable MCP servers are chat connectors: personal, build-time only, and they do not run in your published app. The six connector types, and what's worth wiring.