{"id":17119,"library":"prisma-soft-delete-middleware","title":"Prisma Soft Delete Middleware","description":"prisma-soft-delete-middleware is a utility library for Prisma that provides an efficient way to implement soft deletion for database records using Prisma's middleware system. The current stable version is `1.3.1`. It is actively maintained with a history of regular updates, including recent bug fixes and feature enhancements, though its release cadence may slow as the community shifts towards Prisma Extensions. This library's key differentiator is its ability to automatically handle cascading soft deletes across related models and to filter out soft-deleted records from various Prisma queries, including `findFirst`, `findMany`, `findUnique`, and operations involving `include` or `select`. It achieves this by intelligently modifying query arguments before they reach the database, leveraging `prisma-nested-middleware` for complex nested scenarios. While functional and maintained, Prisma's middleware system is deprecated in favor of Prisma Extensions, and users are encouraged to migrate to `prisma-extension-soft-delete` for future-proof applications.","status":"maintenance","version":"1.3.1","language":"javascript","source_language":"en","source_url":"https://github.com/olivierwilkinson/prisma-soft-delete-middleware","tags":["javascript","prisma","client","middleware","typescript"],"install":[{"cmd":"npm install prisma-soft-delete-middleware","lang":"bash","label":"npm"},{"cmd":"yarn add prisma-soft-delete-middleware","lang":"bash","label":"yarn"},{"cmd":"pnpm add prisma-soft-delete-middleware","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required for interacting with the Prisma database client.","package":"@prisma/client","optional":false}],"imports":[{"note":"The library primarily uses ES Modules. For CommonJS, configure your build system or use dynamic import.","wrong":"const createSoftDeleteMiddleware = require('prisma-soft-delete-middleware')","symbol":"createSoftDeleteMiddleware","correct":"import { createSoftDeleteMiddleware } from 'prisma-soft-delete-middleware'"},{"note":"This is a TypeScript type for the middleware function, useful for type hinting.","symbol":"SoftDeleteMiddleware","correct":"import type { SoftDeleteMiddleware } from 'prisma-soft-delete-middleware'"}],"quickstart":{"code":"import { PrismaClient } from '@prisma/client';\nimport { createSoftDeleteMiddleware } from 'prisma-soft-delete-middleware';\n\n// Example Prisma Schema:\n// model User {\n//   id        String    @id @default(uuid())\n//   email     String    @unique\n//   name      String?\n//   deleted   Boolean   @default(false)\n//   posts     Post[]\n// }\n// model Post {\n//   id        String    @id @default(uuid())\n//   title     String\n//   content   String?\n//   published Boolean   @default(false)\n//   authorId  String\n//   author    User      @relation(fields: [authorId], references: [id])\n//   deleted   Boolean   @default(false)\n// }\n\nconst prisma = new PrismaClient();\n\nprisma.$use(createSoftDeleteMiddleware({\n  models: {\n    User: true, // Enable soft delete for User model\n    Post: { field: 'deleted', deleteValue: true, includeSoftDeleted: false },\n  },\n}));\n\nasync function main() {\n  // Create a user and a post\n  const user = await prisma.user.create({\n    data: { email: 'test@example.com', name: 'Test User' },\n  });\n  console.log('Created user:', user);\n\n  const post = await prisma.post.create({\n    data: { title: 'First Post', authorId: user.id },\n  });\n  console.log('Created post:', post);\n\n  // Soft delete the user (and cascade to post if configured)\n  await prisma.user.delete({ where: { id: user.id } });\n  console.log(`Soft deleted user with ID: ${user.id}`);\n\n  // Attempt to find the user (should not be found by default)\n  const foundUser = await prisma.user.findUnique({ where: { id: user.id } });\n  console.log('Found user after soft delete (default):', foundUser);\n\n  // Find the user, explicitly including soft-deleted records\n  const foundSoftDeletedUser = await prisma.user.findUnique({ \n    where: { id: user.id },\n    // This is a special flag added by the middleware config for the model\n    includeSoftDeleted: true \n  });\n  console.log('Found soft-deleted user (explicitly):', foundSoftDeletedUser);\n\n  // Find all posts (soft-deleted post should not be found by default)\n  const allPosts = await prisma.post.findMany();\n  console.log('All posts (default):', allPosts);\n\n  // Find all posts, including soft-deleted ones (if 'Post' model was configured with includeSoftDeleted in middleware)\n  const allPostsIncludingDeleted = await prisma.post.findMany({ includeSoftDeleted: true });\n  console.log('All posts (including deleted):', allPostsIncludingDeleted);\n\n} \n\nmain().catch(e => {\n  console.error(e);\n  process.exit(1);\n}).finally(async () => {\n  await prisma.$disconnect();\n});","lang":"typescript","description":"Demonstrates how to set up the soft delete middleware with a PrismaClient, create and soft-delete a record, and then query for it both with and without explicitly including soft-deleted records."},"warnings":[{"fix":"Consider migrating to `prisma-extension-soft-delete` for long-term compatibility and to leverage the latest Prisma features. Install `npm install prisma-extension-soft-delete` and update your client setup.","message":"Prisma's native middleware system, which this library uses, is officially deprecated. While this library will continue to be maintained, the Prisma team recommends migrating to Prisma Extensions for future development. The library's author provides `prisma-extension-soft-delete` as a direct migration path.","severity":"deprecated","affected_versions":">=1.0.0"},{"fix":"Ensure all models intended for soft deletion include a `deleted: Boolean @default(false)` field or a custom field defined in the `createSoftDeleteMiddleware` configuration.","message":"The middleware requires a specific 'deleted' field (defaulting to `deleted: Boolean @default(false)`) on any model configured for soft deletion. Failing to define this field in your Prisma schema will lead to runtime errors when the middleware attempts to modify queries.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Upgrade to `prisma-soft-delete-middleware@1.2.0` or newer if you are using Prisma v5 with `find*OrThrow` methods.","message":"Version `1.2.0` introduced support for Prisma v5's `find*OrThrow` actions. If you are using Prisma v5 and `find*OrThrow` methods, older versions of this middleware may not function correctly with those specific actions.","severity":"gotcha","affected_versions":"<1.2.0"},{"fix":"If using a non-boolean `deleted` field (e.g., `DateTime`), configure `createSoftDeleteMiddleware` with `{ models: { YourModel: { field: 'deletedAt', deleteValue: new Date() } } }` to match your schema's update behavior.","message":"As of `v1.3.0`, the middleware supports `deleted` fields that store 'truthy' values (e.g., a timestamp) instead of strictly boolean `true/false`. If your `deleted` field is not a boolean, ensure `deleteValue` in the middleware configuration is set correctly for your schema.","severity":"gotcha","affected_versions":">=1.3.0"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Ensure `prisma.$use(createSoftDeleteMiddleware({ models: { /* your models */ } }))` is called before any database operations.","cause":"The middleware was not correctly applied to the Prisma Client using `$use()`, or the `models` configuration is empty/incorrect.","error":"TypeError: Cannot read properties of undefined (reading 'length') at applyMiddleware"},{"fix":"Pass `includeSoftDeleted: true` directly as a top-level argument to the query function (e.g., `prisma.user.findMany({ includeSoftDeleted: true })`) as enabled by the middleware.","cause":"`includeSoftDeleted` is a special parameter added by the middleware, not a standard Prisma query argument, and should not be placed inside a `where` clause.","error":"Unknown arg `includeSoftDeleted` in `where` for type `QueryUserArgs`."},{"fix":"Add the `deleted: Boolean @default(false)` field to the respective model in your `schema.prisma` file, then run `npx prisma generate`.","cause":"A model configured for soft deletion in the middleware does not have a `deleted` field (or the custom field name specified) in its Prisma schema.","error":"Error: Property 'deleted' does not exist on type 'User'."},{"fix":"Ensure all models you wish to apply soft delete to are explicitly listed in the `createSoftDeleteMiddleware` configuration: `{ models: { User: true, Post: true } }`.","cause":"The `Post` model (or any other model) was not included in the `models` configuration object passed to `createSoftDeleteMiddleware`.","error":"Error: Middleware not invoked for model 'Post'"}],"ecosystem":"npm","meta_description":null}