Skip to content

feat!: rename stored upload sizes field to variants - #18431

Merged
paulpopus merged 15 commits into
feat/file-transformersfrom
feat/file-transformers-variants-data
Oct 5, 2026
Merged

paulpopus merged 15 commits into
feat/file-transformersfrom
feat/file-transformers-variants-data

Conversation

@r1tsuu

@r1tsuu r1tsuu commented Oct 1, 2026 •

Copy link
Copy Markdown
Member

Note

Stacked on #18411. Draft.

What?

Upload documents now store generated image sizes under variants instead of sizes, matching the variants config option.

- doc.sizes?.thumbnail?.url
+ doc.variants?.thumbnail?.url

How?

  • Renames the stored field and every place that reads or queries it, across core, the admin UI, the storage plugins, tests, templates and docs.
  • Adds a sizes-to-variants migration for each database adapter (MongoDB, Postgres, Vercel Postgres, SQLite, D1): payload migrate:create --file @payloadcms/db-<adapter>/sizes-to-variants. On SQL databases it renames the columns in place, so no data is lost.
  • Stops the predefined migration before it changes data or indexes when legacy sizes storage conflicts with custom variants storage.
  • Escapes custom SQL identifiers, makes SQLite index replacement safe to retry, and preserves and validates MongoDB index definitions, including partial filters and text-index weights.
  • Fixes the db-postgres and db-vercel-postgres builds, which shipped migration-utils importing a predefined-migration helper that was only published as .mjs, so importing @payloadcms/db-postgres/migration-utils failed.

Breaking changes

Payload 4 uses variants as the top-level field for generated upload variants. An upload collection can already define a custom field with this name.

If a collection has a custom variants field, rename it before running the predefined migration:

  1. Choose a new field name, such as customVariants.
  2. Update the collection config to use the new name.
  3. Write a custom migration that moves the existing custom data from variants to the new field.
  4. Run the predefined sizes-to-variants migration after the custom data has moved.
  5. Start Payload 4 only after both migrations succeed.

The predefined migration cannot choose a name or merge custom variants data because Payload cannot determine the intended schema. It checks MongoDB documents, SQL columns, and SQL snapshots for conflicts and reports what must be moved before it can continue. A partly completed migration that contains only expected generated variant fields remains safe to retry.

Testing

  • test/sizes-to-variants covers the migration on MongoDB, SQLite and Postgres, including camelCase variant names and running inside a transaction, the way payload migrate does.
  • Regression coverage includes custom variants collisions, quoted SQL identifiers, SQLite retry and rerun behaviour, MongoDB partial filters and index options, text indexes, and incompatible destination indexes.
  • End to end on blank projects outside the monorepo, upgrading a real Payload 3.90.2 project to this branch's packed packages:
    1. Set up and seed with 3.x (sharp + imageSizes), using migrations for SQL.
    2. Upgrade and run the migrate-sharp-to-transformer codemod.
    3. Run the sizes-to-variants migration.
    4. For SQL, generate a plain v4 migration and check it creates v4's new tables without dropping any sizes/variants columns.
    5. Compare every stored size before and after, run runtime checks, then roll back with migrate:down, migrate up again and compare.
Postgres SQLite MongoDB
Config drafts + localization, camelCase/webp sizes, custom dbName, a collection without sizes, upload relationship versions without drafts, crop/focal point, generateImageName, upload in an array, hasMany upload drafts + 3 locales, generateImageName, avif size, upload in a block, polymorphic hasMany upload
Documents and versions compared 15 10 16

Runtime checks after the upgrade cover where and select on variants.*, generated files on disk, and new uploads. Index names match the v4 schema.

Notes

  • The templates/with-vercel-website initial migration still creates sizes_* columns and needs regenerating.

Written with AI

@github-actions

github-actions Bot commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

📦 esbuild Bundle Analysis for payload

This analysis was generated by esbuild-bundle-analyzer. 🤖

