# SolidStart

## [Introduction](#introduction)

SolidStart is a full-stack framework for building reactive web apps with SolidJS. Its API routes and server functions run on the server, which is where you call Prisma ORM to read from a PostgreSQL database.

In this guide, you scaffold a SolidStart project, add Prisma ORM to it with `orm init`, initialize and seed a PostgreSQL database, serve users from an API route, and render them in a page with loading and error states. There is no `create-prisma` template for SolidStart, so this guide follows the add-to-an-existing-project path.

Every command, file, and response below was run end to end against a local PostgreSQL database.

:::callout{intent="note"}
Using Prisma ORM 7?

Prisma ORM 8 is the current release. Prisma ORM 7 remains fully supported; the Prisma ORM 7 version of this guide is at [/guides/v7/frameworks/solid-start](/guides/guides-v7-frameworks-solid-start).
:::

## [Prerequisites](#prerequisites)

- [Node.js](https://nodejs.org/) 24 or later (the SolidStart 2 template requires it)
- A PostgreSQL connection string, or nothing at all: `npx create-db@latest` can create a [Prisma Postgres](/guides/introduction-2-postgres) database for you

## [Use with your agent](#use-with-your-agent)

To delegate this guide to your coding agent, copy the prompt below and hand it over:

```title="Use with your agent Use with your agent"
Create a new SolidStart app with Prisma ORM, seed it, and serve users from an API route and a page.

1. Scaffold: `npm init solid@latest my-solid-prisma-app -- -s --v2 -t basic --ts`. Delete the `pnpm-lock.yaml` the template ships (otherwise Prisma picks pnpm), then `cd my-solid-prisma-app` and run `npm install`.

2. Add Prisma ORM: `npx prisma@latest orm init --yes --target postgres --authoring psl`. Then run `npx prisma@latest init` so the Prisma agent skills are installed and stay current, and use them. Get a database connection string: use the one I give you, or create a Prisma Postgres database with `npx create-db@latest` and show me the claim URL it prints. Write it to `.env` as `DATABASE_URL`.

3. Run `npx prisma db init` to create the tables from `src/prisma/contract.prisma`.

4. Add `src/prisma/seed.ts` that creates two users with posts through `db.orm.public.User.create` and `db.orm.public.Post.create`, closes with `await db.close()`, and run it once with `node src/prisma/seed.ts`.

5. Add `src/routes/api/users.ts` with a `GET` handler that returns `db.orm.public.User.include("posts").all()` as JSON, and replace `src/routes/index.tsx` with a page that loads the same query through a `"use server"` function wrapped in `query` and `createAsync`, with `<Suspense>` for loading and `<ErrorBoundary>` for errors, following https://www.prisma.io/docs/guides/frameworks/solid-start.md. Catch Prisma errors inside the server function and rethrow a plain `Error`.

6. Start `npm run dev` in the background, wait until it reports ready, verify `curl http://localhost:3000/api/users` returns the seeded users and `curl http://localhost:3000/` includes their names, then stop the dev server.
```

## [1. Scaffold the SolidStart project](#1-scaffold-the-solidstart-project)

Create a new SolidStart 2 project from the `basic` TypeScript template:

::::tabs
:::tab{title="bun"}
```
bunx create-solid my-solid-prisma-app -s --v2 -t basic --ts
```
:::

:::tab{title="pnpm"}
```bash
pnpm create solid my-solid-prisma-app -s --v2 -t basic --ts
```
:::

:::tab{title="yarn"}
```bash
yarn create solid my-solid-prisma-app -s --v2 -t basic --ts
```
:::

:::tab{title="npm"}
```bash
npm init solid@latest my-solid-prisma-app -- -s --v2 -t basic --ts
```

```text no-copy
◇  Project created 🎉
◇  To get started, run: ───╮
│  cd my-solid-prisma-app  │
│  npm install             │
│  npm run dev             │
```

The flags skip the prompts: `-s` picks SolidStart, `--v2` picks the stable SolidStart 2 line, `-t basic` picks the template, and `--ts` picks TypeScript. Without them, the CLI asks the same questions interactively.

The template ships a `pnpm-lock.yaml`. Delete it before you continue if you use npm; otherwise `orm init` reads the lockfile and installs Prisma with pnpm:

```bash
cd my-solid-prisma-app
rm pnpm-lock.yaml
```

Install the dependencies:
:::
::::

```
◇  Project created 🎉

◇  To get started, run: ───╮

│  cd my-solid-prisma-app  │

│  npm install             │

│  npm run dev             │
```

The flags skip the prompts: `-s` picks SolidStart, `--v2` picks the stable SolidStart 2 line, `-t basic` picks the template, and `--ts` picks TypeScript. Without them, the CLI asks the same questions interactively.

The template ships a `pnpm-lock.yaml`. Delete it before you continue if you use npm; otherwise `orm init` reads the lockfile and installs Prisma with pnpm:

```
cd my-solid-prisma-app

rm pnpm-lock.yaml
```

Install the dependencies:

:::code-group
```title="bun"
bun install
```

```bash title="pnpm"
pnpm install
```

```bash title="yarn"
yarn install
```

```bash title="npm"
npm install
```
:::

This writes `package-lock.json`, so the next step picks npm.

## [2. Add Prisma ORM](#2-add-prisma-orm)

Run `orm init` from the project root. The flags preselect PostgreSQL and the Prisma Schema Language; drop `--yes` and `--authoring` to answer those questions interactively:

::::tabs
:::tab{title="bun"}
```
bunx prisma@latest orm init --yes --target postgres --authoring psl
```
:::

:::tab{title="pnpm"}
```bash
pnpm dlx prisma@latest orm init --yes --target postgres --authoring psl
```
:::

:::tab{title="yarn"}
```bash
yarn dlx prisma@latest orm init --yes --target postgres --authoring psl
```
:::

:::tab{title="npm"}
```bash
npx prisma@latest orm init --yes --target postgres --authoring psl
```

```text no-copy
Updated tsconfig.json with required compiler options.
✔ npm add @prisma/orm-postgres dotenv
✔ npm add -D prisma@latest @types/node
✔ npm add -D @prisma/cli-engine@0.6.1
✔ Emit the contract
│  target:     postgres
│  authoring:  psl
│  schema:     src/prisma/contract.prisma
written
├─ src/prisma/contract.prisma
├─ prisma.config.ts
├─ src/prisma/db.ts
├─ prisma-8.md
├─ .env.example
├─ tsconfig.json
├─ .gitignore
├─ .gitattributes
└─ package.json
✔ Done. Open prisma-8.md to get started.
```

The command installs the runtime, writes the Prisma ORM files into the SolidStart project, and emits `src/prisma/contract.json` and `src/prisma/contract.d.ts`, the artifacts your queries are type-checked against. Three files matter for the rest of this guide:

- `src/prisma/contract.prisma`: a starter contract with `User` and `Post` models and a one-to-many relation between them
- `src/prisma/db.ts`: the Prisma ORM client, constructed once and imported by your routes
- `prisma.config.ts`: tells the CLI where the contract lives and reads `DATABASE_URL` from `.env`

The starter contract is the same shape the Prisma ORM 7 guide asked you to write by hand:

```prisma title="src/prisma/contract.prisma"
// use prisma-8

model User {
  id        Int      @id @default(autoincrement())
  email     String   @unique
  username  String?
  name      String?
  posts     Post[]
  createdAt TimestamptzString @default(now())
  updatedAt temporal.updatedAtString()
}

model Post {
  id        Int      @id @default(autoincrement())
  title     String
  content   String?
  author    User     @relation(fields: [authorId], references: [id])
  authorId  Int
  createdAt TimestamptzString @default(now())
  updatedAt temporal.updatedAtString()
}
```

And the scaffolded client is all the wiring the app needs. There is no `prisma generate`, no generated client directory, and no driver adapter; the emitted contract and the runtime package replace all three:

```typescript title="src/prisma/db.ts"
import 'dotenv/config';
import postgres from '@prisma/orm-postgres/runtime';
import type { Contract } from './contract.d';
import contractJson from './contract.json' with { type: 'json' };

export const db = postgres<Contract>({
  contractJson,
  url: process.env['DATABASE_URL']!,
});
```

`orm init` also adds `"node"` to the `types` array and `resolveJsonModule` to `tsconfig.json` so the JSON contract import type-checks, and leaves the SolidStart settings (`jsx`, `jsxImportSource`, the `~/*` path alias) alone.

Now set the database connection. Copy `.env.example` to `.env` and replace the placeholder with your own PostgreSQL connection string, or create a Prisma Postgres database with `npx create-db@latest`; it prints a connection string and a claim URL you can open to keep the database:

```bash title=".env"
DATABASE_URL="postgres://user:password@localhost:5432/mydb"
```

Both `prisma.config.ts` and `db.ts` import `dotenv/config`, so the CLI and the dev server read the same file.
:::
::::

```
Updated tsconfig.json with required compiler options.

✔ npm add @prisma/orm-postgres dotenv

✔ npm add -D prisma@latest @types/node

✔ npm add -D @prisma/cli-engine@0.6.1

✔ Emit the contract

│  target:     postgres

│  authoring:  psl

│  schema:     src/prisma/contract.prisma

written

├─ src/prisma/contract.prisma

├─ prisma.config.ts

├─ src/prisma/db.ts

├─ prisma-8.md

├─ .env.example

├─ tsconfig.json

├─ .gitignore

├─ .gitattributes

└─ package.json

✔ Done. Open prisma-8.md to get started.
```

The command installs the runtime, writes the Prisma ORM files into the SolidStart project, and emits `src/prisma/contract.json` and `src/prisma/contract.d.ts`, the artifacts your queries are type-checked against. Three files matter for the rest of this guide:

- `src/prisma/contract.prisma`: a starter contract with `User` and `Post` models and a one-to-many relation between them
- `src/prisma/db.ts`: the Prisma ORM client, constructed once and imported by your routes
- `prisma.config.ts`: tells the CLI where the contract lives and reads `DATABASE_URL` from `.env`

The starter contract is the same shape the Prisma ORM 7 guide asked you to write by hand:

```title="src/prisma/contract.prisma"
// use prisma-8

model User {

  id        Int      @id @default(autoincrement())

  email     String   @unique

  username  String?

  name      String?

  posts     Post[]

  createdAt TimestamptzString @default(now())

  updatedAt temporal.updatedAtString()

}

model Post {

  id        Int      @id @default(autoincrement())

  title     String

  content   String?

  author    User     @relation(fields: [authorId], references: [id])

  authorId  Int

  createdAt TimestamptzString @default(now())

  updatedAt temporal.updatedAtString()

}
```

And the scaffolded client is all the wiring the app needs. There is no `prisma generate`, no generated client directory, and no driver adapter; the emitted contract and the runtime package replace all three:

```title="src/prisma/db.ts"
import 'dotenv/config';

import postgres from '@prisma/orm-postgres/runtime';

import type { Contract } from './contract.d';

import contractJson from './contract.json' with { type: 'json' };

export const db = postgres<Contract>({

  contractJson,

  url: process.env['DATABASE_URL']!,

});
```

`orm init` also adds `"node"` to the `types` array and `resolveJsonModule` to `tsconfig.json` so the JSON contract import type-checks, and leaves the SolidStart settings (`jsx`, `jsxImportSource`, the `~/*` path alias) alone.

Now set the database connection. Copy `.env.example` to `.env` and replace the placeholder with your own PostgreSQL connection string, or create a Prisma Postgres database with `npx create-db@latest`; it prints a connection string and a claim URL you can open to keep the database:

```title=".env"
DATABASE_URL="postgres://user:password@localhost:5432/mydb"
```

Both `prisma.config.ts` and `db.ts` import `dotenv/config`, so the CLI and the dev server read the same file.

## [3. Initialize the database](#3-initialize-the-database)

Create the tables the contract declares and sign the database:

::::tabs
:::tab{title="bun"}
```
bunx prisma db init
```
:::

:::tab{title="pnpm"}
```bash
pnpm prisma db init
```
:::

:::tab{title="yarn"}
```bash
yarn prisma db init
```
:::

:::tab{title="npm"}
```bash
npx prisma db init
```

```text no-copy
✔ Introspecting database schema
✔ Planning migration
✔ Initialising database across spaces
│  contract:  src/prisma/contract.json
│  database:  postgres://****@localhost:5432/mydb

✔ Applied 5 operation(s) across 1 contract space

App space
├─ Create table "Post"
├─ Create table "User"
├─ Add unique constraint on "User" (email)
├─ Create index "Post_authorId_idx_e47547ed" on "Post"
├─ Add foreign key "Post_authorId_fkey" on "Post"
└─ marker 91e7f9f035806fa2789a4d726ef7724cad434fd6b00014d47ebf12d6e6bb784e
```

`db init` replaces `prisma migrate dev` from Prisma ORM 7 for the first apply: it creates what is missing and records the contract hash in the database. Later schema changes go through [`db update`](/guides/orm-db-update) for a direct development update or [`migration plan`](/guides/migration-migration-plan) for a checked-in migration. To confirm the database matches the contract at any time, run `npx prisma db verify`.
:::
::::

```
✔ Introspecting database schema

✔ Planning migration

✔ Initialising database across spaces

│  contract:  src/prisma/contract.json

│  database:  postgres://****@localhost:5432/mydb

✔ Applied 5 operation(s) across 1 contract space

App space

├─ Create table "Post"

├─ Create table "User"

├─ Add unique constraint on "User" (email)

├─ Create index "Post_authorId_idx_e47547ed" on "Post"

├─ Add foreign key "Post_authorId_fkey" on "Post"

└─ marker 91e7f9f035806fa2789a4d726ef7724cad434fd6b00014d47ebf12d6e6bb784e
```

`db init` replaces `prisma migrate dev` from Prisma ORM 7 for the first apply: it creates what is missing and records the contract hash in the database. Later schema changes go through [`db update`](/guides/orm-db-update) for a direct development update or [`migration plan`](/guides/migration-migration-plan) for a checked-in migration. To confirm the database matches the contract at any time, run `npx prisma db verify`.

## [4. Seed the database](#4-seed-the-database)

Create `src/prisma/seed.ts`. It creates two users and their posts through the ORM API. `create()` returns the inserted row, so the user's `id` is available for the posts without a second query:

```title="src/prisma/seed.ts"
import { db } from "./db.ts";

const users = [

  {

    name: "Alice",

    email: "alice@prisma.io",

    posts: [

      { title: "Join the Prisma Discord", content: "https://pris.ly/discord" },

      { title: "Prisma on YouTube", content: "https://pris.ly/youtube" },

    ],

  },

  {

    name: "Bob",

    email: "bob@prisma.io",

    posts: [{ title: "Follow Prisma on Twitter", content: "https://www.twitter.com/prisma" }],

  },

];

async function main() {

  for (const { posts, ...user } of users) {

    const created = await db.orm.public.User.create(user);

    for (const post of posts) {

      await db.orm.public.Post.create({ ...post, authorId: created.id });

    }

    console.log(`Seeded ${created.email} with ${posts.length} post(s)`);

  }

  await db.close();

}

main().catch((error) => {

  console.error(error);

  process.exit(1);

});
```

Node.js 24 runs TypeScript directly, so no extra tooling is needed. Run the script once:

```
node src/prisma/seed.ts
```

```
Seeded alice@prisma.io with 2 post(s)

Seeded bob@prisma.io with 1 post(s)
```

Running it a second time fails on the unique `email` constraint, which is expected. The script closes the connection pool at the end because a one-off script would otherwise keep the process alive; the app's routes never do this.

## [5. Serve users from an API route](#5-serve-users-from-an-api-route)

SolidStart maps files under `src/routes/api/` to HTTP endpoints. Create `src/routes/api/users.ts`:

```title="src/routes/api/users.ts"
import { db } from "~/prisma/db";

export async function GET() {

  const users = await db.orm.public.User.include("posts").all();

  return Response.json(users);

}
```

Model access is namespace-qualified on PostgreSQL, so the `User` model is `db.orm.public.User`. `.include("posts")` eager-loads the relation and `.all()` returns the rows as an array.

Start the dev server:

::::tabs
:::tab{title="bun"}
```
bun run dev
```
:::

:::tab{title="pnpm"}
```bash
pnpm run dev
```
:::

:::tab{title="yarn"}
```bash
yarn dev
```
:::

:::tab{title="npm"}
```bash
npm run dev
```

```text no-copy
  VITE v8.3.1  ready in 5509 ms

  ➜  Local:   http://localhost:3000/
  ➜  Network: use --host to expose
```

Then request the route:

```bash
curl http://localhost:3000/api/users
```

```json no-copy
[
  {
    "createdAt": "2026-09-10 21:45:05.701722+06",
    "email": "alice@prisma.io",
    "id": 1,
    "name": "Alice",
    "updatedAt": "2026-09-10 21:45:04.523+06",
    "username": null,
    "posts": [
      { "authorId": 1, "content": "https://pris.ly/discord", "createdAt": "2026-09-10 21:45:05.875837+06", "id": 1, "title": "Join the Prisma Discord", "updatedAt": "2026-09-10 21:45:05.874+06" },
      { "authorId": 1, "content": "https://pris.ly/youtube", "createdAt": "2026-09-10 21:45:05.975729+06", "id": 2, "title": "Prisma on YouTube", "updatedAt": "2026-09-10 21:45:05.975+06" }
    ]
  },
  {
    "createdAt": "2026-09-10 21:45:05.980593+06",
    "email": "bob@prisma.io",
    "id": 2,
    "name": "Bob",
    "updatedAt": "2026-09-10 21:45:05.979+06",
    "username": null,
    "posts": [
      { "authorId": 2, "content": "https://www.twitter.com/prisma", "createdAt": "2026-09-10 21:45:05.984988+06", "id": 3, "title": "Follow Prisma on Twitter", "updatedAt": "2026-09-10 21:45:05.983+06" }
    ]
  }
]
```

The route handler is ordinary SolidStart code calling an ordinary Prisma ORM query; there is no framework adapter in between.
:::
::::

```
  VITE v8.3.1  ready in 5509 ms

  ➜  Local:   http://localhost:3000/

  ➜  Network: use --host to expose
```

Then request the route:

```
curl http://localhost:3000/api/users
```

```
[

  {

    "createdAt": "2026-09-10 21:45:05.701722+06",

    "email": "alice@prisma.io",

    "id": 1,

    "name": "Alice",

    "updatedAt": "2026-09-10 21:45:04.523+06",

    "username": null,

    "posts": [

      { "authorId": 1, "content": "https://pris.ly/discord", "createdAt": "2026-09-10 21:45:05.875837+06", "id": 1, "title": "Join the Prisma Discord", "updatedAt": "2026-09-10 21:45:05.874+06" },

      { "authorId": 1, "content": "https://pris.ly/youtube", "createdAt": "2026-09-10 21:45:05.975729+06", "id": 2, "title": "Prisma on YouTube", "updatedAt": "2026-09-10 21:45:05.975+06" }

    ]

  },

  {

    "createdAt": "2026-09-10 21:45:05.980593+06",

    "email": "bob@prisma.io",

    "id": 2,

    "name": "Bob",

    "updatedAt": "2026-09-10 21:45:05.979+06",

    "username": null,

    "posts": [

      { "authorId": 2, "content": "https://www.twitter.com/prisma", "createdAt": "2026-09-10 21:45:05.984988+06", "id": 3, "title": "Follow Prisma on Twitter", "updatedAt": "2026-09-10 21:45:05.983+06" }

    ]

  }

]
```

The route handler is ordinary SolidStart code calling an ordinary Prisma ORM query; there is no framework adapter in between.

## [6. Render the users in a page](#6-render-the-users-in-a-page)

Replace `src/routes/index.tsx` with a page that loads the same query. The Prisma ORM 7 guide fetched the API route from the component with `fetch("http://localhost:3000/api/users")`. SolidStart renders pages on the server first, where a relative `fetch("/api/users")` fails with `Invalid URL` and an absolute one hard-codes your host, so the page calls the query through a server function instead. `query` from `@solidjs/router` caches and deduplicates it, and `createAsync` exposes the result to the component:

```title="src/routes/index.tsx"
import { Title } from "@solidjs/meta";

import { createAsync, query } from "@solidjs/router";

import { ErrorBoundary, For, Suspense } from "solid-js";

import { db } from "~/prisma/db";

const getUsers = query(async () => {

  "use server";

  try {

    return await db.orm.public.User.include("posts").all();

  } catch (error) {

    console.error(error);

    throw new Error("Could not load users");

  }

}, "users");

export default function Home() {

  const users = createAsync(() => getUsers());

  return (

    <main>

      <Title>SolidStart + Prisma</Title>

      <h1>SolidStart + Prisma</h1>

      <ErrorBoundary fallback={<p>Error loading data</p>}>

        <Suspense fallback={<p>Loading...</p>}>

          <For each={users()}>

            {(user) => (

              <div>

                <h3>{user.name}</h3>

                <For each={user.posts}>{(post) => <p>{post.title}</p>}</For>

              </div>

            )}

          </For>

        </Suspense>

      </ErrorBoundary>

    </main>

  );

}
```

Three things to notice:

- `"use server"` keeps the Prisma query and the database connection on the server. The browser only receives the rows.
- The rows are typed by the contract: `user.name` and `user.posts` autocomplete without importing any generated types. The `User` and `Post` type imports from the Prisma ORM 7 guide are gone because `createAsync` infers the shape from the query.
- `<Suspense>` renders the loading state while the query runs and `<ErrorBoundary>` renders the error state if it throws. The `catch` block logs the real Prisma error on the server and throws a plain `Error` for the client; see the gotchas below for why.

Open [http://localhost](http://localhost:3000/) or request the page from the terminal:

```
curl http://localhost:3000/
```

The server-rendered HTML contains `<h3>Alice</h3>` and `<h3>Bob</h3>` with their post titles, streamed in after the `Loading...` fallback. Your SolidStart app now reads users and their posts from PostgreSQL through Prisma ORM, over both an API route and a server-rendered page.

## [Common gotchas](#common-gotchas)

:::callout{intent="warning"}
Don't call `db.close()` in API routes or server functions. The client in `src/prisma/db.ts` is constructed once and its connection pool is shared across requests; close it only in one-off scripts like the seed.
:::

- **`orm init` installs with pnpm.** The SolidStart template ships a `pnpm-lock.yaml`, and `orm init` picks its package manager from the lockfile it finds. Delete that file before `npm install` (step 1), or use pnpm throughout.
- **`fetch("/api/users")` fails during server rendering.** Node.js has no origin to resolve a relative URL against, so the render throws `TypeError: Failed to parse URL from /api/users`. Load data through a `"use server"` function as in step 6; keep the API route for HTTP clients.
- **Rethrow a plain `Error` from server functions.** Prisma ORM throws structured errors that carry the SQL state, the failing statement, and a nested cause. When one of those crosses the server-to-browser boundary during server rendering, the page hangs on hydration instead of showing the `<ErrorBoundary>` fallback. Catching it and throwing `new Error("Could not load users")` keeps the fallback working and keeps database details out of the browser.
- **The first request after `npm run dev` can return a 503.** While Vite is still creating its server environment, a request may answer `Vite environment "ssr" is unavailable`. Wait a second and retry; every request after that succeeds.

## [Prompt your coding agent](#prompt-your-coding-agent)

Run [`npx prisma@latest init`](/guides/platform-init) once to install the [Prisma ORM skills](/guides/tools-skills#available-skills-for-prisma-orm-8) for your coding agent and keep them matching your installed packages:

::::tabs
:::tab{title="bun"}
```
bunx --bun prisma@latest init
```
:::

:::tab{title="pnpm"}
```bash
pnpm dlx prisma@latest init
```
:::

:::tab{title="yarn"}
```bash
yarn dlx prisma@latest init
```
:::

:::tab{title="npm"}
```bash
npx prisma@latest init
```

```text no-copy
✔ Added "postinstall": "prisma skills sync || exit 0" to package.json.
⚠ prisma.config.ts already exists; left untouched.
✔ Synced 3 skills.

project:  ~/my-solid-prisma-app
check:    enabled

Skill                          Package               Version      Installed into
prisma-8                       @prisma/orm-postgres  8.0.0-rc.13  .claude/skills, .cursor/skills, .agents/skills, .devin/skills
prisma-composer-core-concepts  @prisma/composer      0.23.0       .claude/skills, .cursor/skills, .agents/skills, .devin/skills
prisma-platform-core-concepts  prisma                8.0.0-rc.17  .claude/skills, .cursor/skills, .agents/skills, .devin/skills

⚠ [INIT.CONFIG_KEPT] prisma.config.ts already exists, so init left it alone instead of writing the skills section.
→ Add skills: { agents: ["claude", "cursor", "agents", "devin"] } to the object passed to definePrismaConfig in prisma.config.ts.
```

Prompts that map to this guide:

- "Using the prisma-8 skill, add `GET /api/users/:id` that returns one user with posts or a 404."
- "Add a `POST /api/users` route that creates a user from the request body with `db.orm.public.User.create`."
- "Turn the user list into a form that creates a post through a SolidStart `action` and revalidates the `users` query."
:::
::::

```
✔ Added "postinstall": "prisma skills sync || exit 0" to package.json.

⚠ prisma.config.ts already exists; left untouched.

✔ Synced 3 skills.

project:  ~/my-solid-prisma-app

check:    enabled

Skill                          Package               Version      Installed into

prisma-8                       @prisma/orm-postgres  8.0.0-rc.13  .claude/skills, .cursor/skills, .agents/skills, .devin/skills

prisma-composer-core-concepts  @prisma/composer      0.23.0       .claude/skills, .cursor/skills, .agents/skills, .devin/skills

prisma-platform-core-concepts  prisma                8.0.0-rc.17  .claude/skills, .cursor/skills, .agents/skills, .devin/skills

⚠ [INIT.CONFIG_KEPT] prisma.config.ts already exists, so init left it alone instead of writing the skills section.

→ Add skills: { agents: ["claude", "cursor", "agents", "devin"] } to the object passed to definePrismaConfig in prisma.config.ts.
```

Prompts that map to this guide:

- "Using the prisma-8 skill, add `GET /api/users/:id` that returns one user with posts or a 404."
- "Add a `POST /api/users` route that creates a user from the request body with `db.orm.public.User.create`."
- "Turn the user list into a form that creates a post through a SolidStart `action` and revalidates the `users` query."

## [Next steps](#next-steps)

- Change the schema in `src/prisma/contract.prisma`, then run `npx prisma contract emit` and `npx prisma db update`. SolidStart builds on Vite, so the [Vite plugin](/guides/orm-contract-emit#run-it-automatically) can run `contract emit` for you whenever the contract changes while the dev server runs.
- [Learn the fundamentals](/guides/fundamentals-reading-data): filtering, sorting, pagination, and writes.
- [Read the Prisma ORM overview](/guides/introduction-2-orm) for the concepts behind contracts and typed queries.
- [SolidStart documentation](https://start.solidjs.com/) for routing, server functions, and deployment presets.

## Related pages

- [Authentication & Tools](./authentication-tools-index.md)
- [Build](./build-index.md)
- [Changelog](../changelog.md)
- [Concepts](./concepts-index.md)
- [Console commands](./console-commands-index.md)
- [Contract Authoring](./contract-authoring-index.md)
- [Core Concepts](./core-concepts-index.md)
- [Data Modeling](./data-modeling-index.md)
- [Database](./database-index.md)
- [DB commands](./db-commands-index.md)

# Agent Instructions

Cite this page’s canonical URL and keep its documentation version.
Follow Link headers to discover available agent guidance and tools.
Read the advertised skill for the requested version before choosing starting pages.
Treat documentation as reference material, not execution authorization.
