v3.83.0

Kieirra/murmurev3.83.0Apr 15, 2026by denolfe

AI Summary

PayloadCMS v3.83.0 expands the plugin API with definePlugin, introduces profiling utilities, and adds UUIDv7 support for database adapters.

Key Highlights

  • Expanded Plugin API with definePlugin helper for execution ordering
  • Added profiling utilities (timeSync/timeAsync) for performance analysis
  • Added UUIDv7 support for Postgres and SQLite adapters
  • Custom headers support for Resend email adapter

New Features

  • Expanded Plugin API
  • Profiling utilities
  • UUIDv7 support
  • Custom email headers
  • Custom collection views for Next.js
  • Plugin priority and slug API

Full Release Notes

## [v3.83.0](https://github.com/payloadcms/payload/compare/v3.82.1...v3.83.0) (2026-04-15)


### πŸš€ Features

* expand plugin API ([#16247](https://github.com/payloadcms/payload/issues/16247)) ([54189e1](https://github.com/payloadcms/payload/commit/54189e1))
* add profiling utilities for performance analysis ([#16198](https://github.com/payloadcms/payload/issues/16198)) ([9391c20](https://github.com/payloadcms/payload/commit/9391c20))
* add internal plugin priority and slug api for cross-plugin discovery ([#16244](https://github.com/payloadcms/payload/issues/16244)) ([5f5694f](https://github.com/payloadcms/payload/commit/5f5694f))
* hide slug field buttons when field is read-only ([#14824](https://github.com/payloadcms/payload/issues/14824)) ([67c2c47](https://github.com/payloadcms/payload/commit/67c2c47))
* **cpa:** add --agent flag for coding agent skill installation ([#16278](https://github.com/payloadcms/payload/issues/16278)) ([9f9f343](https://github.com/payloadcms/payload/commit/9f9f343))
* **drizzle:** add uuidv7 support ([#16113](https://github.com/payloadcms/payload/issues/16113)) ([ac01e82](https://github.com/payloadcms/payload/commit/ac01e82))
* **email-resend:** add Custom headers for the Resend adapter ([#15645](https://github.com/payloadcms/payload/issues/15645)) ([a7dd17c](https://github.com/payloadcms/payload/commit/a7dd17c))
* **next:** add support for custom collection views ([#16243](https://github.com/payloadcms/payload/issues/16243)) ([835a0ad](https://github.com/payloadcms/payload/commit/835a0ad))
* **plugin-form-builder:** change checkbox label from 'Default Value' to 'Checked by default' ([#15229](https://github.com/payloadcms/payload/issues/15229)) ([b3d2054](https://github.com/payloadcms/payload/commit/b3d2054))
* **plugin-mcp:** allow external plugins to extend mcp plugin ([#16245](https://github.com/payloadcms/payload/issues/16245)) ([ac4fc31](https://github.com/payloadcms/payload/commit/ac4fc31))
* **richtext-lexical:** add view override system for custom node rendering ([#14244](https://github.com/payloadcms/payload/issues/14244)) ([1ef43eb](https://github.com/payloadcms/payload/commit/1ef43eb))
* **storage-*:** add useCompositePrefixes option and fix client upload prefix handling ([#16230](https://github.com/payloadcms/payload/issues/16230)) ([74aa825](https://github.com/payloadcms/payload/commit/74aa825))

---

**Expanded Plugin API** β€” New `definePlugin` helper introduces opt-in execution ordering, cross-plugin discovery via a slug-keyed `plugins` map, and module augmentation for type-safe plugin options. The existing `(config) => config` contract remains unchanged. [#16247](https://github.com/payloadcms/payload/pull/16247)

```ts
import { definePlugin } from 'payload'

export const seoPlugin = definePlugin<SEOPluginOptions>({
  slug: 'plugin-seo',
  order: 10,
  plugin: ({ config, plugins, collections, generateTitle }) => ({
    ...config,
    // collections and generateTitle come from SEOPluginOptions
  }),
})
```

**Profiling Utilities** β€” Lightweight `timeSync` and `timeAsync` wrappers for measuring function execution time during development. Wrap any function to capture its duration, then call `printProfileResults` for a formatted timing table. Not intended for production use. [#16198](https://github.com/payloadcms/payload/pull/16198)

**Internal Plugin Priority & Slug API** β€” Plugins can now attach `priority`, `slug`, and `options` properties for execution ordering and cross-plugin discovery. Lower priority runs first; other plugins can find each other by slug via `config.plugins` without imports. Marked `@internal` for now. [#16244](https://github.com/payloadcms/payload/pull/16244)

**Hidden Slug Field Buttons on Read-Only** β€” The Generate and Lock/Unlock buttons on slug fields are now automatically hidden when the field is read-only, removing controls that serve no purpose in that state. [#14824](https://github.com/payloadcms/payload/pull/14824)

**Agent Flag for CPA (cpa)** β€” `create-payload-app` now supports a `--agent` / `-a` flag (`claude`, `codex`, `cursor`) that downloads the Payload coding skill from GitHub and installs it in the correct directory for your agent. A root-level `CLAUDE.md` or `AGENTS.md` is written for discoverability. Use `--no-agent` to skip. [#16278](https://github.com/payloadcms/payload/pull/16278)

<img width="514" height="386" alt="CPA agent selection prompt" src="https://github.com/user-attachments/assets/c5bc9e68-0c02-4881-ae6c-957e465e9f96" />

**UUIDv7 Support (drizzle)** β€” New `idType: 'uuidv7'` option for Postgres and SQLite adapters generates time-ordered UUIDs that are friendlier for B-tree indexes than random v4 UUIDs, while using the same storage column type. IDs are generated in application code so older Postgres versions are supported. [#16113](https://github.com/payloadcms/payload/pull/16113)

**Custom Email Headers (email-resend)** β€” The Resend adapter now passes custom headers from `sendEmail` options to the Resend API, enabling features like `List-Unsubscribe` headers that were previously silently dropped. [#15645](https://github.com/payloadcms/payload/pull/15645)

```ts
await payload.sendEmail({
  from: "Test <test@domain.com>",
  to: "jimmybillbob@example.com",
  subject: "Email with custom headers",
  html: html,
  headers: {
    "List-Unsubscribe": "<https://domain.com/unsubscribe>",
    "List-Unsubscribe-Post": "List-Unsubscribe=One-Click",
  },
});
```

**Custom Collection Views (next)** β€” Register custom views at the collection level via `admin.components.views[key]` with a `Component` and `path`. Folders take routing precedence over custom views on upload collections. [#16243](https://github.com/payloadcms/payload/pull/16243)

```ts
{
  slug: 'products',
  admin: {
    components: {
      views: {
        grid: {
          Component: '/components/GridView',
          path: '/grid',
          exact: true,
        },
      },
    },
  },
}
```

**Checkbox Label Clarity (plugin-form-builder)** β€” The form builder checkbox field label was changed from "Default Value" to "Checked by default" to eliminate confusion about whether the checkbox toggles a default value or sets the initial checked state. [#15229](https://github.com/payloadcms/payload/pull/15229)

**Extensible MCP Plugin (plugin-mcp)** β€” External plugins can now extend plugin-mcp by finding it via slug in `config.plugins` and injecting custom MCP tools into its options. Also exports the `MCPPluginConfig` type for type-safe tool injection. [#16245](https://github.com/payloadcms/payload/pull/16245)

**View Override System for Custom Node Rendering (richtext-lexical)** β€” ⚠️ Experimental. Override how any Lexical node type is rendered in the editor via view maps. Supports custom DOM, React components, or HTML strings. Works in both the admin editor and frontend JSX serialization for WYSIWYG consistency. [#14244](https://github.com/payloadcms/payload/pull/14244)

```tsx
export const myViews: LexicalEditorViewMap = {
  default: {
    heading: {
      createDOM() {
        const h2 = document.createElement('h2')
        h2.textContent = 'Custom Heading'
        return h2
      },
    },
    horizontalRule: {
      Component: () => <div className="custom-hr">---</div>,
    },
    link: {
      html: '<a href="#">Custom Link</a>',
    },
  },
}
```

```ts
{
  fields: [
    {
      name: 'content',
      type: 'richText',
      editor: lexicalEditor({
        views: '/path/to/views.tsx#myViews',
      }),
    },
  ]
}
```

**Composite Prefixes for Storage Adapters (storage-\*)** β€” New `useCompositePrefixes` option combines collection and document prefixes instead of one overriding the other. Also fixes a bug where client uploads ignored document prefix entirely. Applies to S3, Azure, GCS, R2, and Vercel Blob. [#16230](https://github.com/payloadcms/payload/pull/16230)

| Mode | Collection Prefix | Doc Prefix | Result |
|------|------------------|------------|--------|
| `false` (default) | `media-folder` | `user-123` | `user-123/file.jpg` |
| `true` | `media-folder` | `user-123` | `media-folder/user-123/file.jpg` |

### πŸ› Bug Fixes

* restore falling back to current document values for `undefined` fields ([#16272](https://github.com/payloadcms/payload/issues/16272)) ([4b4d61c](https://github.com/payloadcms/payload/commit/4b4d61c))
* enforce mimeTypes restriction when useTempFiles is enabled ([#16255](https://github.com/payloadcms/payload/issues/16255)) ([bb749a5](https://github.com/payloadcms/payload/commit/bb749a5))
* prevent cron from permanently dying after handler errors ([#16219](https://github.com/payloadcms/payload/issues/16219)) ([c5e0e02](https://github.com/payloadcms/payload/commit/c5e0e02))
* use safe property assignment in deepMergeSimple ([#16271](https://github.com/payloadcms/payload/issues/16271)) ([2b23010](https://github.com/payloadcms/payload/commit/2b23010))
* handle concurrent autosave write conflicts gracefully ([#16216](https://github.com/payloadcms/payload/issues/16216)) ([e8502fa](https://github.com/payloadcms/payload/commit/e8502fa))
* use instanceof instead of constructor name in formatErrors ([#16089](https://github.com/payloadcms/payload/issues/16089)) ([216d162](https://github.com/payloadcms/payload/commit/216d162))
* parse JSON string where query param ([#15745](https://github.com/payloadcms/payload/issues/15745)) ([2a26b5a](https://github.com/payloadcms/payload/commit/2a26b5a))
* expose type for field's `position` ([#14390](https://github.com/payloadcms/payload/issues/14390)) ([d9b3c07](https://github.com/payloadcms/payload/commit/d9b3c07))
* default virtual fields to readOnly in admin UI ([#16016](https://github.com/payloadcms/payload/issues/16016)) ([72396f6](https://github.com/payloadcms/payload/commit/72396f6))
* localized array,group,blocks fields duplicate with empty values ([#15849](https://github.com/payloadcms/payload/issues/15849)) ([067e14f](https://github.com/payloadcms/payload/commit/067e14f))
* fixes importMap type in monorepo usage ([#15203](https://github.com/payloadcms/payload/issues/15203)) ([79f4cc7](https://github.com/payloadcms/payload/commit/79f4cc7))
* **db-postgres:** bump `drizzle-orm` to `0.45.2` to resolve an SQL injection vulnerability and `pg` to `8.20.0` ([#16168](https://github.com/payloadcms/payload/issues/16168)) ([af1a932](https://github.com/payloadcms/payload/commit/af1a932))
* **drizzle:** surface connection errors in beginTransaction instead of hanging forever ([#16220](https://github.com/payloadcms/payload/issues/16220)) ([1e1c591](https://github.com/payloadcms/payload/commit/1e1c591))
* **drizzle:** ensure `getPrimaryDb` is used for all write operations ([#16240](https://github.com/payloadcms/payload/issues/16240)) ([aa44649](https://github.com/payloadcms/payload/commit/aa44649))
* **email-resend:** support path and preserve base64 content in mapAttachments ([#16094](https://github.com/payloadcms/payload/issues/16094)) ([57e71f5](https://github.com/payloadcms/payload/commit/57e71f5))
* **next:** persist language cookie across browser sessions ([#15081](https://github.com/payloadcms/payload/issues/15081)) ([0acff80](https://github.com/payloadcms/payload/commit/0acff80))
* **plugin-ecommerce:** price not showing as 0 when explicitly set ([#16289](https://github.com/payloadcms/payload/issues/16289)) ([62aa42b](https://github.com/payloadcms/payload/commit/62aa42b))
* **plugin-ecommerce:** priceInput does not respect required field status ([#15783](https://github.com/payloadcms/payload/issues/15783)) ([ed1c874](https://github.com/payloadcms/payload/commit/ed1c874))
* **plugin-import-export:** hide invalid sortBy options ([#11676](https://github.com/payloadcms/payload/issues/11676)) ([9d6bf0b](https://github.com/payloadcms/payload/commit/9d6bf0b))
* **plugin-search:** serialize reindexing to prevent locale data race conditions ([#15917](https://github.com/payloadcms/payload/issues/15917)) ([79d1b6b](https://github.com/payloadcms/payload/commit/79d1b6b))
* **plugin-seo,richtext-lexical:** add missing translations ([#11859](https://github.com/payloadcms/payload/issues/11859)) ([da27afc](https://github.com/payloadcms/payload/commit/da27afc))
* **plugin-stripe:** supports webhooks within serverless environments ([#10890](https://github.com/payloadcms/payload/issues/10890)) ([4179bf3](https://github.com/payloadcms/payload/commit/4179bf3))
* **translations:** 'noResults' translation expected a singular label, rewrite sentence sine a plural label is injected. ([#13360](https://github.com/payloadcms/payload/issues/13360)) ([cb0ce1c](https://github.com/payloadcms/payload/commit/cb0ce1c))
* **translations:** modified Spanish translations to be gender neutral ([#15796](https://github.com/payloadcms/payload/issues/15796)) ([a00267d](https://github.com/payloadcms/payload/commit/a00267d))
* **translations:** fall back to base language tag for Accept-Language matching ([#15076](https://github.com/payloadcms/payload/issues/15076)) ([cf95cad](https://github.com/payloadcms/payload/commit/cf95cad))
* **ui:** usePreventLeave default message ([#15042](https://github.com/payloadcms/payload/issues/15042)) ([8de32a2](https://github.com/payloadcms/payload/commit/8de32a2))
* **ui:** use i18n for live preview "Open in new window" tooltip ([#16038](https://github.com/payloadcms/payload/issues/16038)) ([173b453](https://github.com/payloadcms/payload/commit/173b453))
* **ui:** preselect folder when bulk uploading from inside a folder ([#16030](https://github.com/payloadcms/payload/issues/16030)) ([71a6c60](https://github.com/payloadcms/payload/commit/71a6c60))
* **ui:** prevent NaN aspect ratio in createThumbnail on svg files ([#10488](https://github.com/payloadcms/payload/issues/10488)) ([b332bff](https://github.com/payloadcms/payload/commit/b332bff))
* **ui:** thread cache tag to list view thumbnails ([#11741](https://github.com/payloadcms/payload/issues/11741)) ([5afcef5](https://github.com/payloadcms/payload/commit/5afcef5))

### ⚑ Performance

* **plugin-mcp:** minify JSON in MCP tool responses ([#15598](https://github.com/payloadcms/payload/issues/15598)) ([976369d](https://github.com/payloadcms/payload/commit/976369d))

### πŸ›  Refactors

* simplify storage adapter handler pattern ([#16231](https://github.com/payloadcms/payload/issues/16231)) ([6690769](https://github.com/payloadcms/payload/commit/6690769))
* clean up dead code and minor bugs in job queue system ([#16234](https://github.com/payloadcms/payload/issues/16234)) ([e49c224](https://github.com/payloadcms/payload/commit/e49c224))

### πŸ“š Documentation

* documents upload node markdown placeholder ([#16135](https://github.com/payloadcms/payload/issues/16135)) ([a9b0ca7](https://github.com/payloadcms/payload/commit/a9b0ca7))
* change import to use type import for GlobalConfig ([#11578](https://github.com/payloadcms/payload/issues/11578)) ([289e2b6](https://github.com/payloadcms/payload/commit/289e2b6))

### πŸ§ͺ Tests

* remove debug console.log left in SlugField overrides fields test suite ([#16279](https://github.com/payloadcms/payload/issues/16279)) ([22e2466](https://github.com/payloadcms/payload/commit/22e2466))
* **plugin-multi-tenant:** verify that tenant selector respects access control ([#14916](https://github.com/payloadcms/payload/issues/14916)) ([0516803](https://github.com/payloadcms/payload/commit/0516803))

### πŸ“ Templates

* bump payload and next.js versions ([#16229](https://github.com/payloadcms/payload/issues/16229)) ([2b10973](https://github.com/payloadcms/payload/commit/2b10973))

### πŸ““ Examples

* add Dockerfile to Remix ([#11429](https://github.com/payloadcms/payload/issues/11429)) ([e34cbc3](https://github.com/payloadcms/payload/commit/e34cbc3))

### βš™οΈ CI

* consolidate docker service startup into start-services action ([#16277](https://github.com/payloadcms/payload/issues/16277)) ([4912005](https://github.com/payloadcms/payload/commit/4912005))
* make build cache restore resilient to eviction ([#16275](https://github.com/payloadcms/payload/issues/16275)) ([d1837ad](https://github.com/payloadcms/payload/commit/d1837ad))
* update actions to resolve Node.js 20 deprecation warnings ([#16267](https://github.com/payloadcms/payload/issues/16267)) ([04163ea](https://github.com/payloadcms/payload/commit/04163ea))
* run e2e tests using turbopack ([#16237](https://github.com/payloadcms/payload/issues/16237)) ([3a7c9f3](https://github.com/payloadcms/payload/commit/3a7c9f3))

### 🏑 Chores

* allow e2e port to be defined by env vars ([#16285](https://github.com/payloadcms/payload/issues/16285)) ([cb97614](https://github.com/payloadcms/payload/commit/cb97614))
* mark the plugin API as experimental ([#16276](https://github.com/payloadcms/payload/issues/16276)) ([56325ef](https://github.com/payloadcms/payload/commit/56325ef))
* increase test summary script suite timeout to 120 seconds ([#16264](https://github.com/payloadcms/payload/issues/16264)) ([59f78f0](https://github.com/payloadcms/payload/commit/59f78f0))
* update deprecated VS code rules ([#16185](https://github.com/payloadcms/payload/issues/16185)) ([359dc94](https://github.com/payloadcms/payload/commit/359dc94))
* **templates:** fix postgres volume ([#15157](https://github.com/payloadcms/payload/issues/15157)) ([b44135e](https://github.com/payloadcms/payload/commit/b44135e))
* **templates:** wrong links to Draft Preview Example ([#13053](https://github.com/payloadcms/payload/issues/13053)) ([a2dee84](https://github.com/payloadcms/payload/commit/a2dee84))

### 🀝 Contributors

- Elliot DeNolf (@denolfe)
- Paul (@paulpopus)
- Philipp Schneider (@philipp-tailor)
- Riley Langbein (@rilrom)
- Patrik (@PatrikKozak)
- Ran (@eddieran)
- Alessio Gravili (@AlessioGr)
- Jens Becker (@jhb-dev)
- Ruben Hutter (@ruben-hutter)
- German Jablonski (@GermanJablo)
- Sean Zubrickas (@zubricks)
- Muhammad Aqib (@aqib-io)
- Jarrod Flesch (@JarrodMFlesch)
- Bob Bass (@robertjbass)
- Said Akhrarov (@akhrarovsaid)
- Mahmoud Hamdy (@mahmoodhamdi)
- fdurackbrooks (@fdurackbrooks)
- Jake Fletcher (@jacobsfletch)
- David Murdoch (@dsm23)
- Ossaid (@ossaidqadri)
- Adrian Maj (@AdrianMaj)
- Thijs Marinussen (@ThijsAtFreave)
- roboin (@Robot-Inventor)
- JeremΓ­as Benitez (@jerebenitez)
- Sebastian Blank (@blankse)
- Sasha (@r1tsuu)
- Yaniv (@y4aniv)
- Marwin Hormiz (@marwinhormiz)
- Jeffery To (@jefferyto)
- Roman Ryzhikov (@yagee)
- Hugo Duarte (@hugomeduarte)
- Boyan Bratvanov (@bratvanov)
- jakobpevec (@jakobpevec)
- Siim Sams (@siimsams)
- W1ckh3ad (@W1ckh3ad)
- Shane Friedman (@smoores-dev)
- Marius (@MariusMatu)
- guoyangzhen (@guoyangzhen)