Meta File Out File Size (raw) Note
packages/next/meta_index.json esbuild/index.js 216.59 KB 🆕 Added
packages/payload/meta_index.json esbuild/index.js 1.88 MB 🆕 Added
packages/payload/meta_shared.json esbuild/exports/shared.js 563.49 KB 🆕 Added
packages/richtext-lexical/meta_client.json esbuild/exports/client_optimized/index.js 296.15 KB 🆕 Added
packages/ui/meta_client.json esbuild/exports/client_optimized/index.js 36.81 KB 🆕 Added
packages/ui/meta_shared.json esbuild/exports/shared_optimized/index.js 18.98 KB 🆕 Added
Largest paths These visualization shows top 20 largest paths in the bundle.

Meta file: packages/next/meta_index.json, Out file: esbuild/index.js

Path Size
../../node_modules ${{\color{Goldenrod}{ ████████████████████████▋ }}}$ 98.8%, 212.07 KB
dist/adapters/router.js ${{\color{Goldenrod}{ }}}$ 0.3%, 718 B
dist/adapters/server.js ${{\color{Goldenrod}{ }}}$ 0.2%, 533 B
dist/adapters/layout.js ${{\color{Goldenrod}{ }}}$ 0.2%, 529 B
dist/adapters/views.js ${{\color{Goldenrod}{ }}}$ 0.2%, 324 B
dist/utilities/initAdminContext.js ${{\color{Goldenrod}{ }}}$ 0.1%, 315 B
dist/utilities/selectiveCache.js ${{\color{Goldenrod}{ }}}$ 0.1%, 263 B
dist/esbuildEntry.js ${{\color{Goldenrod}{ }}}$ 0.0%, 0 B

Meta file: packages/payload/meta_index.json, Out file: esbuild/index.js

Path Size
../../node_modules ${{\color{Goldenrod}{ █████████████████▉ }}}$ 71.7%, 1.34 MB
dist/collections/operations ${{\color{Goldenrod}{ ▋ }}}$ 2.9%, 54.67 KB
dist/fields/hooks ${{\color{Goldenrod}{ ▋ }}}$ 2.5%, 46.14 KB
dist/auth/operations ${{\color{Goldenrod}{ ▏ }}}$ 0.9%, 16.95 KB
dist/globals/operations ${{\color{Goldenrod}{ ▏ }}}$ 0.9%, 16.18 KB
dist/utilities/configToJSONSchema.js ${{\color{Goldenrod}{ ▏ }}}$ 0.9%, 16.02 KB
dist/queues/operations ${{\color{Goldenrod}{ ▏ }}}$ 0.8%, 14.31 KB
dist/fields/config ${{\color{Goldenrod}{ ▏ }}}$ 0.7%, 13.65 KB
dist/utilities/telemetry ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 11.88 KB
dist/collections/config ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 10.98 KB
dist/fields/validations.js ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 10.82 KB
dist/cli/commands ${{\color{Goldenrod}{ ▏ }}}$ 0.5%, 9.92 KB
dist/config/orderable ${{\color{Goldenrod}{ ▏ }}}$ 0.5%, 8.76 KB
dist/uploads/fetchAPI-multipart ${{\color{Goldenrod}{ }}}$ 0.4%, 8.38 KB
dist/database/migrations ${{\color{Goldenrod}{ }}}$ 0.4%, 8.16 KB
dist/config/sanitize.js ${{\color{Goldenrod}{ }}}$ 0.4%, 8.01 KB
dist/hierarchy/utils ${{\color{Goldenrod}{ }}}$ 0.4%, 7.66 KB
dist/index.js ${{\color{Goldenrod}{ }}}$ 0.4%, 7.54 KB
dist/auth/strategies ${{\color{Goldenrod}{ }}}$ 0.4%, 7.36 KB
dist/utilities/entityInputSchema ${{\color{Goldenrod}{ }}}$ 0.4%, 7.34 KB
(other) ${{\color{Goldenrod}{ ███████ }}}$ 28.3%, 528.78 KB

Meta file: packages/payload/meta_shared.json, Out file: esbuild/exports/shared.js

