SaaS engine for Next.js
The hard decisions, already made.
Most SaaS teams spend 6–10 weeks wiring billing, RBAC, and multi-tenant enforcement — and still ship subtle race conditions, permission drift, and webhook bugs. SaaSCoreX ships with those systems already built, and enforced in code.
For serious SaaS builders who’ve rebuilt backend systems before. Not optimized for side projects or hobby apps.
Enforcement Pipeline
Every state mutation flows through this pipeline before it touches your database
Auth
Session verified
Rate Limit
Abuse prevention
RBAC
Permission enforced
Entitlements
Plan limits checked
Limits
Atomic plan enforcement
Execute
State mutation committed
Postgres commit
The core principle
If it mutates state, it’s enforced.
Not checked in the UI. Not validated by a middleware you might forget. Enforced at the server boundary, before the database is touched.
Every mutation is permission-guarded.
Every plan limit is atomically enforced.
Every webhook is idempotent.
Every tenant query is scoped.
Every audit event is immutable.
Every API key is hashed at rest.
What you don’t have to build
Four systems most teams get wrong.
These aren’t features you can bolt on later. They’re architectural decisions that compound — and they’re already made.
Billing & Entitlements
- Stripe checkout, portal, plan switching with proration
- Webhook state machine — events process exactly once
- Entitlements enforced at the route level. Not the UI.
- Nightly reconciliation catches Stripe/database drift
- Plan limits enforced atomically — no TOCTOU bypass
Access Control
- 13 server-enforced permission gates. No UI-only checks.
- TOTP 2FA with QR setup and hashed backup codes
- Multi-tenant org model with ownership invariants
- Last owner cannot be removed, demoted, or leave
API Surface
- 21-endpoint REST API with OpenAPI 3.1 spec
- API keys with SHA-256 hashed storage. Plaintext never stored.
- Rate limiting with memory + Redis adapters
- Consistent JSON envelope, CORS, pagination, request tracing
Operational Systems
- 24-action audit taxonomy with structured query API
- Background jobs with retries and scheduling
- Notification preferences checked before every send
- GDPR data export via async job
- Environment doctor validates everything before deploy
SaaSCoreX is not a template.
Templates get you to login. SaaSCoreX gets you to production.
Templates
- Login pages
- Stripe checkout button
- Role enum
- Admin dashboard
- Feature flag toggles
SaaSCoreX
- Atomic plan enforcement. Not UI checks.
- 13 permission gates. Every mutation guarded server-side.
- 21-endpoint API with OpenAPI spec and rate limiting
- TOTP 2FA with hashed backup codes
- 24-action audit taxonomy. Immutable.
- Background jobs, notifications, GDPR export
Real code. Real enforcement.
Three invariants enforced before state changes.
The stuff that usually breaks in month three.
Access control that can’t drift
Every mutation checks permissions server-side. No UI-only gating.
packages/core/src/teams/permissions.ts
export function requirePermission(
role: MemberRole,
action: OrgAction,
): void {
if (!ROLE_PERMISSIONS[role]?.has(action)) {
throw new PermissionDeniedError(role, action);
}
}
// In every server action:
const membership = await getMembership(session.user.id, orgId);
requirePermission(membership.role, "billing.manage");Prevents route-by-route permission drift as the codebase grows.
Limits that can’t be bypassed
Plan limits enforced atomically under concurrency.
packages/core/src/projects/service.ts
return db.$transaction(async (tx) => {
await tx.$executeRaw`
SELECT pg_advisory_xact_lock(${ns}::int, ${orgHash}::int)
`;
const count = await tx.project.count({
where: { orgId, deletedAt: null },
});
if (count >= maxProjects) {
throw new LimitExceededError("project", maxProjects);
}
return tx.project.create({ data: { orgId, name, ... } });
});Prevents two concurrent requests from both sneaking past the quota.
Billing events that can’t double-process
Stripe webhooks process exactly once — even with retries and concurrency.
packages/core/src/billing/webhook-handler.ts
const existing = await db.webhookEvent.findUnique({
where: { stripeEventId: event.id },
});
if (existing?.status === "PROCESSED") return;
if (existing?.status === "PROCESSING") return;
await db.webhookEvent.upsert({
where: { stripeEventId: event.id },
create: { stripeEventId: event.id, status: "PROCESSING", ... },
update: { status: "PROCESSING", attempts: { increment: 1 } },
});Prevents duplicate side effects when Stripe re-delivers events.
Running in under five minutes.
An opinionated CLI installer that configures your SaaS engine correctly from day one.
npx create-saascorex my-app
# CLI generates and scopes your .env
pnpm db:migrate
pnpm devWhat the installer handles
- Interactive setup wizard (domain, billing provider, feature flags, OAuth)
- Environment variables generated per selected features
- Identity-neutral brand configuration from first run
- Pre-built database schema and migrations
- Billing and tenancy wired end-to-end (Stripe configuration required)
- Optional demo seed data (3 orgs, 8 users, 10 projects)
- Environment doctor validates DB, Stripe, Prisma, and auth config
See the actual code
Architecture deep dive
Real code from the SaaSCoreX source — not pseudocode, not slides. RBAC enforcement, tenant isolation, webhook idempotency, entitlement billing, and six more subsystems with inline explanations.
Where SaaS apps usually break
Built for month three.
Most SaaS templates stop at login. Production problems start after your first paying customers.
Security & Abuse Hardening
- Default-on auth rate limiting
- TOTP two-factor authentication with backup codes
- API keys hashed at rest with SHA-256
- Zod-validated admin actions with input sanitization
Billing & Consistency Guarantees
- Stripe webhook idempotency state machine
- Nightly subscription reconciliation
- Concurrency tests for plan limits, seat limits, and last-owner protections
Operational Reliability
- Health endpoint for uptime checks
- Background jobs with retries and scheduling
- Async data export via jobs
- Notification preferences checked before every send
Confidence in Deployment
- Playwright E2E critical path tests
- Environment doctor and setup wizard
Frequently asked questions
Is the output branded?+
No. The output is identity-neutral. Your brand from day one.
Is this a subscription?+
No. One-time purchase. Full source code access. No recurring fees.
Can I use this for client work?+
Depends on your license tier. Individual covers one developer. Team covers up to five. You can build and deploy unlimited projects under your license — but the source code cannot be shared outside your licensed team.
What does “rolling updates” mean?+
All plans include lifetime access to the purchased major version. Minor updates and patches are included as they ship.
Do I get future major versions?+
Major version upgrades (e.g., 2.0) are optional and offered at a discounted upgrade price. You keep lifetime access to everything in 1.x.
What if I stop using it?+
Nothing changes. The code runs on your infrastructure. No license server, no phone-home, no kill switch.
Is it maintained?+
Yes. Releases are tagged and changelogged.
Refund policy?+
All sales are final once source code has been accessed. If unaccessed, you can request a refund within 14 days.
Stop rewriting your SaaS backend.
Skip 6–10 weeks of infrastructure work. One-time license. Full source code. No subscription.