Access your Database from React Apps with Ease
Build high-performance and type-safe React apps with Prisma's developer-friendly database tools: The world's most popular TypeScript ORM and the first serverless database without cold starts.
Why React and Prisma?
Built for high-performance web apps
Built on unikernels, Prisma Postgres runs on bare metal servers for peak performance and infinite scalability.
Serverless, without cold starts
The first serverless database with pay-as-you-go pricing, no infrastructure management, and zero cold starts.
Flexible data fetching & rendering
Display your data using client-side rendering, server-side rendering and static site generation.
Built-in global caching
Add a cache strategy to any database query and its results will be cached close to your users for peak performance and UX.
End-to-end type safety
Pairing Prisma with React ensures your app is coherently typed, from the database to your React components.
Helpful communities
Both React and Prisma have vibrant communities where you find support, fun events and amazing developers.
How Prisma and React fit together
React Server Components
React Server Components let you access your database with Prisma directly in your component code. These components run exclusively on the server, allowing you to query your database without exposing credentials or creating API endpoints.
The data is rendered to HTML on the server and streamed to the client, with zero impact on your JavaScript bundle size.
// UserList.tsx (Server Component)
import { PrismaPg } from '@prisma/adapter-pg'
import { PrismaClient } from '../generated/client'
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL,
})
const prisma = new PrismaClient({ adapter })
export default async function UserList() {
const users = await prisma.user.findMany({
select: { id: true, name: true, email: true },
})
return (
<div>
<h1>Users</h1>
<ul>
{users.map((user) => (
<li key={user.id}>{user.name} ({user.email})</li>
))}
</ul>
</div>
)
}Next.js App Router
Next.js integrates React Server Components and Server Actions for a complete solution. Server Components fetch data directly from the database for initial page loads, while Server Actions handle data mutations without building separate API routes.
Next.js automatically manages rendering strategies, letting you focus on your application logic while Prisma handles your database connections and queries.
// app/users/page.tsx
import { PrismaPg } from '@prisma/adapter-pg'
import { PrismaClient } from '../generated/client'
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL,
})
const prisma = new PrismaClient({ adapter })
export default async function UsersPage() {
const users = await prisma.user.findMany()
return (
<div>
<h1>Users</h1>
<ul>{users.map((user) => <li key={user.id}>{user.name}</li>)}</ul>
</div>
)
}
// app/actions.ts (Server Action)
'use server'
import { PrismaPg } from '@prisma/adapter-pg'
import { PrismaClient } from '../generated/client'
import { revalidatePath } from 'next/cache'
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL,
})
const prisma = new PrismaClient({ adapter })
export async function createUser(formData: FormData) {
const name = formData.get('name') as string
const email = formData.get('email') as string
await prisma.user.create({ data: { name, email } })
revalidatePath('/users')
}Remix
Remix uses a loader and action pattern for server-side data. The loader function accesses your database using Prisma to fetch data before component rendering, while actions handle form submissions and data mutations.
This approach provides a clean separation between data fetching and UI rendering, with Prisma ORM's type-safety ensuring your database queries are correct.
// app/routes/users.tsx
import { PrismaPg } from '@prisma/adapter-pg'
import { PrismaClient } from '../generated/client'
import { json, type ActionFunctionArgs } from '@remix-run/node'
import { Form, useLoaderData } from '@remix-run/react'
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL,
})
const prisma = new PrismaClient({ adapter })
export async function loader() {
const users = await prisma.user.findMany()
return json({ users })
}
export async function action({ request }: ActionFunctionArgs) {
const formData = await request.formData()
await prisma.user.create({
data: { name: formData.get('name') as string, email: formData.get('email') as string }
})
return json({ success: true })
}
export default function Users() {
const { users } = useLoaderData<typeof loader>()
return (
<div>
<ul>{users.map((user) => <li key={user.id}>{user.name}</li>)}</ul>
<Form method="post">
<input name="name" />
<input name="email" type="email" />
<button type="submit">Add User</button>
</Form>
</div>
)
}React Router 7 Framework
React Router's new framework capabilities adopt similar patterns to Remix. Loaders fetch data from your database using Prisma before rendering, and actions handle form submissions.
This approach provides a lightweight framework option that maintains React Router's familiar API while adding powerful data fetching capabilities through Prisma.
// routes/users.tsx
import { PrismaPg } from '@prisma/adapter-pg'
import { PrismaClient } from '../generated/client'
import { Form, useLoaderData } from 'react-router-dom'
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL,
})
const prisma = new PrismaClient({ adapter })
export async function loader() {
const users = await prisma.user.findMany()
return { users }
}
export async function action({ request }) {
const formData = await request.formData()
await prisma.user.create({
data: { name: formData.get('name'), email: formData.get('email') }
})
return { success: true }
}
export default function Users() {
const { users } = useLoaderData()
return (
<div>
<ul>{users.map(user => <li key={user.id}>{user.name}</li>)}</ul>
<Form method="post">
<input name="name" placeholder="Name" />
<input name="email" placeholder="Email" />
<button type="submit">Add User</button>
</Form>
</div>
)
}Resources
Featured Prisma & React community examples
Modern Saas Starter Kit: next-forge
A starter template for modern SaaS apps with React! next-forge comes with Next.js 15, auth, DB & ORM, payments, docs, blog, o11y, analytics, emails, and a lot more, to save you the initial boilerplate for your next Next.js SaaS app.
Remix Blues Stack
The Remix Blues Stack provides a complete, production-ready template with Docker-based multi-region deployment on Fly.io, PostgreSQL database integration via Prisma ORM, and authentication using cookie-based sessions.
t3 Stack
t3 is a web development stack focused on simplicity, modularity, and full-stack type safety. It includes Next.js, tRPC, Tailwind, TypeScript, Prisma and NextAuth.
Blitz.js
Blitz.js is an application framework that is built on top of Next.js and Prisma. It brings back the simplicity and conventions of server-rendered frameworks like Ruby on Rails while preserving everything developers love about React and client-side rendering.
Fullstack Form Builder
This comprehensive 4-hour tutorial teaches you how to build a fullstack form application with drag & drop functionality, layout fields, and field types like text, number, dropdowns, dates, checkbox and text areas.

