How to use
- Copy the installation command and review the source package before installing it in your own agent environment.
- Check the source document for required tools, credentials and supported hosts.
- Describe your input and desired deliverable; review the output against the source material.
npx skills add https://github.com/maheshawasare/claude-skills-pro --skill scaffold-fullstack-appBefore you start
- Installation does not include a model subscription, API allowance or permission to access your files.
- Repository stars and installation counts describe activity, not an independent quality or security test.
Rendered from the source repository. Headings, examples, code, tables, links, and referenced images are preserved.
Scaffold a Single-Tenant Full-Stack App
The lighter cousin of scaffold-saas-starter. For apps where the tenancy boundary is the user, not an organization — internal tools, indie SaaS, side projects, B2C consumer apps. No row-level security ceremony, no Clerk billing, just enough structure to ship.
When to use
- Indie SaaS / side project — you want production-quality but not enterprise scaffolding.
- Internal tool — small team, single org effectively.
- B2C consumer app where each user owns their own data.
- Pre-PMF, want to ship in days.
When NOT to use
- B2B with teams/orgs/invites →
scaffold-saas-starter. - Need shared workspaces / collaboration →
scaffold-saas-starter. - Multi-region or compliance constraints (HIPAA, regulated) — needs more than this scaffold.
Decisions made for you
| Decision | Choice | Why |
|---|---|---|
| Auth | Auth.js (NextAuth v5) | Free, no vendor lock-in, magic-link + OAuth out of box |
| DB | Postgres + Drizzle | Same as SaaS scaffold, less the RLS overhead |
| Tenancy | user_id column on owned rows | No RLS needed; single-tenant boundary |
| Web | Next.js 16 App Router | Matches SaaS scaffold for muscle memory |
| Brevo | Free tier covers most indie launches | |
| Payments | Razorpay or Stripe (skip if not needed) | Don't wire until you charge |
| Background jobs | pg-boss on same DB | Avoid Redis until needed |
| Deploy | Vercel + Neon (free tiers) | $0 to first user |
File structure
my-app/
src/
app/
(marketing)/page.tsx # public landing
(auth)/sign-in/page.tsx
(app)/ # authenticated
dashboard/page.tsx
settings/page.tsx
api/
auth/[...nextauth]/route.ts
webhooks/
razorpay/route.ts # only if billing
brevo/route.ts
lib/
auth.ts # auth() helper
db.ts # Drizzle client
email.ts # Brevo wrapper
billing.ts # only if billing
db/
schema.ts
migrations/
.env.example
drizzle.config.ts
next.config.ts
package.json
README.md
docker-compose.yml # local PostgresNote: no apps/ monorepo split. One Next.js project, one DB package. If you outgrow it, lift to apps/web later — 30 min refactor.
Auth.js v5 minimal setup
// src/lib/auth.ts
import NextAuth from "next-auth";
import GitHub from "next-auth/providers/github";
import { DrizzleAdapter } from "@auth/drizzle-adapter";
import { db } from "./db";
export const { auth, handlers, signIn, signOut } = NextAuth({
adapter: DrizzleAdapter(db),
providers: [GitHub],
pages: { signIn: "/sign-in" },
callbacks: {
session: async ({ session, user }) => {
session.user.id = user.id;
return session;
},
},
});// src/middleware.ts
export { auth as middleware } from "@/lib/auth";
export const config = {
matcher: ["/((?!api/auth|_next/static|_next/image|favicon.ico|sign-in).*)"],
};That's it for auth. No Clerk dashboard, no org UI to build, no per-tenant config.
Schema rule: every owned row has user_id
// src/db/schema.ts
import { pgTable, uuid, text, timestamp, integer } from "drizzle-orm/pg-core";
export const users = pgTable("users", {
id: text("id").primaryKey(), // from Auth.js
email: text("email").notNull().unique(),
name: text("name"),
createdAt: timestamp("created_at").notNull().defaultNow(),
});
export const projects = pgTable("projects", {
id: uuid("id").primaryKey().defaultRandom(),
userId: text("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
name: text("name").notNull(),
createdAt: timestamp("created_at").notNull().defaultNow(),
});Discipline (no RLS net): every query against projects MUST filter by userId. Bake this into a helper:
// src/lib/db-helpers.ts
export async function listMyProjects() {
const session = await auth();
if (!session?.user?.id) throw new Error("unauthenticated");
return db.select().from(projects).where(eq(projects.userId, session.user.id));
}Don't expose raw db to route handlers — only helpers that have already filtered by user. This is the poor person's RLS.
What the scaffold emits
- The directory tree above.
- Auth.js v5 with GitHub + Google + Email magic-link providers configured (env-toggle).
- Drizzle schema with
users,accounts,sessions(Auth.js tables) + exampleprojectstable withuser_id. - Brevo email helper with magic-link template.
- Optional Razorpay/Stripe billing (asks at scaffold time; skips if "not yet").
.env.examplewith every var.docker-compose.ymlfor local Postgres.- GitHub Actions: typecheck, lint, build, migration dry-run.
Anti-patterns
- No `userId` filter on a query — single bug = full leak. Helper-only access pattern catches it at code review.
- Storing user data without `onDelete: "cascade"` — GDPR/DPDP "right to delete" requires the cascade work. Setting it later requires backfill.
- Auth.js Email provider without configuring Brevo — magic links fail silently. Wire email at the same time as auth, not later.
- Building auth UI from scratch — Auth.js gives you sane defaults. Don't.
- Wiring billing before you charge — adds maintenance load with no revenue. Skip until you have a real plan to sell.
- No `.env.example` — same problem as in SaaS scaffold; ship it day 1.
- Vercel + Vercel Postgres — Vercel Postgres is expensive for small apps. Use Neon free tier; switch later if needed.
- No background jobs at all, "we'll cron it" — first delayed task you need (welcome email after signup, retention campaign) becomes a hack.
pg-bossis 50 lines.
Verify it worked
- [ ]
pnpm devstarts Next.js with Postgres connected. - [ ] GitHub sign-in completes round-trip; user row appears in
userstable. - [ ]
listMyProjects()returns 0 rows when called as a different user. - [ ] Magic link email arrives via Brevo (check spam in test).
- [ ]
pnpm build && pnpm startsucceeds — no dev-only imports leak. - [ ] First Vercel deploy: < 15 minutes from
git inittohttps://*.vercel.app/sign-inworking. - [ ] CI passes on a fresh push.
- [ ]
DELETE FROM users WHERE id='xxx'cascades and removes their projects (no orphans).



