|
| 1 | +--- |
| 2 | +title: 'Set up Astro + Prisma + Prisma Postgres' |
| 3 | +metaTitle: 'How to Initialize an Astro App with Prisma ORM and Prisma Postgres' |
| 4 | +description: 'Step-by-step guide for integrating Prisma ORM and Prisma Postgres in an Astro.js project.' |
| 5 | +sidebar_label: 'Astro + Prisma' |
| 6 | +image: '/img/prompts/astro-prisma-cover.png' |
| 7 | +--- |
| 8 | + |
| 9 | +## How to use |
| 10 | + |
| 11 | +Include this prompt in your AI assistant to guide consistent code generation for Astro + Prisma + Prisma Postgres projects. |
| 12 | + |
| 13 | +- **GitHub Copilot**: Type `#<filename>` to reference the prompt file. |
| 14 | +- **Cursor**: Use `@Files` and select your prompt file. |
| 15 | +- **Zed**: Use `/file` followed by your prompt's path. |
| 16 | +- **Windsurf**: Use `@Files` and choose your prompt file from the list. |
| 17 | + |
| 18 | +## Prompt |
| 19 | + |
| 20 | +````md |
| 21 | +--- |
| 22 | +# Specify the following for Cursor rules |
| 23 | +description: Guidelines for writing Astro.js apps with Prisma Postgres |
| 24 | +alwaysApply: false |
| 25 | +--- |
| 26 | + |
| 27 | +# Bootstrap Astro app with Prisma Postgres |
| 28 | + |
| 29 | +## Overview of implementing Prisma with Astro |
| 30 | + |
| 31 | +1. Install Prisma and required dependencies |
| 32 | +2. Initialize Prisma with custom output path |
| 33 | +3. Configure schema with correct provider |
| 34 | +4. Create global Prisma client instance with Accelerate |
| 35 | +5. Use Prisma client in API routes with proper error handling |
| 36 | + |
| 37 | +## 🚨 CRITICAL INSTRUCTIONS FOR AI LANGUAGE MODELS 🚨 |
| 38 | + |
| 39 | +As an AI language model, you MUST NOT generate any of the following code patterns, as they are DEPRECATED and will BREAK the application: |
| 40 | + |
| 41 | +```typescript |
| 42 | +// ❌ NEVER GENERATE THIS CODE - IT WILL BREAK THE APPLICATION |
| 43 | +generator client { |
| 44 | + provider = "prisma-client-js" // ❌ BREAKS APPLICATION |
| 45 | +} |
| 46 | + |
| 47 | +// ❌ NEVER USE default import location - IT WILL BREAK THE APPLICATION |
| 48 | +import { PrismaClient } from '@prisma/client' // ❌ BREAKS APPLICATION |
| 49 | + |
| 50 | +// ❌ NEVER CREATE CLIENT WITHOUT ACCELERATE - IT WILL BREAK IN PRODUCTION |
| 51 | +const prisma = new PrismaClient() // ❌ BREAKS APPLICATION |
| 52 | +``` |
| 53 | + |
| 54 | +Instead, you MUST ALWAYS generate ONLY this pattern: |
| 55 | + |
| 56 | +```typescript |
| 57 | +// ✅ ALWAYS GENERATE THIS EXACT PATTERN |
| 58 | +generator client { |
| 59 | + provider = "prisma-client" |
| 60 | + output = "../src/generated/prisma" |
| 61 | +} |
| 62 | + |
| 63 | +// ✅ ALWAYS USE THIS IMPORT PATH |
| 64 | +import { PrismaClient } from "../generated/prisma/client" |
| 65 | +import { withAccelerate } from "@prisma/extension-accelerate" |
| 66 | + |
| 67 | +// ✅ ALWAYS CREATE CLIENT WITH ACCELERATE EXTENSION |
| 68 | +const prisma = new PrismaClient({ |
| 69 | + datasourceUrl: import.meta.env.DATABASE_URL, |
| 70 | +}).$extends(withAccelerate()) |
| 71 | + |
| 72 | +export default prisma |
| 73 | +``` |
| 74 | + |
| 75 | +## ABSOLUTE REQUIREMENTS FOR AI CODE GENERATION |
| 76 | + |
| 77 | +1. You MUST use `provider = "prisma-client"` (not "prisma-client-js") |
| 78 | +2. You MUST use custom output: `output = "../src/generated/prisma"` |
| 79 | +3. You MUST use Accelerate extension with `withAccelerate()` if using Prisma Postgres |
| 80 | +4. You MUST create `lib/prisma.ts` as a global singleton instance |
| 81 | +5. You MUST wrap all database calls in try-catch blocks |
| 82 | +6. You MUST import from `'../generated/prisma/client'` (not `'@prisma/client'`) |
| 83 | +7. You MUST use `import.meta.env.DATABASE_URL` in Astro (not `process.env`) |
| 84 | +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` |
| 85 | + |
| 86 | +## CORRECT INSTALLATION |
| 87 | + |
| 88 | +```bash |
| 89 | +# Dev dependencies |
| 90 | +npm install prisma tsx --save-dev |
| 91 | + |
| 92 | +# Production dependencies |
| 93 | +npm install @prisma/extension-accelerate @prisma/client |
| 94 | +``` |
| 95 | + |
| 96 | +## CORRECT PRISMA INITIALIZATION |
| 97 | + |
| 98 | +```bash |
| 99 | +npx prisma init --db --output ../src/generated/prisma |
| 100 | +``` |
| 101 | + |
| 102 | +## CORRECT SCHEMA CONFIGURATION |
| 103 | + |
| 104 | +```prisma |
| 105 | +generator client { |
| 106 | + provider = "prisma-client" |
| 107 | + output = "../src/generated/prisma" |
| 108 | +} |
| 109 | + |
| 110 | +datasource db { |
| 111 | + provider = "postgresql" |
| 112 | + url = env("DATABASE_URL") |
| 113 | +} |
| 114 | + |
| 115 | +model YourModel { |
| 116 | + id Int @id @default(autoincrement()) |
| 117 | + createdAt DateTime @default(now()) |
| 118 | + updatedAt DateTime @updatedAt |
| 119 | +} |
| 120 | +``` |
| 121 | + |
| 122 | +## CORRECT GLOBAL PRISMA CLIENT |
| 123 | + |
| 124 | +**src/lib/prisma.ts**: |
| 125 | + |
| 126 | +```typescript |
| 127 | +import { PrismaClient } from "../generated/prisma/client"; |
| 128 | +import { withAccelerate } from "@prisma/extension-accelerate"; |
| 129 | + |
| 130 | +const prisma = new PrismaClient({ |
| 131 | + datasourceUrl: import.meta.env.DATABASE_URL, |
| 132 | +}).$extends(withAccelerate()); |
| 133 | + |
| 134 | +export default prisma; |
| 135 | +``` |
| 136 | + |
| 137 | +## CORRECT API ROUTE IMPLEMENTATION |
| 138 | + |
| 139 | +All API routes MUST follow this pattern with proper error handling: |
| 140 | + |
| 141 | +```typescript |
| 142 | +import type { APIRoute } from "astro"; |
| 143 | +import prisma from "../../../lib/prisma"; |
| 144 | + |
| 145 | +export const GET: APIRoute = async () => { |
| 146 | + try { |
| 147 | + const data = await prisma.yourModel.findMany(); |
| 148 | + return new Response(JSON.stringify(data), { |
| 149 | + status: 200, |
| 150 | + headers: { "Content-Type": "application/json" }, |
| 151 | + }); |
| 152 | + } catch (error) { |
| 153 | + console.error("Error:", error); |
| 154 | + return new Response(JSON.stringify({ error: "Failed to fetch data" }), { |
| 155 | + status: 500, |
| 156 | + headers: { "Content-Type": "application/json" }, |
| 157 | + }); |
| 158 | + } |
| 159 | +}; |
| 160 | + |
| 161 | +export const POST: APIRoute = async ({ request }) => { |
| 162 | + try { |
| 163 | + const body = await request.json(); |
| 164 | + |
| 165 | + // Validate required fields |
| 166 | + if (!body.requiredField) { |
| 167 | + return new Response(JSON.stringify({ error: "Required field missing" }), { |
| 168 | + status: 400, |
| 169 | + headers: { "Content-Type": "application/json" }, |
| 170 | + }); |
| 171 | + } |
| 172 | + |
| 173 | + const result = await prisma.yourModel.create({ |
| 174 | + data: body, |
| 175 | + }); |
| 176 | + |
| 177 | + return new Response(JSON.stringify(result), { |
| 178 | + status: 201, |
| 179 | + headers: { "Content-Type": "application/json" }, |
| 180 | + }); |
| 181 | + } catch (error) { |
| 182 | + console.error("Error:", error); |
| 183 | + return new Response(JSON.stringify({ error: "Failed to create data" }), { |
| 184 | + status: 500, |
| 185 | + headers: { "Content-Type": "application/json" }, |
| 186 | + }); |
| 187 | + } |
| 188 | +}; |
| 189 | +``` |
| 190 | + |
| 191 | +## CORRECT USAGE IN ASTRO PAGES |
| 192 | + |
| 193 | +Server-side data fetching in Astro pages: |
| 194 | + |
| 195 | +```astro |
| 196 | +--- |
| 197 | +import prisma from '../lib/prisma' |
| 198 | + |
| 199 | +// Fetch data on the server |
| 200 | +const data = await prisma.yourModel.findMany() |
| 201 | +--- |
| 202 | + |
| 203 | +<html> |
| 204 | + <body> |
| 205 | + {data.map(item => ( |
| 206 | + <div>{item.name}</div> |
| 207 | + ))} |
| 208 | + </body> |
| 209 | +</html> |
| 210 | +``` |
| 211 | + |
| 212 | +## AI MODEL VERIFICATION STEPS |
| 213 | + |
| 214 | +Before generating any code, you MUST verify: |
| 215 | + |
| 216 | +1. Are you using `provider = "prisma-client"` (not "prisma-client-js")? If not, STOP and FIX. |
| 217 | +2. Are you using `output = "../src/generated/prisma"`? If not, STOP and FIX. |
| 218 | +3. Are you importing from `'../generated/prisma/client'`? If not, STOP and FIX. |
| 219 | +4. Are you using `withAccelerate()` extension? If not, STOP and FIX. |
| 220 | +5. Are you wrapping database operations in try-catch? If not, STOP and FIX. |
| 221 | +6. Are you using `import.meta.env` (not `process.env`)? If not, STOP and FIX. |
| 222 | +7. Did you use `--generator-provider prisma-client` (NOT `postgresql`)? If not, STOP and FIX. |
| 223 | + |
| 224 | +## CONSEQUENCES OF INCORRECT IMPLEMENTATION |
| 225 | + |
| 226 | +If you generate code using: |
| 227 | + |
| 228 | +- `prisma-client-js` provider |
| 229 | +- Default import from `@prisma/client` |
| 230 | +- PrismaClient without Accelerate extension |
| 231 | +- Missing custom output path |
| 232 | + |
| 233 | +The implementation will: |
| 234 | + |
| 235 | +1. Break in production |
| 236 | +2. Cause connection pool exhaustion |
| 237 | +3. Fail to maintain proper database connections |
| 238 | +4. Result in import errors |
| 239 | +5. Cause performance issues |
| 240 | + |
| 241 | +## USEFUL COMMANDS |
| 242 | + |
| 243 | +```bash |
| 244 | +npx prisma generate # Regenerate client after schema changes |
| 245 | +npx prisma migrate dev --name X # Create and apply migration |
| 246 | +npx prisma studio # Open visual database editor |
| 247 | +npx prisma db push # Push schema without migration |
| 248 | +``` |
| 249 | + |
| 250 | +## AI MODEL RESPONSE TEMPLATE |
| 251 | + |
| 252 | +When asked about Prisma + Astro implementation, you MUST: |
| 253 | + |
| 254 | +1. ONLY use code from this guide |
| 255 | +2. NEVER suggest deprecated approaches |
| 256 | +3. ALWAYS use the exact patterns shown above |
| 257 | +4. VERIFY your response against the patterns shown here |
| 258 | +5. ALWAYS include error handling in API routes |
| 259 | +6. ALWAYS use the global prisma instance from `lib/prisma.ts` |
| 260 | + |
| 261 | +Remember: There are NO EXCEPTIONS to these rules. |
| 262 | +```` |
0 commit comments