# Prisma v8.0.0-rc.22 — Release & Upgrade Intelligence
- **Product:** Prisma (https://prisma.io)
- **Version:** v8.0.0-rc.22
- **Released:** Oct 30, 2026
- **Impact Score:** 7/10
- **Breaking Changes:** Source flagged
- **Canonical Analysis:** https://changelogs.us/prisma/updates/v8.0.0-rc.22/

## Executive Summary (TL;DR)
Prisma v8.0.0-rc.22. Source highlight: On PostgreSQL, `DateTime`, `Date`, `Time` and the new `Duration` are convenience types whose defaults read a JavaScript `Date` or a string, with no `Temporal` polyfill. Value objects move into the storage plane, so changing one is a migration, and Postgres checks value object and discriminator colum

## Breaking Changes & Deprecations
- The upgrade recipes for this hop: the [app recipe](https://github.com/prisma/orm/blob/v8.0.0-rc.22/skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.21-to-8.0.0-rc.22/) and the [extension recipe](https://github.com/prisma/orm/blob/v8.0.0-rc.22/skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.21-to-8.0.0-rc.22/). Each breaking change below names the change ids to look for in them. The app recipe opens with the order to do the steps in. After upgrading, run `prisma contract emit` once, so a contract that an extension such as Supabase stamps with its version matches the installed package (`con
- Breaking changes - **On PostgreSQL, `DateTime`, `Date` and `Time` are convenience types with new defaults.** Each is named for what a field means and becomes one explicit type, chosen by its optional `as`, `storage` and `precision` arguments. At its default, `DateTime` is a `timestamptz(3)` column read as a JavaScript `Date`, `Date` reads a string such as `"2024-02-29"`, `Time` reads a string such as `"09:30:00"`, and the new `Duration` reads an ISO 8601 duration such as `"P1M"`. Until now the three names read `Temporal` values. To keep a field as it is, rename `DateTime` to `TimestamptzTempor

## New Features
- **On PostgreSQL, `DateTime`, `Date` and `Time` are convenience types with new defaults.** Each is named for what a field means and becomes one explicit type, chosen by its optional `as`, `storage` and `precision` arguments. At its default, `DateTime` is a `timestamptz(3)` column read as a JavaScript `Date`, `Date` reads a string such as `"2024-02-29"`, `Time` reads a string such as `"09:30:00"`, and the new `Duration` reads an ISO 8601 duration such as `"P1M"`. Until now the three names read `Te
- `connect()` without options on a `postgres()`, `sqlite()`, `mysql()` or `mongo()` client is safe to call again: it waits for a connection in progress, or resolves with the runtime the client's queries already use. `connect(options)` on a bound client still rejects with `DRIVER.ALREADY_CONNECTED`, now with the message `<Target> client is already bound`. See `client-connect-safe-to-call-again` in the app recipe. (#30899)
- A Postgres contract can declare the extensions it needs, with `extension pg_trgm {}` in PSL or `extension('pg_trgm')` in TypeScript, at the top level or in a namespace. `db verify` checks them, the planner creates them, and `contract infer` and `contract print` write them. The Prisma 7 reader reads the datasource `extensions` list, so a Prisma 7 database that uses pgvector, PostGIS or ParadeDB adopts Prisma 8 with `contract emit` and `db sign`. (#30902)
- A new package, `@prisma/orm-postgres-contrib`, holds a `citext` extension pack: the PSL type `citext.Citext`, which compares case-insensitively. The Prisma 7 reader reads `@db.Citext` as `citext.Citext` when the config composes the pack, and refuses it with `PSL.PRISMA7_EXTENSION_PACK_MISSING`, naming the import to add, when it does not. Every Postgres `@db.*` type Prisma 7 accepts is now read. (#30904)
- PostgreSQL gains the types `Xml`, `Oid` and `Money`, and the Prisma 7 reader reads `@db.Bit`, `@db.VarBit`, `@db.Xml`, `@db.Oid` and `@db.Money`. The Postgres driver sets `lc_monetary=C` on every connection and writes `money` through `numeric`, so `money` reads and writes the same value in any locale. (#30900)
- MySQL gets ORM and SQL builder reads, including nested and ordered includes, through `@prisma/orm-mysql/runtime` and `@prisma/orm-mysql/static`. The MySQL drivers run on the `mariadb` package, which writes each value into the statement with its own escaping, so Prisma's code never puts a value into SQL and each statement takes one round trip. (#30863, #30893, #30918)

## Bug Fixes
- **Value objects are storage entities, and Postgres checks their columns.** A contract keeps its value objects at `storage.namespaces.<ns>.entries.valueObject`, and a field names one by its storage coordinate, so changing a value object changes the storage hash and is a migration. On SQL, a discriminator column names a value set of its variants' values, and a discriminator field is typed by those values, such as `'bug' | 'feature'`. On a managed Postgres table, the contract derives a check for ea
- On PostgreSQL, the `now` generator of a timestamp column read as a `Date` or a `Temporal` value rounds the time down to the column's precision, so the value a create returns is the value PostgreSQL stores. Before, a `timestamp(0)` column could store a time one second after the write. Re-emit the contract; only the execution hash changes. See `date-now-takes-column-precision` in the app recipe. (#30847)
- The diagnostic for a Prisma 7 `@db.*` attribute in a Prisma 8 schema suggests the constructor Prisma 8 renamed it to, such as `String` for `@db.Text`, instead of a type that does not exist. (#30909)
