Wasp
Declarative full-stack web framework for React and Node
Wasp is an open-source language and framework for building full-stack web apps with React, Node.js and Prisma using a concise declarative config. The generated apps are deployed and self-hosted as standard containers.
Key features
- Declarative app config
- Full-stack React + Node
- Built-in auth
- Self-hosted deploys
Pros & cons
Strengths
- Concise declarative config
- Auth built in
- Full stack from one spec
Trade-offs
- Own DSL to learn
- Young evolving framework
Wasp replaces
Last reviewed Aug 26, 2026 · 802 words
Wasp is not something you run; it is something you compile. You describe an app in a main.wasp file (routes, pages, auth, database entities, jobs) and wasp build emits a plain Node server plus a static React client that you host anywhere a container runs. That makes it a self-hoster's framework in the best sense: the thing that ends up on your box is boring, standard and yours, with no Wasp runtime to keep alive. The trade is a small domain-specific language that 18,709 GitHub stargazers have decided is worth learning and that will cost you a weekend.
The DSL is about 100 lines, not a new language
A Wasp app is three things: the .wasp config, ordinary React components, and ordinary Node functions. The config wires them together (the CLI scaffolds a version pin at the top, omitted here):
app todo {
title: "Todo",
auth: {
userEntity: User,
methods: { usernameAndPassword: {} },
onAuthFailedRedirectTo: "/login"
},
db: { system: PostgreSQL }
}
route RootRoute { path: "/", to: MainPage }
page MainPage {
authRequired: true,
component: import { MainPage } from "@src/MainPage"
}
query getTasks {
fn: import { getTasks } from "@src/queries",
entities: [Task]
}
Everything after an import is a normal file in src/. Queries and actions are the whole client-server contract: declare them once, call them from React with generated hooks, and Wasp handles the HTTP route, the Prisma client and cache invalidation. Auth (username and password, email with verification, Google, GitHub, Discord, Keycloak) is a config block rather than 400 lines of Passport glue. If you have built a Next.js app with tRPC, Prisma and NextAuth, this is that stack with the plumbing deleted.
wasp build hands you a Dockerfile and a static folder
Run wasp build and look in .wasp/build/. You get a server directory with a Dockerfile (Node, runs Prisma migrations on start) and a web-app directory that builds to static files. Self-hosting is therefore two artefacts:
wasp build
cd .wasp/build
docker build -t myapp-server .
cd web-app
npm install
REACT_APP_API_URL=https://api.example.com npm run build
# build/ is your static client
The server needs four environment variables: DATABASE_URL (Postgres; SQLite is for development only), JWT_SECRET, WASP_WEB_CLIENT_URL and WASP_SERVER_URL. Get the two URLs wrong and CORS plus auth redirects fail in confusing ways, so set them to the exact public origins. The static client goes behind any web server; I put it on Caddy with the API proxied on a subdomain. If you would rather not hand-write the compose file, Coolify or Dokploy will build straight from the emitted Dockerfile. The official one-command path is wasp deploy fly, which works, but it is the cloud path rather than the self-hosted one.
Where it sits: Firebase's job, on your own Postgres
The honest comparison is not with Express. Wasp is a Firebase replacement for people who want auth, a database and a deployable app from a small spec, without renting the backend. Against PocketBase or Supabase the difference is architectural: those are backends you point a frontend at; Wasp generates the whole app, frontend included, so there is no BaaS process to run, just Node and Postgres. The cost is that you live inside Wasp's opinions: React, Node, Prisma, and whatever the DSL exposes this year. The team also ships OpenSaaS, a starter with Stripe billing and an admin dashboard, which is why a noticeable share of indie SaaS projects run on Wasp.
The two ways it bites
First, the framework is young (2021) and still pre-1.0 in spirit: releases occasionally change the DSL, and an app you leave for a year will need migration work when you return. Read the changelog before upgrading, not after. Second, the escape hatch is narrow. Wasp exposes the Express layer only through a documented middleware config hook, so if your app needs an unusual server shape (custom streaming uploads, gRPC, a bespoke websocket auth dance) you will fight it. It does support background jobs (pg-boss on Postgres) and websockets via Socket.IO, which covers what a typical app wants.
What I'd do
Use Wasp for a new app with a conventional shape (users, CRUD, a dashboard, maybe billing) when you want to be running on your own box in a day instead of a week. Build on Postgres from the first commit, deploy the emitted server container plus the static client behind Caddy on a 512 MB VPS or a home box, and pin the Wasp version in the project so upgrades are a deliberate act. If your app is mostly a strange backend with a thin UI, pick a plain framework instead; Wasp's value is entirely in the plumbing it removes, and you would be paying the DSL tax for nothing.
Compare Wasp
4 head-to-head comparisons.
Similar developer tools & git apps
Excalidraw
Developer Tools & GitVirtual hand-drawn style whiteboard
Replaces Miro
lazygit
Developer Tools & GitSimple terminal UI for Git commands
Replaces GitKraken, Sourcetree
Hoppscotch
Developer Tools & GitOpen-source API development ecosystem
Replaces Postman, Insomnia
json-server
Developer Tools & GitFull fake REST API from a JSON file in seconds
Replaces Mockoon, Postman Mock
Strapi
Developer Tools & GitLeading open-source headless CMS
Replaces Contentful
NocoDB
Developer Tools & GitOpen-source Airtable alternative
Replaces Airtable