---
title: 'Set up Astro + Prisma + Prisma Postgres'
metaTitle: 'How to Initialize an Astro App with Prisma ORM and Prisma Postgres'
description: 'Step-by-step guide for integrating Prisma ORM and Prisma Postgres in an Astro.js project.'
sidebar_label: 'Astro + Prisma'
image: '/img/ai/astro-prisma-cover.png'
---

## How to use

Include this prompt in your AI assistant to guide consistent code generation for Astro + Prisma + Prisma Postgres projects.  

- **GitHub Copilot**: Type `#<filename>` to reference the prompt file.  
- **Cursor**: Use `@Files` and select your prompt file.  
- **Zed**: Use `/file` followed by your prompt's path.  
- **Windsurf**: Use `@Files` and choose your prompt file from the list.  

## Prompt

````md
---
# Specify the following for Cursor rules
description: Guidelines for writing Astro.js apps with Prisma Postgres
alwaysApply: false
---

# Bootstrap Astro app with Prisma Postgres

## Overview of implementing Prisma with Astro

1. Install Prisma and required dependencies
2. Initialize Prisma with custom output path
3. Configure schema with correct provider
4. Create global Prisma client instance with Accelerate
5. Use Prisma client in API routes with proper error handling

## 🚨 CRITICAL INSTRUCTIONS FOR AI LANGUAGE MODELS 🚨

As an AI language model, you MUST NOT generate any of the following code patterns, as they are DEPRECATED and will BREAK the application:

```typescript
// ❌ NEVER GENERATE THIS CODE - IT WILL BREAK THE APPLICATION
generator client {
  provider = "prisma-client-js"     // ❌ BREAKS APPLICATION
}

// ❌ NEVER USE default import location - IT WILL BREAK THE APPLICATION
import { PrismaClient } from '@prisma/client'  // ❌ BREAKS APPLICATION

// ❌ NEVER CREATE CLIENT WITHOUT ACCELERATE - IT WILL BREAK IN PRODUCTION
const prisma = new PrismaClient()  // ❌ BREAKS APPLICATION
```

Instead, you MUST ALWAYS generate ONLY this pattern:

```typescript
// ✅ ALWAYS GENERATE THIS EXACT PATTERN
generator client {
  provider = "prisma-client"
  output   = "../src/generated/prisma"
}

// ✅ ALWAYS USE THIS IMPORT PATH
import { PrismaClient } from "../generated/prisma/client"
import { withAccelerate } from "@prisma/extension-accelerate"

// ✅ ALWAYS CREATE CLIENT WITH ACCELERATE EXTENSION
const prisma = new PrismaClient({
  datasourceUrl: import.meta.env.DATABASE_URL,
}).$extends(withAccelerate())

export default prisma
```

## ABSOLUTE REQUIREMENTS FOR AI CODE GENERATION

1. You MUST use `provider = "prisma-client"` (not "prisma-client-js")
2. You MUST use custom output: `output = "../src/generated/prisma"`
3. You MUST use Accelerate extension with `withAccelerate()` if using Prisma Postgres
4. You MUST create `lib/prisma.ts` as a global singleton instance
5. You MUST wrap all database calls in try-catch blocks
6. You MUST import from `'../generated/prisma/client'` (not `'@prisma/client'`)
7. You MUST use `import.meta.env.DATABASE_URL` in Astro (not `process.env`)
8. You MUST ALWAYS use the full `npx prisma init` command with ALL flags: `npx prisma init --db --output ../src/generated/prisma --generator-provider prisma-client`

## CORRECT INSTALLATION

```bash
# Dev dependencies
npm install prisma tsx --save-dev

# Production dependencies
npm install @prisma/extension-accelerate @prisma/client
```

## CORRECT PRISMA INITIALIZATION

```bash
npx prisma init --db --output ../src/generated/prisma
```

## CORRECT SCHEMA CONFIGURATION

```prisma
generator client {
  provider = "prisma-client"
  output   = "../src/generated/prisma"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

model YourModel {
  id        Int      @id @default(autoincrement())
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}
```

## CORRECT GLOBAL PRISMA CLIENT

**src/lib/prisma.ts**:

