DEV Community

Alex Spinov
Alex Spinov

Posted on

Wasp Has a Free API That Builds Full-Stack React Apps With 10x Less Code

Wasp is the Rails for React. Define your data model, auth, and API in a simple DSL — Wasp generates the full-stack React + Node.js app.

What Is Wasp?

Wasp is a full-stack framework that uses a simple configuration language alongside React and Node.js. You describe WHAT you want, Wasp generates HOW.

The Wasp File

// main.wasp
app TodoApp {
  wasp: { version: "^0.14.0" },
  title: "My Todo App",
  auth: {
    userEntity: User,
    methods: { email: {} },
    onAuthFailedRedirectTo: "/login"
  }
}

entity User {=psl
  id    Int    @id @default(autoincrement())
  email String @unique
  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

Server Logic

// src/queries.ts
import { GetTasks } from 'wasp/server/operations'

export const getTasks: GetTasks = async (args, context) => {
  return context.entities.Task.findMany({
    where: { userId: context.user.id },
    orderBy: { id: 'desc' },
  })
}

// src/actions.ts
import { CreateTask } from 'wasp/server/operations'

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

React Components

// src/pages/Main.tsx
import { useQuery, useAction } from 'wasp/client/operations'
import { getTasks, createTask } from 'wasp/client/operations'

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

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

  return (
    <div>
      <h1>My Tasks</h1>
      <input
        placeholder="New task..."
        onKeyDown={async (e) => {
          if (e.key === 'Enter') {
            await createTaskFn({ description: e.target.value })
            e.target.value = ''
          }
        }}
      />
      {tasks?.map(task => (
        <div key={task.id}>{task.description}</div>
      ))}
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

What Wasp Generates

  • Full React frontend with routing
  • Express.js backend with Prisma ORM
  • Authentication (email, Google, GitHub)
  • Database migrations
  • Type-safe operations (queries + actions)
  • Deployment configuration

Getting Started

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

Wasp vs Next.js vs Remix

Feature Wasp Next.js Remix
Auth built-in Yes No No
ORM built-in Prisma No No
Full-stack DSL Yes No No
Lines of code ~10x less Baseline Baseline
Learning curve Low Medium Medium
Deploy One command Vercel Fly.io

Need to add web scraping to your Wasp app? Scrapfly provides data extraction APIs. Email spinov001@gmail.com for full-stack + scraping solutions.

Top comments (0)