Skip to main content

Codemods

This page documents the @archibald/codemod package — a CLI wrapper around jscodeshift used to apply automated code transformations when upgrading between Archibald major versions.

Requires Node.js >= 24

Quick start

Run the interactive CLI (will prompt for files and transform):

pnpx @archibald/codemod

Run a specific codemod on a path (or glob):

pnpx @archibald/codemod src/components "logger"

Dry-run to preview changes without modifying files:

pnpx @archibald/codemod src "commerce" --dry

Run all available codemods:

pnpx @archibald/codemod . "all"

CLI options

  • --force — ignore the "git must be clean" safety check
  • --dry — do not write changes (preview only)
  • --print — print transformed files to stdout
  • --explicit-require — pass explicit require option to jscodeshift
  • --jscodeshift <options...> — extra options forwarded to jscodeshift

The CLI will also prompt for missing arguments if you call it without parameters.

The versioned catalog

Codemods live in a versioned catalog under packages/codemod/codemods/, one folder per major version (v6v9) and one folder per codemod inside it:

codemods/
v9/
manifest.json # { "order": [...] } — run order for this major
platform-tenant-names/
meta.json # name, description, kind, engine, idempotent, postNotes, …
transform.js # the jscodeshift transform
__testfixtures__/ # <case>.input.tsx / <case>.output.tsx

The registry (packages/codemod/src/registry.ts) discovers the catalog from disk; the codemod's target version and transform path are derived from the folder, so they cannot drift. The interactive prompt lists every codemod labelled [vN] <description>, where vN is the major it migrates to.

Every codemod declares a kind in its meta.json:

  • transform — rewrites source code (AST).
  • config — rewrites JSON config files (e.g. archibald.json).
  • detectreport-only: it flags sites that need manual migration (file and line) and never writes. Use these as a checklist while upgrading.

Many codemods also carry postNotes — manual follow-up steps printed after the codemod runs. Read them: they describe the cases the codemod intentionally does not rewrite.

Codemods per major

v6

CodemodKindDescription
data-hook-aliasestransformRename the removed useClient/useFetchValue aliases to useDataClient/useFetchStatus
if-renametransformRename the removed IF component alias to If
login-options-objecttransformWrap the positional suspense argument of useLogin/useLogOut/useIsLoggedIn in an options object
use-mutate-suspend-optiontransformDrop the removed suspendAfterFirstLoad option from useMutate calls
renderer-abort-millisecondstransformConvert the removed Renderer option abortAfterSeconds to abortAfterMSeconds
default-middlewaredetectFlag the removed default middleware (createMiddleware without a type, DefaultMiddleware types)
data-request-resetdetectFlag .reset() calls in files using the data layer (DataRequest.reset is now delete)
hmr-helperdetectFlag imports of the removed HMRHelper namespace
cms-helperdetectFlag imports of the removed CMSHelper

v7

