Wasp Review 2026: Full-Stack Web Framework with Built-In Auth
TL;DR
Wasp is a full-stack language built on React + Node.js that eliminates most backend boilerplate — and it works. You define your app in a .wasp config file, and Wasp generates auth, routing, API endpoints, database, email, and background jobs. The result is genuinely faster development: auth in 5 minutes, email in 5 minutes, background jobs in 10 minutes. The cost: you're learning a DSL, and debugging generated code takes getting used to. For indie hackers and small teams willing to bet on Wasp, it's legitimately productive.
Key Takeaways
- Type: Open source full-stack framework (React + Node.js + Prisma)
- Key DX: Declare features in
.wasp, Wasp generates the boilerplate - Built-in: Auth (email, Google, GitHub), email sending, background jobs, RPC (tRPC-like)
- Database: Prisma + PostgreSQL
- Best for: indie hackers, solo developers, small teams wanting fast iteration
- GitHub: 14K+ stars, actively maintained
How Wasp Works
// main.wasp — the central config file
app MySaaS {
wasp: { version: "^0.14.0" },
title: "My SaaS",
auth: {
userEntity: User,
methods: {
email: {
fromField: { name: "My SaaS", email: "noreply@mysaas.com" },
emailVerification: { clientRoute: EmailVerificationRoute },
passwordReset: { clientRoute: PasswordResetRoute },
},
google: {},
github: {},
},
onAuthFailedRedirectTo: "/login",
},
emailSender: {
provider: SendGrid,
defaultFrom: { name: "My SaaS", email: "noreply@mysaas.com" },
},
}
// Define your data model:
entity User {=psl
id Int @id @default(autoincrement())
email String @unique
createdAt DateTime @default(now())
subscription Subscription?
psl=}
// Define routes:
route DashboardRoute { path: "/dashboard", to: DashboardPage }
page DashboardPage {
authRequired: true,
component: import { DashboardPage } from "@client/pages/DashboardPage.tsx",
}
// Define server-side actions (mutations):
action createPost {
fn: import { createPost } from "@server/actions/posts.js",
entities: [Post, User]
}
// Define queries:
query getPosts {
fn: import { getPosts } from "@server/queries/posts.js",
entities: [Post]
}
What Wasp Generates
From the .wasp config above, Wasp generates:
- Complete auth UI (login, signup, email verification, password reset)
- JWT session handling with secure cookies
- Route protection middleware
- Type-safe RPC layer (similar to tRPC)
- Email verification + password reset flows
- OAuth integration (Google, GitHub)
You don't write any of this — you just configure it.
Wasp Actions and Queries (RPC)
// src/server/actions/posts.ts
import type { CreatePost } from 'wasp/server/operations';
import { HttpError } from 'wasp/server';
type CreatePostArgs = { title: string; content: string };
export const createPost: CreatePost<CreatePostArgs, Post> = async (args, context) => {
if (!context.user) throw new HttpError(401);
return context.entities.Post.create({
data: {
title: args.title,
content: args.content,
authorId: context.user.id,
},
});
};
// src/client/pages/DashboardPage.tsx — client-side usage
import { useQuery, useAction } from 'wasp/client/operations';
import { getPosts, createPost } from 'wasp/client/operations';
export function DashboardPage() {
const { data: posts, isLoading } = useQuery(getPosts); // Auto-typed!
const createPostFn = useAction(createPost);
return (
<div>
{posts?.map(post => <div key={post.id}>{post.title}</div>)}
<button onClick={() => createPostFn({ title: 'New Post', content: '...' })}>
Create Post
</button>
</div>
);
}
Background Jobs
// Declare a job in main.wasp:
job weeklyReport {
executor: PgBoss,
perform: {
fn: import { sendWeeklyReport } from "@server/jobs/weeklyReport.js",
},
schedule: {
cron: "0 9 * * MON", // Every Monday 9am
},
entities: [User],
}
// src/server/jobs/weeklyReport.ts
export const sendWeeklyReport = async (_args: unknown, context: JobContext) => {
const users = await context.entities.User.findMany({
where: { weeklyReportsEnabled: true },
});
for (const user of users) {
await sendReportEmail(user);
}
};
Wasp vs Next.js + T3
| Wasp | T3 Stack (create-t3-app) | |
|---|---|---|
| Setup time | ~5 minutes | ~15 minutes |
| Auth included | ✅ | ❌ (add NextAuth separately) |
| Email included | ✅ | ❌ |
| Background jobs | ✅ | ❌ |
| Learning curve | Medium (learn .wasp) | Medium (learn tRPC) |
| Framework lock-in | High (Wasp-specific) | Medium (T3 conventions) |
| Ecosystem | Small (Wasp-only) | Huge (Next.js ecosystem) |
| Deployment | Fly.io / Railway / VPS | Vercel (native) |
Who Should Use Wasp
Use Wasp if:
→ Indie hacker or solo developer
→ Want to minimize boilerplate
→ Willing to learn Wasp's conventions
→ Self-hosting on VPS/Railway/Fly.io
→ OpenSaaS template appeals to you
Skip Wasp if:
→ Team requires standard Next.js/React
→ Need Vercel-native deployment
→ Enterprise environment with strict tech standards
→ Need the full Node.js ecosystem without constraints
Verdict: Wasp genuinely accelerates development for solo developers and small teams. The .wasp config is the learning curve — once past it, auth/email/jobs take minutes instead of hours. If you're an indie hacker building your first SaaS, Wasp + OpenSaaS is worth serious consideration.
Compare Wasp with other SaaS starters at StarterPick.