DEV Community

Alex Spinov
Alex Spinov

Posted on

Wasp Has a Free Full-Stack Framework That Generates React + Express in One File

Next.js has 50+ config options. Wasp has a declarative DSL that generates a complete full-stack app — auth, CRUD, jobs, email — from one config file.

The Wasp File

// main.wasp — this generates your ENTIRE app structure
app TodoApp {
  wasp: { version: "^0.15.0" },
  title: "My Todo App",
  auth: {
    userEntity: User,
    methods: {
      usernameAndPassword: {},
      google: {},
      github: {},
    },
    onAuthFailedRedirectTo: "/login",
  },
}

entity User {=psl
  id       Int    @id @default(autoincrement())
  tasks    Task[]
psl=}

entity Task {=psl
  id          Int     @id @default(autoincrement())
  description String
  isDone      Boolean @default(false)
  user        User    @relation(fields: [userId], references: [id])
  userId      Int
psl=}

route RootRoute { path: "/", to: MainPage }
page MainPage {
  authRequired: true,
  component: import { MainPage } from "@src/pages/Main"
}

query getTasks {
  fn: import { getTasks } from "@src/queries",
  entities: [Task],
}

action createTask {
  fn: import { createTask } from "@src/actions",
  entities: [Task],
}
Enter fullscreen mode Exit fullscreen mode

From this single file, Wasp generates:

  • React frontend with routing
  • Express backend with API
  • Prisma database layer
  • Authentication (email, Google, GitHub)
  • Type-safe client-server communication

Queries (Type-Safe)

// src/queries.ts
import { getTasks } from "wasp/server/operations";

export const getTasks = async (args, context) => {
  return context.entities.Task.findMany({
    where: { user: { id: context.user.id } },
    orderBy: { id: "desc" },
  });
};
Enter fullscreen mode Exit fullscreen mode
// src/pages/Main.tsx
import { useQuery, getTasks } from "wasp/client/operations";

export function MainPage() {
  const { data: tasks, isLoading } = useQuery(getTasks);

  if (isLoading) return <p>Loading...</p>;
  return (
    <ul>
      {tasks?.map(task => <li key={task.id}>{task.description}</li>)}
    </ul>
  );
}
Enter fullscreen mode Exit fullscreen mode

Full type safety from database to UI — no manual API types.

Background Jobs

job emailChecker {
  executor: PgBoss,
  perform: { fn: import { checkEmails } from "@src/jobs/emailChecker" },
  schedule: { cron: "0 * * * *" }  // Every hour
}
Enter fullscreen mode Exit fullscreen mode

Built-in job queue with cron scheduling.

Email Sending

app MyApp {
  emailSender: {
    provider: SendGrid,
  },
}
Enter fullscreen mode Exit fullscreen mode
import { emailSender } from "wasp/server/email";

await emailSender.send({
  to: "user@test.com",
  subject: "Welcome!",
  html: "<h1>Hello!</h1>",
});
Enter fullscreen mode Exit fullscreen mode

Deploy

wasp deploy fly launch my-app mia
# Deploys to Fly.io with database in ~2 minutes
Enter fullscreen mode Exit fullscreen mode

One command deployment — Fly.io, Railway, or any Docker host.

SaaS Starter (OpenSaaS)

wasp new my-saas -t saas
Enter fullscreen mode Exit fullscreen mode

Gets you: auth, Stripe payments, admin dashboard, blog, analytics, email — ready to customize.


Need full-stack app development? I build web tools and data solutions. Email spinov001@gmail.com or check my Apify tools.

Top comments (0)