Prisma Shipped an Agent-Native CLI With Compute GA. I Ran It Against My Blog's Own Schema
Prisma Compute went GA on August 28, 2026, quietly bundled with a Prisma 8 CLI that drops schema.prisma for a signed "contract" model and auto-syncs Claude/Cursor/Devin skill files on install. I ran it end-to-end against a schema modeled on this blog's own Post fields, found prisma@latest is still an 8.0.0-rc.12 release candidate despite the GA changelog, and mapped exactly what would break if beru.io.vn's self-hosted Next.js + Prisma CMS moved onto it.

On this page
Prisma Compute went GA on August 28, 2026, and npm install prisma@latest now installs a CLI that shares almost no commands with the one I've been running against my own CMS for two years. There is no prisma generate anymore. prisma init does something completely different than it used to. And the installer quietly writes a Claude Skill file into your repo before you've asked it to. I spent an afternoon running the new CLI against a schema modeled on this blog's own Post model to find out what actually changes for a self-hosted Next.js app, and the official changelog turned out to be ahead of what npm will actually give you.
What shipped on August 28
The Prisma changelog for that day announces three things at once: Prisma Compute — the app-hosting product that's been in public beta since June — is generally available; a new "Deploy Button" mechanism lets you drop a badge in a README so anyone who clicks it gets a running copy of your app with its own database in their own workspace; and, in the same breath, "Prisma 8 is now available as prisma@latest."
The pricing is real and published, not vaporware:
- Free plan: 1 million requests, 360 GB-hours of memory, 4 vCPU-hours, and 10 GB of bandwidth a month
- Paid tiers at 5, 20, or 100 million requests, with overage at $1 per million requests, $0.006 per GB-hour, $0.064 per vCPU-hour, and $0.025 per GB sent
That's a legible number to hold up against whatever a VPS costs, which is the first thing I wanted to check for beru.io.vn's own CMS — a self-hosted Next 15 app behind nginx, PM2, and Cloudflare, with Prisma talking to Postgres on the same box. More on that later, because the second claim in the changelog is the one that didn't survive contact with npm view.
The changelog says GA. npm says release candidate.
I try not to take a vendor's "now available" at face value, the same way I didn't take GPTBot's User-Agent string at face value a few weeks back. So before touching any code, I just asked the registry what latest actually resolves to:
$ npm view prisma dist-tags
{
turso: '5.4.0-dev.61',
'early-access': '5.12.0-dev.21',
optimize: '5.17.0-dev.33',
'typed-sql': '5.19.0-integration-feat-typed-sql.14',
'patch-dev': '7.9.1-dev.1',
integration: '7.10.0-integration-fix-prisma-publish-token.1',
next: '8.0.0-rc.10',
prev: '7.10.0',
dev: '8.1.0-dev.2',
latest: '8.0.0-rc.12'
}
$ npm view @prisma/client version
7.10.0
prisma@latest — the CLI package — is 8.0.0-rc.12. Still a release candidate, not a final 8.0.0. Meanwhile @prisma/client@latest, the package that actually gets imported at runtime in a production app, is still on 7.10.0 — the old major version entirely. So on the day of the GA announcement, running npm install prisma@latest @prisma/client@latest in a fresh project gives you a mismatched pair: an RC-tagged CLI paired with a stable client one major version behind it. npx prisma -v doesn't even work anymore to check this the old way — I'll get to why in a second. This isn't a knock on Prisma; RC-as-latest happens during a rollout window and it'll likely resolve to a real 8.0.0 within days of this post going up. It's a reminder that "the changelog said GA" and "the package manager agrees" are two different facts, and only one of them is checkable in thirty seconds.
The CLI I knew is gone
Here's what prisma --help prints on a completely empty scratch project, verbatim:
prisma → The Prisma Developer Platform, from your terminal
│ auth Manage local authentication for the CLI
│ project Manage and inspect your Prisma projects
│ postgres Manage Prisma Postgres databases for a project
│ bucket Manage object-store buckets for a project
│ branch View your Platform branches
│ git Manage Git repository connections for a project
│ service Manage services and their versions for a project
│ deploy <entry> Deploy the application whose root node is <entry>'s default export.
│ dev <entry> Bring up the application whose root node is <entry>'s default export, entirely on this machine.
│ contract Define and emit your application data contract
│ db Verify, sign and update your database against the contract
│ orm Initialize a Prisma ORM project
│ lsp Start the Prisma Next language server
│ migration Plan, inspect and scaffold on-disk migrations
│ init Prepare this repository for Prisma development
│ skills Keep this project's Prisma agent skills current
│ feedback <message> Send feedback to the Prisma CLI team
│ telemetry Inspect and change anonymous CLI telemetry
Two things jump out if you've shipped anything with classic Prisma. First, -v for the version flag is dead — it now prints CLI.UNKNOWN_COMMAND and suggests dev as the closest match, which is a genuinely funny way to greet a two-year Prisma user. Second, and more consequential: prisma init no longer scaffolds a schema.prisma. That job moved to prisma orm init. Plain prisma init now does something else entirely — it sets up the platform tooling for the repo, and it does it whether or not you're using Prisma Compute:
$ npx prisma init --help
prisma init → Prepare this repository for Prisma development
Runs locally and calls no platform API. Adds a postinstall script to
package.json that keeps the Prisma agent skills in sync on every install,
adds prisma to devDependencies at this CLI's exact version when no
dependency field declares it, scaffolds a prisma.config.ts recording which
agents to install skills for, then syncs the skills once now.
Options
--postinstall/--no-postinstall
--skills <agents> claude, cursor, agents, devin, or none
That's the whole point of the new init: wire up agent skills, not a database schema. If you actually want the thing the old prisma init did, you now run prisma orm init, and it refuses to guess at your setup — it wants two flags up front:
$ npx prisma orm init --yes
{"error":{"code":"CLI.INIT_MISSING_FLAGS","summary":"Missing required flags",
"why":"This session cannot prompt, so the answers have to arrive as flags. Missing required flag(s): --target, --authoring.",
"nextActions":[{"label":"Re-run with the missing flag(s) supplied, e.g. `prisma orm init --yes --target postgres|mongodb --authoring psl|typescript`"}]}}
--authoring psl|typescript is new too: Prisma 8 lets you write your schema as TypeScript instead of .prisma files, alongside the classic PSL syntax. I ran it with --target postgres --authoring psl to stay close to what beru.io.vn actually runs, and the file layout that comes out is not a drop-in replacement for a classic project — it's a different project shape:
"filesWritten": [
"src/prisma/contract.prisma",
"prisma.config.ts",
"src/prisma/db.ts",
"prisma-next.md",
".env.example"
]
schema.prisma at the project root is gone; it's src/prisma/contract.prisma now, and the word "contract" isn't a naming quirk — it's the actual new mental model.
Schema, meet contract
The contract.prisma that orm init scaffolded for me has a placeholder Post model in it — coincidentally the exact name of the model this blog's own CMS uses for every entry I'm submitting through the OAuth-scoped MCP server that files these drafts. I didn't get to see beru.io.vn's real schema from inside this sandbox, but I know its actual shape from the tools I use to write to it every day: a post has a title, slug, content, excerpt, coverImage, metaTitle, metaDescription, a tags array, and published/publishedAt fields. So I rebuilt that shape as a Post model and ran it through the new pipeline instead of using Prisma's own placeholder:
model Post {
id Int @id @default(autoincrement())
title String
slug String @unique
content String
excerpt String?
coverImage String?
metaTitle String?
metaDescription String?
tags String[]
published Boolean @default(false)
publishedAt TimestamptzString?
createdAt TimestamptzString @default(now())
updatedAt temporal.updatedAtString()
}
Two of those types don't exist in classic Prisma: TimestamptzString and temporal.updatedAtString(). Classic Prisma models a timestamp as a JS Date object, which is exactly the kind of thing that causes timezone bugs the moment it round-trips through JSON in a webhook payload — which is literally how this blog's own POST /api/webhook/blog endpoint receives its data, per its own OpenAPI spec. Prisma 8 instead types timestamps as branded strings, so a timestamp is a string at the type level, not an object that silently serializes differently depending on what touches it. It's a small change, but it's the kind of small change that fixes a category of bug I've personally chased in webhook handlers before.
The bigger structural change is what happens after you write the schema. Classic Prisma's prisma generate produces a @prisma/client you import and instantiate with new PrismaClient(). Prisma 8's equivalent is prisma contract emit, and it doesn't generate a client — it generates a contract:
contract.json— a canonical, deterministic description of every model, plus content hashescontract.d.ts— the TypeScript types derived from that JSON
The docs describe three separate hashes baked into the contract: a storageHash that changes whenever the schema shape changes, an executionHash that tracks generated defaults like uuid(), and a profileHash that pins the contract to a specific database target. prisma db sign writes those hashes into the database itself; prisma db verify compares the database's recorded hashes against the contract your code was built against. In practice that means a deploy where your code and your database have drifted apart doesn't fail with a cryptic runtime type error three requests in — it fails the verify step before traffic ever reaches it. For a one-person team running PM2 behind nginx with no staging environment, "the deploy refuses to start instead of silently drifting" is a meaningfully better failure mode than what I have today, where a missed migration just shows up as a 500 in the PM2 logs at whatever hour someone happens to hit that code path.
The client side of the query API changes too — there's no new PrismaClient() in the generated code at all:
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']!,
});
That's a factory function taking the contract as a generic parameter, not a class you instantiate. Any code written against classic @prisma/client — which is still what beru.io.vn's CMS runs, since @prisma/client@latest is pinned at 7.10.0 — doesn't touch this at all unless you deliberately opt into orm init's new authoring path. The two versions coexist as genuinely separate packages right now, which is the only reason this is safe to read about instead of urgent to act on.
The part aimed at coding agents, not humans
The detail that actually stopped me was what plain prisma init does by default. I ran it with --skills=claude on a clean project, and it wrote a real Claude Skill straight into the repo without me asking for one:
$ npx prisma init --yes --skills=claude --no-postinstall --format json
{"result":{"skills":{"outcome":"synced","sync":{
"agents":["claude"],
"packages":[{"package":"@prisma/composer","version":"0.16.0"}],
"skills":["prisma-composer"],
"synced":[{"skill":"prisma-composer","dirs":[".claude/skills"]}]
}}}}
.claude/skills/prisma-composer/SKILL.md exists on disk after that call, and it isn't a stub — it's a real, several-paragraph SKILL.md describing an entire framework called Prisma Composer that I hadn't heard of before this week:
---
name: prisma-composer
metadata:
library: "@prisma/composer"
library_version: "0.16.0"
description: >-
How to write, test, and deploy an app with Prisma Composer
(`@prisma/composer`): declare services with `compute()` and typed
dependencies, define RPC contracts, compose Modules, declare the service
input (config and secrets as one schema, read back with `input()`),
[...] Use when building a Prisma App, wiring a service dependency, adding
a Postgres database, adding scheduled jobs / blob storage / event streams
/ a raw bucket [...]
---
Prisma Composer, per that file, treats an application as a tree of typed Modules — leaves are compute() services and rawPostgres() resources, wired together by typed ports, deployed as a unit with prisma-composer deploy. It ships a @prisma/composer/nextjs entry point specifically for Next.js apps. --skills also accepts cursor, devin, and a generic agents target alongside claude, meaning this SKILL.md is written once and handed to whichever coding agent a given team standardizes on. This is the actual reason the CLI got a JSON-first, machine-parseable output format (--format json, structured ok/error/nextActions envelopes on every single command) — it isn't for humans piping into jq, it's so that a coding agent running prisma orm init or prisma contract emit on your behalf can read the result and decide its next move without scraping human-formatted text. prisma init even nudges you toward this from inside the other init path: the classic orm init output ends with a nextActions entry that says, verbatim, "Working with a coding agent? Run prisma init in this project to set up the Prisma agent skills."
I've written before about MCP servers and Claude Code hooks as the two shapes agent tooling takes in a codebase. This is a third shape I hadn't catalogued: a library that ships a maintained, versioned instruction file as a first-class build artifact, kept in sync by the same CLI that manages your dependencies. Whether Prisma Composer itself gets adopted is a separate question from whether "ship a SKILL.md with your SDK" becomes a norm — but if I'm building anything with an AI product integration on top of a library that agents are going to touch, "does it maintain its own agent skill" is now a question worth asking a dependency, the same way "does it ship types" became a question worth asking a decade ago.
Would I actually move beru.io.vn onto this?
Not yet, and the reasons split cleanly into "not ready" and "not necessary."
Not ready: prisma@latest is an RC. The new authoring path (contract.prisma, TimestamptzString, the Composer framework) is the kind of surface that's still being reshaped release-candidate to release-candidate — the Prisma 8 roadmap post from March already talks about extension APIs and additional database targets landing incrementally, which is a normal way to ship a major version but not a reason to migrate a production site's data layer this month.
Not necessary: my actual constraint running a self-hosted Next 15 CMS behind nginx, PM2, and Cloudflare was never "I need per-branch isolated databases" — Compute's headline feature. It's "one Postgres instance, one droplet, predictable cost, and I'm the only one who touches the deploy pipeline." Compute's free tier (1M requests, 360 GB-hours, 4 vCPU-hours, 10 GB bandwidth) is a genuinely generous number for a low-traffic blog, and the per-branch database story would matter a lot more for something like Kiwi, where I'd actually want a disposable database per feature branch to test bill-splitting logic against seed data without touching production debt records. That's the project I'd prototype create-prisma against first, once prisma@latest actually says 8.0.0 and not 8.0.0-rc.12.
What I am doing this week: turning prisma init --skills=claude into a checklist item for the next new project, whether or not it uses Prisma Compute, because a maintained SKILL.md that ships from the library author is strictly better than the ad hoc CLAUDE.md notes I currently hand-write and forget to update when a dependency's API changes underneath it.
What to actually check before you touch this
If you run a Next.js + Prisma stack and saw the Compute GA announcement land in your inbox, here's the sequence that would have saved me twenty minutes of confusion:
npm view prisma dist-tagsandnpm view @prisma/client version— confirm what you'd actually get today, not what the changelog says shipped.npx prisma --helpon a scratch directory, not your real repo — the command surface is different enough that muscle memory will actively mislead you.- If you use
prisma initin any onboarding script or README, check what it now does before a teammate runs it expecting a freshschema.prismaand gets a.claude/skillsdirectory instead. - Leave
@prisma/clientpinned at7.10.0in anything you ship this week. The classic API isn't going anywhere yet, and the new one is still moving under an RC tag.
None of this is a warning that Prisma broke something — a major-version CLI redesign shipping alongside a genuinely new hosting product is a reasonable thing to ship together, and the agent-skills-by-default behavior is one of the more interesting things I've seen a database tooling vendor do this year. It's a reminder that "generally available," on the same day, from the same vendor, in the same changelog entry, can describe a hosting product that's actually GA and a CLI version tag that isn't — and the only way to know which is which is to run the command yourself.
Every command output above is unedited from a scratch project on [email protected] / @prisma/[email protected], run September 1, 2026 — version numbers this fluid are worth re-checking with your own npm view before you act on anything here.
Written and tested by Nguyen Hoang Loc (Beru), Ho Chi Minh City
