## Introduction

Prisma ORM simplifies database interactions, and [TanStack Start](https://tanstack.com/start/latest/docs/framework/react/guide/server-functions) offers a robust framework for building modern React applications. Together with [Prisma Postgres](https://www.prisma.io/postgres), they provide a seamless full-stack development experience with type-safe queries and efficient data management.

This guide will walk you through integrating Prisma ORM with a Prisma Postgres database in a TanStack Start project from scratch.

## Prerequisites
- [Node.js 20+](https://nodejs.org)

## 1. Set up your project

To begin, create a new TanStack Start project. 

```terminal
npm create @tanstack/start@latest
```

:::info
- *What would you like to name your project?* tanstack-start-prisma
- *Would you like to use Tailwind CSS?* No
- *Select Toolchain* None 
- *Select deployment adapter* Nitro 
- *What add-ons would you like for your project?* Prisma 
- *Would you like any examples?* No
- *Prisma: Database Provider* Prisma PostgresSQL
:::

This will create a new folder called `tanstack-start-prisma` and create a new Prisma Postgres
Database for you. The final database connection string will be printed out.

```shell
●  Database Connection
│
│    Connection String:
│
│    postgresql://b4889.....
│
```

Copy this connection string and set the `DATABASE_URL` variable in `.env.local`:

``` 
# Database URL for PostgreSQL
DATABASE_URL="postgresql://b4889....."
```

## 2. Configure Prisma

### 2.1. Define your Prisma Schema

In `schema.prisma`, the model for our todos is defined below the generator and datasource blocks:

```prisma file=prisma/schema.prisma
generator client {
  provider = "prisma-client"
  output   = "../app/generated/prisma"
}

datasource db {
  provider = "postgresql"
}

model Todo {
  id        Int      @id @default(autoincrement())
  title     String
  createdAt DateTime @default(now())
}
```

This creates a `Todo` model that will be pushed to the database

### 2.2. Configure the Prisma Client generator

Now, run the following command to create the database tables:

```terminal
npm run db:seed -- --name init
```
### 2.3. Seed the database

Generate the Prisma Client needed for the project;

```terminal
npm run db:generate
```

Then seed the project with the `seed.ts` file in the `prisma/` directory: 

```terminal
npm run db:seed
```

And open Prisma Studio to inspect your data:

```terminal
npm run db:studio
```

## 3. Integrate Prisma into TanStack Start

### 3.1 The Prisma Client

Instead of creating a new Prisma Client instance in each file, TanStack Start has a `db.ts` that
creates a single instance that can be shared globally 

```tsx file=src/db.ts
import { PrismaClient } from './generated/prisma/client.js'

import { PrismaPg } from '@prisma/adapter-pg'

const adapter = new PrismaPg({
  connectionString: process.env.DATABASE_URL!,
})

declare global {
  var __prisma: PrismaClient | undefined
}

export const prisma = globalThis.__prisma || new PrismaClient({ adapter })

if (process.env.NODE_ENV !== 'production') {
  globalThis.__prisma = prisma
}
```


### 3.2 Fetch data on load

First, import the necessary modules. Then, create a server function using the [`createServerFn`](https://tanstack.com/start/latest/docs/framework/react/guide/server-functions) function. This function will fetch the data from the database using the `.findMany()` method

```typescript file=src/routes/index.tsx
import { createFileRoute } from "@tanstack/react-router";
// add-start
import { createServerFn } from "@tanstack/react-start";
import { prisma } from '../db';
// add-end

export const Route = createFileRoute("/")({
  component: Home,
});

// add-start
const getTodos = createServerFn({ method: "GET" }).handler(async () => {
  return prisma.todo.findMany();
});
// add-end

function Home() {
  return (
    <div>
    </div>
  );
}
```

TanStack Start allows functions to run on load with loader functions in the [`createFileRoute`](https://tanstack.com/router/latest/docs/framework/react/api/router/createFileRouteFunction) function. Fetch the users and their posts on load with this code:

```typescript file=app/routes/index.tsx
import { createFileRoute } from '@tanstack/react-router';
import { createServerFn } from '@tanstack/react-start';
import { prisma } from '../db';

export const Route = createFileRoute("/")({
  component: Home,
  // add-start
  loader: () => {
    return getTodos();
  },
  // add-end
});

const getTodos = createServerFn({ method: "GET" }).handler(async () => {
  return prisma.todo.findMany();
});

function Home() {
  return (
    <div>
      <h1>Todos</h1>
    </div>
  );
}
```

Store the response from the loader in the main component using [`Route.useLoaderData()`](https://tanstack.com/router/latest/docs/framework/react/api/router/useLoaderDataHook):

```typescript file=app/routes/index.tsx
import { createServerFn } from "@tanstack/react-start";
import { createFileRoute } from "@tanstack/react-router";
import { prisma } from '../db';

export const Route = createFileRoute("/")({
  component: Home,
  loader: () => {
    return getTodos();
  },
});

const getTodos = createServerFn({ method: "GET" }).handler(async () => {
  return prisma.todo.findMany();
});

function Home() {
  // add-start
  const todos = Route.useLoaderData();
  // add-end

  return (
    <div>
      <h1>Todos</h1>
    </div>
  );
}
```

### 3.3 Display the todos

Next, you'll update the home page to display the data retrieved from your database.

Map over the `todos` and display them in a list:

```typescript file=app/routes/index.tsx
import { createFileRoute } from '@tanstack/react-router';
import { createServerFn } from '@tanstack/react-start';
import { prisma } from '../db';

export const Route = createFileRoute('/')({
  component: App,
  loader: () => getTodos(),
});

const getTodos = createServerFn({ method: 'GET' }).handler(async () => {
  return prisma.todo.findMany();
});

function App() {
  const todos = Route.useLoaderData();
  
  return (
    <div>
      <ul>
        {todos.map(todo => (
          <li key={todo.id}>{todo.title}</li>
        ))}
      </ul>
    </div>
  );
}
```

This setup will display the todos on your page, fetched directly from your database.

## Next steps

You've successfully integrated Prisma ORM with TanStack Start, creating a seamless full-stack application. Here are a few suggestions for what you can do next:

- Expand your Prisma models to handle more complex data relationships.
- Implement additional CRUD operations to enhance your application's functionality.
- Explore more features of Prisma and TanStack Start to deepen your understanding.
- Check out [Prisma Postgres](https://www.prisma.io/postgres) to see how you can scale your application.

## More info

- [Prisma ORM Documentation](/orm/overview/introduction)
- [TanStack Start Documentation](https://tanstack.com/start/latest/docs/framework/react/overview)
---

# How to use Prisma ORM and Prisma Postgres with React Router 7