DEV Community

Alex Spinov
Alex Spinov

Posted on

Wasp Has a Free API — Build Full-Stack React Apps 10x Faster

TL;DR

Wasp is an open-source framework that uses a simple DSL to generate a full-stack React + Node.js app — complete with auth, database, email, cron jobs, and deployment. Write 10 lines of config, get 1000 lines of boilerplate for free.

What Is Wasp?

Wasp is a Rails-like framework for JavaScript:

  • Full-stack DSL — declare routes, auth, entities in simple config
  • React + Node.js — generates production-ready code
  • Built-in auth — email/password, Google, GitHub, Discord
  • Prisma ORM — type-safe database access
  • Type-safe RPC — auto-generated API with full TypeScript
  • Jobs and cron — background tasks built-in
  • One-command deploy — Fly.io or Railway
  • Free — MIT license

Quick Start

curl -sSL https://get.wasp-lang.dev/installer.sh | sh
wasp new my-app
cd my-app
wasp start
Enter fullscreen mode Exit fullscreen mode

The Wasp Config

// main.wasp — this is ALL you need for a full-stack app

app MyApp {
  wasp: { version: "^0.15.0" },
  title: "My SaaS App",
  auth: {
    userEntity: User,
    methods: {
      email: {},
      google: {},
      gitHub: {},
    },
    onAuthFailedRedirectTo: "/login",
  },
  db: { system: PostgreSQL },
  emailSender: {
    provider: Resend,
  },
}

// Database entities
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=}

// Pages
route HomeRoute { path: "/", to: HomePage }
page HomePage {
  authRequired: true,
  component: import { HomePage } from "@src/pages/Home"
}

route LoginRoute { path: "/login", to: LoginPage }
page LoginPage {
  component: import { LoginPage } from "@src/pages/Login"
}

// Operations (type-safe API)
query getTasks {
  fn: import { getTasks } from "@src/queries",
  entities: [Task],
}

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

// Cron job
job dailyReport {
  executor: PgBoss,
  perform: {
    fn: import { sendReport } from "@src/jobs/report"
  },
  schedule: {
    cron: "0 9 * * *"
  },
}
Enter fullscreen mode Exit fullscreen mode

React Pages

// src/pages/Home.tsx
import { useQuery } from "wasp/client/operations";
import { getTasks, createTask } from "wasp/client/operations";

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

  const handleAdd = async () => {
    await createTask({ description: "New task" });
  };

  if (isLoading) return <div>Loading...</div>;

  return (
    <div>
      <h1>My Tasks</h1>
      <button onClick={handleAdd}>Add Task</button>
      {tasks?.map((task) => (
        <div key={task.id}>
          {task.isDone ? "Done" : "Todo"}: {task.description}
        </div>
      ))}
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Server Operations

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

export const getTasks: GetTasks<void, Task[]> = async (args, context) => {
  return context.entities.Task.findMany({
    where: { userId: context.user.id },
    orderBy: { id: "desc" },
  });
};

// src/actions.ts
import { type CreateTask } from "wasp/server/operations";

export const createTask: CreateTask<{ description: string }, Task> = async (
  { description },
  context
) => {
  return context.entities.Task.create({
    data: {
      description,
      userId: context.user.id,
    },
  });
};
Enter fullscreen mode Exit fullscreen mode

Deploy

# Deploy to Fly.io
wasp deploy fly setup my-app mia
wasp deploy fly cmd secrets set DATABASE_URL=...
wasp deploy fly deploy

# Or deploy to Railway
wasp deploy
Enter fullscreen mode Exit fullscreen mode

Wasp vs Alternatives

Feature Wasp Next.js Remix RedwoodJS
Auth built-in Yes No (NextAuth) No Yes
Database Prisma built-in Manual Manual Prisma
Type-safe RPC Auto-generated tRPC manual Manual Auto-generated
Cron jobs Built-in Manual Manual Manual
Email Built-in Manual Manual Manual
Boilerplate Minimal (DSL) Moderate Moderate Moderate
Deploy One command Manual Manual Manual

Resources


Building a SaaS that processes web data? My Apify tools extract data from any website — build your data product with Wasp in record time. Questions? Email spinov001@gmail.com

Top comments (0)