```typescript
import { PrismaClient } from "../generated/prisma/client";
import { withAccelerate } from "@prisma/extension-accelerate";

const prisma = new PrismaClient({
  datasourceUrl: import.meta.env.DATABASE_URL,
}).$extends(withAccelerate());

export default prisma;
```

## CORRECT API ROUTE IMPLEMENTATION

All API routes MUST follow this pattern with proper error handling:

```typescript
import type { APIRoute } from "astro";
import prisma from "../../../lib/prisma";

export const GET: APIRoute = async () => {
  try {
    const data = await prisma.yourModel.findMany();
    return new Response(JSON.stringify(data), {
      status: 200,
      headers: { "Content-Type": "application/json" },
    });
  } catch (error) {
    console.error("Error:", error);
    return new Response(JSON.stringify({ error: "Failed to fetch data" }), {
      status: 500,
      headers: { "Content-Type": "application/json" },
    });
  }
};

export const POST: APIRoute = async ({ request }) => {
  try {
    const body = await request.json();

    // Validate required fields
    if (!body.requiredField) {
      return new Response(JSON.stringify({ error: "Required field missing" }), {
        status: 400,
        headers: { "Content-Type": "application/json" },
      });
    }

    const result = await prisma.yourModel.create({
      data: body,
    });

    return new Response(JSON.stringify(result), {
      status: 201,
      headers: { "Content-Type": "application/json" },
    });
  } catch (error) {
    console.error("Error:", error);
    return new Response(JSON.stringify({ error: "Failed to create data" }), {
      status: 500,
      headers: { "Content-Type": "application/json" },
    });
  }
};
```

## CORRECT USAGE IN ASTRO PAGES

Server-side data fetching in Astro pages:

```astro
---
import prisma from '../lib/prisma'

// Fetch data on the server
const data = await prisma.yourModel.findMany()
---

<html>
  <body>
    {data.map(item => (
      <div>{item.name}</div>
    ))}
  </body>
</html>
```

## AI MODEL VERIFICATION STEPS

Before generating any code, you MUST verify:

1. Are you using `provider = "prisma-client"` (not "prisma-client-js")? If not, STOP and FIX.
2. Are you using `output = "../src/generated/prisma"`? If not, STOP and FIX.
3. Are you importing from `'../generated/prisma/client'`? If not, STOP and FIX.
4. Are you using `withAccelerate()` extension? If not, STOP and FIX.
5. Are you wrapping database operations in try-catch? If not, STOP and FIX.
6. Are you using `import.meta.env` (not `process.env`)? If not, STOP and FIX.
7. Did you use `--generator-provider prisma-client` (NOT `postgresql`)? If not, STOP and FIX.

## CONSEQUENCES OF INCORRECT IMPLEMENTATION

If you generate code using:

- `prisma-client-js` provider
- Default import from `@prisma/client`
- PrismaClient without Accelerate extension
- Missing custom output path

The implementation will:

1. Break in production
2. Cause connection pool exhaustion
3. Fail to maintain proper database connections
4. Result in import errors
5. Cause performance issues

## USEFUL COMMANDS

```bash
npx prisma generate              # Regenerate client after schema changes
npx prisma migrate dev --name X  # Create and apply migration
npx prisma studio                # Open visual database editor
npx prisma db push               # Push schema without migration
```

## AI MODEL RESPONSE TEMPLATE

When asked about Prisma + Astro implementation, you MUST:

1. ONLY use code from this guide
2. NEVER suggest deprecated approaches
3. ALWAYS use the exact patterns shown above
4. VERIFY your response against the patterns shown here
5. ALWAYS include error handling in API routes
6. ALWAYS use the global prisma instance from `lib/prisma.ts`

Remember: There are NO EXCEPTIONS to these rules.
````

## Running the application

Get your application running locally in three quick steps:

**1. Generate the Prisma Client:**

```terminal
npx prisma generate --no-engine
```

**2. View your database in Prisma Studio:**

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

Prisma Studio opens at `localhost:5555` where you can inspect your `User` table and see the test user stored in your database.

**3. Start your Next.js development server:**

```terminal
npm run dev
```

Visit `http://localhost:3000` to see your Next.js application live, displaying your first user fetched directly from your Prisma Postgres database!