Guillaume Duvernay

Every business app I built needed the same four pages

business appsproductSoftrno-code

I’ve built dozens of business apps over the past four years. Internal tools, CRMs, ERPs, intranets, client portals, vendor portals, deal rooms. Different companies, different data, and roughly the same set of pages every time.

Four families. They cover something like 90% of what a business app needs, and knowing them turns the hardest question at the start of a project, which pages do I actually need, into a short checklist.

I’m talking about apps people log into. Public directories and marketing sites work differently. A business app has a narrow, defined scope: a client portal exists so clients can see their projects and tasks, and so your team can see all of them. That narrowness is what makes a small set of pages enough.

Dashboards and standalone form pages sit alongside these. They come up often enough to plan for, and rarely enough that they aren't a family of their own.

1. The homepage, and the user group question first

Before you design a homepage, list the groups that log in. Clients and internal staff. Teachers, parents and students. Employees and the finance team. This decision comes before everything else, because it determines whether you build one homepage or several.

My rule of thumb: if more than about half the blocks on the page would differ between two groups, give each group its own homepage. Below that, one page with visibility conditions on a few blocks.

The 50% line is a habit, not a measurement. It's roughly where I've found a conditional page stops being readable to whoever maintains it next.

What belongs on it: the two to four actions this group takes most, and the thing they need to act on now. Not more. The app has a narrow scope, so the homepage should be narrow too.

An expense tracker makes it concrete. An employee logs in to submit a request, so the form is one click away, and below it their own requests still pending. The finance team logs in to approve, so they see the requests waiting on them. Not every request ever filed, not the denied ones from March. The list they have to act on.

Everything else can live in the navigation bar, and usually should.

2. Utility pages, which you should not spend time on

Login. Sign up, or a disabled sign up if it’s an internal tool and people get invited. Forgot password and reset password. The 404. An onboarding flow if you want to force someone to complete their profile before they reach the app.

All boring. All required. None of them is where your app gets good.

This is the family I’d rather not build, and with Softr I don’t: they ship configured, and the work is styling and wording. If you’re building from scratch, budget for them anyway, because every one of them exists in every app and forgetting the 404 is how someone hits a dead end with no way back.

3. Entity pages, one per object

Once your database is right, these almost write themselves. One page per table that means something to a user. A CRM gets contacts, companies, deals, tasks. Log into HubSpot and that’s exactly what the nav is.

The page lists records, and the format is a decision worth making per object:

  • A table when the job is finding one row among many, and density helps.
  • A kanban board for anything with a status people move through, like tasks or deals.
  • A calendar when the date is the thing people navigate by.
  • A grid of cards when a logo or a photo is how people recognise a record.

You can offer two, as tabs on the same page, when different people work differently. In my CRM the deals page has the pipeline as the default and a table view next to it.

The actions belong here too. Add a record. Export the list as CSV, which costs nothing and someone always asks for it. Import a CSV, if people arrive with batches.

Sometimes the entity page is the whole feature. A documents table with a name and a file, unrelated to anything else, can just be a list with edit and delete on each row. No detail page needed.

4. Detail pages, and what sits underneath them

Usually you do want to open a record. A table row has no space to work in, and a company has a description and a website and notes that belong somewhere.

A detail page has three parts.

The record itself, with the fields worth showing, which is more than the entity page shows. The actions on it: edit, delete, change status, assign to someone. Permissions go on these individually, so deleting a contact can be admin only while everyone can edit one.

Then the part I always add and the one that makes an app feel finished: the related records, listed below. Open a company and you see its contacts, its deals, its past interactions. Open a task and you see the project it belongs to.

Each of these is a filter on a list block, pointed at the record currently open. It's the same block as on the entity page, filtered.

Open these in a modal rather than as a full page, centered or sliding in from the side. The URL doesn’t change, the list stays behind it, and going back is closing a panel instead of a page load. On a list someone is working through, that difference is most of how fast the app feels.

The two extra pages worth planning for

A dashboard. Charts and counts. Sometimes it is the homepage, sometimes it’s its own page when there’s enough of it.

A form on its own page. This one is a maintenance argument. If four different places let someone create a company, and each has its own create form configured on it, then adding a field means editing four forms and forgetting one. Build the form once on its own page, and have every button open that page in a modal. One form to maintain.

Structuring an ERP the same way

The four families hold up on bigger apps, they just get grouped. On an ERP I organised the navigation by department rather than by object: inventory, sales, finance. Behind each one, the same entity pages.

Two things I did differently there and would do again. Some pages consolidate two objects, so sales carries orders and customers together, because the people who work in sales work across both. And the homepage doesn’t list all products, it lists products with fewer than 100 units in stock, under a heading saying these need attention. A list filtered to what requires action beats a complete list, on a homepage.

Get the database right and the pages follow

Step three is where the time goes. The pages are close to mechanical once the objects are right, which is why a bad table structure shows up as a confusing app.

One table per real object, with fields that belong to it. A task has a description, a due date, an owner. A company has a name, a website, an industry. Get that wrong and no page layout saves you.

AI is genuinely good at this part. Describe the CRM you want and you’ll get a reasonable first database out of it, which is how I start most projects now.

Knowing the framework is what lets you leave it

Softr’s AI builder produces apps shaped exactly like this. So do the others. Which raises a fair question: if the tool already knows the pattern, why learn it.

Because the generated version is a default, and defaults are the average of everyone’s app rather than yours. The moments that make an app good are the departures: not building the interactions page, opening details in a side panel instead of a route, filtering the homepage list to what needs attention. An AI builder won’t propose those, because nothing in your prompt told it your people work through a list all day.

I keep finding the same thing with agents generally, in Claude Code as much as in an app builder. They’re fast at producing the standard shape, and what you bring is knowing which part of the standard shape is wrong for you. That only comes from having built the thing by hand enough times to have opinions about it.

So use the generator. Then open what it made and change the three things you’d have done differently.