CodemodKindDescription
loggertransformMove the logger symbols out of @archibald/core into @archibald/log and adapt createLogger to its options object
configtransformReplace deprecated import of Config from @archibald/core
create-requesttransformReplace deprecated createEntity with createRequest
use-mutationtransformReplace deprecated useMutate with useMutation
preload-translationtransformReplace deprecated usePreload with usePreloadTranslation
rename-providertransformRename legacy *Provider/*DataProvider to the *ClientProvider naming schema
testbed-wrappertransformRename register/clearDefaultCustomWrapper to register/clearDefaultWrapper
testbed-custom-wrappertransformAdapt the removed customWrapper testing option to the wrapper component signature
preview-wrapperdetectFlag deprecated useSmartEdit imports (use getPreviewWrapperComponent instead)
capitalizetransformRename upperFirst to capitalize when imported from @archibald/helpers
cli-build-importstransformMove build and compiler helpers from @archibald/cli to @archibald/build
throw-on-error-configconfigRename mutateThrowOnError to throwOnError in archibald.json
app-client-hydratedetectFlag AppClient.rendered usage (replaced by the inverted hydrate)

v8

CodemodKindDescription
commercetransformReplace Commerce imports with nested subpackage imports and rename them
facet-importstransformMove facet schema and type imports from @archibald/storefront to @archibald/search
search-importstransformMove search response/suggestion interfaces from @archibald/storefront to @archibald/search
search-suggestionstransformRename the removed useSearchSuggestions hook to useSearchQuerySuggestions
use-session-clienttransformRename the removed useSession hook to useSessionClient
use-is-logged-in-argstransformDrop the removed arguments of useIsLoggedIn
hybris-service-importtransformImport HybrisService from @archibald/server instead of @archibald/auth
compiler-config-parameterstransformRename the removed WebpackConfigParameters type to CompilerConfigParameters
optimization-compiler-configconfigMove archibald.json experimental.compiler to optimization.compiler
search-suggestions-implementationsdetectFlag getSearchSuggestions/onSearchSuggestions definitions and calls (use the QuerySuggestions variants)
auth-removed-exportsdetectFlag Hybris auth providers that moved from @archibald/auth to @archibald/commerce
commerce-product-adapterdetectFlag the removed CommerceProductAdapter (use ProductAdapter from @archibald/product)

v9

CodemodKindDescription
tsconfig-module-resolutionconfigSwitch the per-platform client/server tsconfigs to bundler module resolution so exports-only packages (Storybook 9/10) resolve
storybook-core-importstransformMove the Storybook 8 packages folded into core to their storybook/* subpaths
storybook-define-configtransformReplace a hand-written .storybook/main.ts config object with defineConfig() from @archibald/storybook/config
auth-provider-logout-tokenstransformMigrate UserAuthProvider.logout to ApiServiceTokens: the declared parameter type and the token strings its callers pass
auth-oidc-signaturesdetectFlag SessionClient<User> single-generic and AuthService.logout(token) sites (OIDC rework)
auth-credentials-shapedetectFlag AuthCredentials usage — the [key: string]: any index signature is gone in v9
product-reviews-shapedetectFlag useReviews usage (reviews response is now { reviews: [] }, was an array)
platform-tenant-namestransformWrap direct reads of project.platforms/project.tenants with platformNames()/tenantNames() (entries are InheritanceEntry now, not string)

Shadowing config migration

shadowing-config is a native transform (its subject is archibald.json, not a JS/TS module, so jscodeshift cannot carry it — the CLI dispatches it directly). It moves project.theming to project.shadowing, rewriting each { test, replace } pair as a path template and folding rules that only differ by a single path segment into one enumerated rule:

pnpx @archibald/codemod . "shadowing-config"

Run on a directory it finds every archibald.json beneath it (ignoring node_modules). Files without a project.theming block are skipped and reported.

Safety & formatting

  • By default the CLI checks that the Git working tree is clean. Use --force to override.
  • The tool ignores node_modules and supports TS/JS/JSX/TSX files.
  • If prettier is installed, changed files will be formatted automatically after transforms.

Adding new codemods

  1. Create a folder codemods/v<major>/<name>/ (the folder name becomes the codemod's name and determines the version it belongs to).
  2. Add a meta.json with name (must equal the folder name), description, kind (transform | config | detect), engine (jscodeshift), idempotent, and optionally postNotes for manual follow-up steps.
  3. Add the transform.js (a jscodeshift-compatible transform; detect codemods report findings instead of rewriting).
  4. Add __testfixtures__/ with <case>.input.tsx / <case>.output.tsx pairs.
  5. Register the name in the major's manifest.json order array — that array defines the run order.

Tips

  • Always run with --dry first on large changes or unfamiliar transforms.
  • Commit or stash changes before running transforms when not using --force.
  • Pay attention to the postNotes a codemod prints — they list what still needs a manual review.