Path Size
../../node_modules ${{\color{Goldenrod}{ ██████████████████████▏ }}}$ 88.8%, 495.80 KB
dist/fields/validations.js ${{\color{Goldenrod}{ ▍ }}}$ 1.9%, 10.79 KB
dist/fields/config ${{\color{Goldenrod}{ ▎ }}}$ 1.0%, 5.83 KB
dist/utilities/traverseFields.js ${{\color{Goldenrod}{ ▏ }}}$ 0.8%, 4.34 KB
dist/utilities/deepCopyObject.js ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 3.52 KB
dist/collections/config ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 3.40 KB
dist/config/orderable ${{\color{Goldenrod}{ ▏ }}}$ 0.6%, 3.13 KB
dist/fields/baseFields ${{\color{Goldenrod}{ ▏ }}}$ 0.5%, 2.79 KB
dist/config/client.js ${{\color{Goldenrod}{ ▏ }}}$ 0.5%, 2.56 KB
dist/auth/cookies.js ${{\color{Goldenrod}{ }}}$ 0.3%, 1.55 KB
dist/utilities/flattenTopLevelFields.js ${{\color{Goldenrod}{ }}}$ 0.3%, 1.42 KB
dist/utilities/getVersionsConfig.js ${{\color{Goldenrod}{ }}}$ 0.2%, 1.04 KB
dist/globals/config ${{\color{Goldenrod}{ }}}$ 0.2%, 939 B
dist/uploads/generatePayloadFileURL.js ${{\color{Goldenrod}{ }}}$ 0.2%, 864 B
dist/utilities/unflatten.js ${{\color{Goldenrod}{ }}}$ 0.2%, 850 B
dist/utilities/flattenAllFields.js ${{\color{Goldenrod}{ }}}$ 0.1%, 798 B
dist/utilities/sanitizeUserDataForEmail.js ${{\color{Goldenrod}{ }}}$ 0.1%, 713 B
dist/auth/extractJWT.js ${{\color{Goldenrod}{ }}}$ 0.1%, 696 B
dist/utilities/getFieldPermissions.js ${{\color{Goldenrod}{ }}}$ 0.1%, 651 B
dist/utilities/fieldPath.js ${{\color{Goldenrod}{ }}}$ 0.1%, 639 B
(other) ${{\color{Goldenrod}{ ██▊ }}}$ 11.2%, 62.77 KB

Meta file: packages/richtext-lexical/meta_client.json, Out file: esbuild/exports/client_optimized/index.js

Path Size
dist/features/blocks ${{\color{Goldenrod}{ ███▋ }}}$ 14.6%, 42.74 KB
dist/lexical/plugins ${{\color{Goldenrod}{ ██▉ }}}$ 11.8%, 34.51 KB
dist/lexical/ui ${{\color{Goldenrod}{ ██▊ }}}$ 11.4%, 33.54 KB
dist/features/table ${{\color{Goldenrod}{ ██▎ }}}$ 9.4%, 27.46 KB
dist/features/link ${{\color{Goldenrod}{ █▋ }}}$ 6.5%, 18.92 KB
dist/features/toolbars ${{\color{Goldenrod}{ █▌ }}}$ 6.3%, 18.41 KB
dist/features/upload ${{\color{Goldenrod}{ █▏ }}}$ 4.9%, 14.28 KB
dist/features/textState ${{\color{Goldenrod}{ ▉ }}}$ 3.8%, 11.08 KB
dist/lexical/utils ${{\color{Goldenrod}{ ▊ }}}$ 3.4%, 10.02 KB
dist/features/relationship ${{\color{Goldenrod}{ ▊ }}}$ 3.2%, 9.43 KB
dist/features/converters ${{\color{Goldenrod}{ ▋ }}}$ 2.9%, 8.41 KB
dist/utilities/fieldsDrawer ${{\color{Goldenrod}{ ▋ }}}$ 2.8%, 8.12 KB
dist/features/debug ${{\color{Goldenrod}{ ▋ }}}$ 2.5%, 7.40 KB
dist/lexical/config ${{\color{Goldenrod}{ ▍ }}}$ 1.8%, 5.14 KB
dist/features/indent ${{\color{Goldenrod}{ ▎ }}}$ 1.4%, 4.19 KB
dist/features/lists ${{\color{Goldenrod}{ ▎ }}}$ 1.3%, 3.67 KB
dist/lexical/LexicalEditor.js ${{\color{Goldenrod}{ ▎ }}}$ 1.1%, 3.33 KB
dist/features/format ${{\color{Goldenrod}{ ▎ }}}$ 1.1%, 3.28 KB
dist/features/horizontalRule ${{\color{Goldenrod}{ ▎ }}}$ 1.1%, 3.18 KB
dist/field/Field.js ${{\color{Goldenrod}{ ▎ }}}$ 1.0%, 3.05 KB
(other) ${{\color{Goldenrod}{ █████████████████████▎ }}}$ 85.4%, 250.20 KB

