Skip to content

SaaS application development

Next.js SaaS Development

Multi-tenant SaaS products on the App Router - tenancy and authorisation designed before the first screen, billing that survives an audit, and a dashboard that stays on the server.

A SaaS product is not a website with a login. Three decisions made in the first fortnight - how tenancy works, where authorisation lives, and how billing state reaches the application - determine what the next two years cost, and all three are expensive to reverse once there is production data.

We build these, and we start with those three.

Tenancy, decided before the first screen

There are three models and the right one depends on your customers, not on fashion.

ModelIsolationWhen it is right
Shared tables, tenant columnEnforced in codeMost products. Cheapest to run and to migrate.
Schema per tenantEnforced by the databaseRegulated customers, per-tenant export or restore.
Database per tenantTotalFew, large, contractually isolated customers.

The shared model is right most of the time, and its one real risk is a query that forgets the tenant filter. That is not a discipline problem to be solved with code review - it is solved with row-level security in the database, so a missing filter returns nothing instead of returning someone else's data.

Authorisation at the data, not at the route

Middleware deciding who may see a page is a gate, and gates are useful. They are not authorisation. Server Actions and Route Handlers are callable directly, so a check that lives only in middleware is a check the endpoint does not have.

Every query carries the tenant and the actor. Every mutation re-derives the permission from the session rather than trusting an argument. The reasoning is the same one in Server Actions and the three things people get wrong, and in a multi-tenant product the failure mode is not a bug, it is one customer reading another's data.

Billing that survives an audit

Stripe is the default and the integration is not the hard part. The hard part is that your application and Stripe hold the same fact - what this customer is entitled to - and they will disagree.

We treat Stripe as the source of truth and the application's copy as a cache rebuilt from webhooks, with the webhook handler idempotent and signature- checked. Entitlements are read from your own database on every request, because calling Stripe in the request path makes your product's availability depend on theirs.

Proration, trials, seat changes and failed payments are each a state the UI has to express. Deciding what a past-due account can still do is a product decision, and we will ask for it rather than inventing one.

The dashboard problem

SaaS dashboards are where App Router applications get slow. The instinct is a use client at the top because there are charts and filters, and then the entire dashboard tree ships to the browser.

The tables, headers, navigation and data fetching stay on the server. The chart, the filter and the date picker are client islands. URL state carries the filters, which makes a filtered view shareable and the back button correct. And no page waits for its slowest widget - each streams behind its own boundary, which is the point of loading.tsx not being a spinner.

What we do not do

We do not start from a SaaS boilerplate. They encode tenancy, auth and billing decisions made for a different product, and unpicking those later costs more than the fortnight they saved.

We also do not build the admin panel first. It is the part founders most enjoy specifying and the part customers never see.

How an engagement runs

The first week is a decision and not a build: which tenancy model, what isolation you will have to prove, and what the security review of your largest plausible customer will ask for.

That becomes a written scope with the model, the authorisation approach, the billing behaviour and the phases, priced. It is signed before the product is built, because this is the one thing on the page that no later migration makes cheap.

Then the phases, each ending deployed, with the isolation tests written next to the features.

What you receive

The tenancy and authorisation model settled in writing before the first screen, then the product built against it. The test suite matters more here than usual, because the tests that count are the ones asserting a failure: a request carrying one tenant's session must not reach another tenant's row.

Billing ships with its reconciliation and not only its checkout. And the written answer to the isolation question, which every enterprise prospect eventually puts in a security review and which is far cheaper to have ready than to compose under a deadline.

Scope and terms

Engagement model
Fixed scope, agreed in writing before work starts. Not a day rate against an open backlog.
Price and timeline
Both are set per project, once the scope is. Quoted together, before anything is built.
What we need from you
One person who can approve decisions, and access to your repository and issue tracker.
Not included
Anything outside the agreed scope. It becomes its own scope rather than a variation order.
Third-party costs
Hosting, licences, API fees and SaaS subscriptions are contracted and paid by you.
Invoicing
Codefacture Yazılım A.Ş., Türkiye. EUR, USD or GBP by bank transfer, with no Turkish VAT on exported services.

Frequently asked questions

One database or one per tenant?
A shared database with a tenant column for almost everyone, enforced at the data layer and not in a middleware check. A database per tenant is a real answer when a contract demands isolation, and it costs you migrations, backups and a connection problem for as long as the product lives. Decide it before the first screen.
Do you build the billing?
Yes, usually on Stripe. Checkout is not the part that takes the time. Proration, plan changes mid-cycle and a record that still reconciles when an auditor reads it a year later are.
Can you work on an existing product?
Yes, starting with an audit, because retrofitting tenancy into an application that assumed one customer is a different job from building it in.
How long until we can sign the first customer?
Three to four months to something sellable, for a focused product with the scope agreed. We would cut scope before cutting the tenancy and authorisation work, because those two are what you cannot retrofit cheaply.
Call us+1 848 272 7583WhatsApp+90 850 308 5436Emailinfo@codefacture.comContact page