Replit's pricing is out of control. Vibe coders are paying $350 to use it for a single day. That's why this article will show you how to move your app from Replit to Gadget. This will slash your vibe coding bill and give you a better developer experience.
I have a little pushup tracking app that I built with Replit:
The app is so expensive to maintain, so I'm re-platforming it to Gadget.
The first step is to make a fresh app in Gadget, choosing the web app template:
"Single party auth" means users can only login via Google if I send them an email invite. I couldn't figure out how to do that in Replit. It's available out of box with Gadget.
After pressing "Continue", Gadget prompts you to pick the framework and language for your app. I kept the default framework and language since my Replit app is written in TypeScript.
The database is at the core of every app, so let's start by rebuilding my database. I only need to recreate he pushup_entries
table in Gadget. The user
table was generated by Gadget because I selected "Single party auth" during setup.
I clone the pushup_entries
table in Gadget (I renamed it to pushup
), adding the date
and count
fields. No sweat.
We can associate users with their pushups by creating a "belongs to" relationship:
The Gadget database still doesn't have any data though. Let's get the data that's in Replit over to our new Gadget database. First, export the Replit data as JSON:
Next, select the create.js
action and select "Run action". This will allow us to use the Node.js API that Gadget auto-generates to write to Gadget's database.
In the API playground, paste the JSON data you copied from Replit, and assign that JSON blob to a constant. I called my JSON blob pushups
. Next, loop through the JSON blob, writing each entry to the database using the API that Gadget generates for each data model. You can just copy this code and replace my JSON blob with the one you got from your Replit database:
const pushups = [
{
"id": 1,
"count": 20,
"date": "2025-07-07T21:01:15.000Z",
"notes": null
},
{
"id": 2,
"count": 15,
"date": "2025-07-07T00:53:00.000Z",
"notes": null
},
{
"id": 3,
"count": 45,
"date": "2025-07-04T10:00:00.000Z",
"notes": null
},
{
"id": 4,
"count": 30,
"date": "2025-07-02T18:00:00.000Z",
"notes": null
}
];
pushups.forEach(async (pushup) => {
await api.pushup.create({
count: pushup.count,
date: pushup.date,
user: {
_link: "1",
},
});
});
And ran that action, and all my data is in the "pushup" table:
All my data is safely in Gadget. I thought the next step would be to clone the backend the Replit agent generated for me. I was wrong. Gadget generates Node.js API endpoints for all the data models, so we don't have to write a line of backend code.
The last step is the UI. I used Gadget's nifty Assistant to speed run this part. I'm on Gadget's free tier, and was still able to use the Assistant without having to enter my credit card info. I found the code in my Replit for the process graph, and gave it to the Gadget Assistant. I prompted it to "duplicate this component, but use the Gadget tech stack". It worked first try.
I made the same prompt for the table of entries. Again, I was able to get a table it in 2 minutes thanks to the Assistant:
Finally, I needed a way for users to make new pushup entries. I wasn't happy with the "New pushup" dialog that the Replit agent generated, so I prompted the Assistant to generate a new one. It looks pretty sharp:
That's all folks! Super happy with how the Gadget app turned out, and even happier that I won't have to file for bankruptcy...
Top comments (0)