Meta file: packages/ui/meta_client.json, Out file: esbuild/exports/client_optimized/index.js

Path Size
dist/exports/client ${{\color{Goldenrod}{ █████████████████████████ }}}$ 100.0%, 27.10 KB

Meta file: packages/ui/meta_shared.json, Out file: esbuild/exports/shared_optimized/index.js

Path Size
dist/graphics/Logo ${{\color{Goldenrod}{ ███████▋ }}}$ 30.7%, 5.61 KB
../../node_modules ${{\color{Goldenrod}{ ███▌ }}}$ 14.5%, 2.65 KB
dist/graphics/Icon ${{\color{Goldenrod}{ ██ }}}$ 8.3%, 1.51 KB
dist/utilities/formatDocTitle ${{\color{Goldenrod}{ █▊ }}}$ 7.2%, 1.32 KB
dist/providers/TableColumns ${{\color{Goldenrod}{ █▏ }}}$ 4.7%, 866 B
dist/utilities/getGlobalData.js ${{\color{Goldenrod}{ █ }}}$ 4.2%, 762 B
dist/utilities/api.js ${{\color{Goldenrod}{ █ }}}$ 4.1%, 756 B
dist/utilities/groupNavItems.js ${{\color{Goldenrod}{ █ }}}$ 4.1%, 745 B
dist/elements/Translation ${{\color{Goldenrod}{ ▋ }}}$ 2.7%, 493 B
dist/utilities/handleTakeOver.js ${{\color{Goldenrod}{ ▌ }}}$ 2.4%, 440 B
dist/utilities/traverseForLocalizedFields.js ${{\color{Goldenrod}{ ▌ }}}$ 2.3%, 419 B
dist/elements/withMergedProps ${{\color{Goldenrod}{ ▍ }}}$ 1.9%, 339 B
dist/utilities/getNavGroups.js ${{\color{Goldenrod}{ ▍ }}}$ 1.8%, 338 B
dist/utilities/getVisibleEntities.js ${{\color{Goldenrod}{ ▍ }}}$ 1.8%, 329 B
dist/elements/WithServerSideProps ${{\color{Goldenrod}{ ▎ }}}$ 1.3%, 232 B
dist/layouts/Root ${{\color{Goldenrod}{ ▎ }}}$ 1.3%, 230 B
dist/utilities/handleGoBack.js ${{\color{Goldenrod}{ ▎ }}}$ 1.0%, 180 B
dist/fields/mergeFieldStyles.js ${{\color{Goldenrod}{ ▏ }}}$ 0.9%, 158 B
dist/forms/Form ${{\color{Goldenrod}{ ▏ }}}$ 0.8%, 152 B
dist/utilities/handleBackToDashboard.js ${{\color{Goldenrod}{ ▏ }}}$ 0.8%, 152 B
(other) ${{\color{Goldenrod}{ █████████████████▎ }}}$ 69.3%, 12.68 KB
Details

Next to the size is how much the size has increased or decreased compared with the base branch of this PR.

  • ‼️: Size increased by 20% or more. Special attention should be given to this.
  • ⚠️: Size increased in acceptable range (lower than 20%).
  • ✅: No change or even downsized.
  • 🗑️: The out file is deleted: not found in base branch.
  • 🆕: The out file is newly found: will be added to base branch.

@r1tsuu
r1tsuu marked this pull request as ready for review October 1, 2026 17:06
Base automatically changed from feat/file-transformers-sharp to feat/file-transformers-core October 5, 2026 11:39
Base automatically changed from feat/file-transformers-core to feat/file-transformers October 5, 2026 11:39
@paulpopus
paulpopus merged commit fc3b8c9 into feat/file-transformers Oct 5, 2026
285 checks passed
@paulpopus
paulpopus deleted the feat/file-transformers-variants-data branch October 5, 2026 16:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants