This is how most headless CMS projects go for me. I pick a tool, set up my content models, and get an API. Nice. Then I sit down to build the actual app.
List screen. Detail screen. A form with validation. Loading states, error states, empty states, search, pagination, login. Then I do it all again for the next model, and again on the next project. It’s the same twenty screens every time, and the API didn’t help with any of them.
For years I built apps for small businesses, and almost every one needed the same things: a list of records, a detail page, an add/edit form and a login. Different clients, different logos, same screens. I must have built that set well over a dozen times before it finally annoyed me enough to do something about it.
“Why not just reuse your code?”
I did. Shared widgets, a component library, a starter project I copied from job to job. It helped with the pieces, like buttons, inputs and layouts. But it never saved me the real work, because every client’s data was different. Different fields, different validation, different relationships. So I still ended up editing and customising every screen by hand, every time. A shared library can’t know what your data looks like.
A generator can, because it reads your models.
The API should be where it starts
I’ve been building Underpeaks for about a year and a half now, and one idea keeps coming back to me: the API should be where a backend tool starts. It shouldn’t be where it stops.
If I’ve already told the tool what a Product is, with its fields, types and relationships, then it knows enough to build the screen that lists products, the form that edits them, and the code that talks to the API. Making me write all that by hand is just a choice the tool made.
So Underpeaks generates real Flutter and Next.js apps from your models. One model, two apps, with the data layer already wired up.
The elephant in the room
Let me be straight about what Underpeaks is. It’s a backend. It doesn’t build your product for you.
The generated app is a starting point. You’ll still design your own UI, add your own business logic, and change things to suit your users. I’m not promising a finished app. I’m promising you skip the boring first 80% of wiring screens to an API, so you can get to the part that’s actually yours.
“Generated code is a trap”
I’ve heard that a lot, and I half agree. Most generators have the same three problems. You edit the output, regenerate, and lose your changes. The result looks generic. And you end up stuck with whatever architecture the tool decided on.
Those are fair complaints. I just don’t think the fix is to stop generating code. I think it’s being honest about what generation is for.
For me it’s a head start. The code is normal code and it’s yours, so you can open it, change it, and walk away from the tool tomorrow if you want. The API is still sitting there too. If you don’t like the generated screens, replace them or ignore them and build your own with any HTTP client.
The bit I haven’t cracked yet is keeping generated files and your own files properly separate, so regenerating never wipes out your work. I’m still working on that one, and honestly I’d like to hear how you’d want it to behave.
Why not just ask an AI?
Fair question, and it’s a good option. But AI gives you something a bit different every time, and a generator doesn’t. If I rename a field on a model, I want every screen that uses it to update the same way, not get a best guess. For me, generation covers the repeatable part, and AI is great for everything you build on top of it.
Where I’ve landed
A headless CMS shouldn’t stop at serving data. It should give you the data, the API and a working starting point, and then get out of your way. My test is simple: if you could leave the tool tomorrow and still keep your app, then generating code isn’t a trap. It’s just time saved.
Underpeaks Core is free and self-hosted if you want to have a look: [https://github.com/underpeaks/underpeaks-core]
Over to you
I’d like to know where you stand on this:
- Would you rather get just an API, or a working app to start from?
- What would make you trust generated code enough to ship it?
- What’s burned you before with a code generator?
I’m building this in the open, so what you say really does shape what I do next.
Top comments (0)