Skip to main content

Upgrading to v9

Archibald 9 requires Node.js >= 24 and drops webpack — the compiler is rspack only. Upgrade your @archibald/* dependencies to the 9 line (pnpm add @archibald/cli@latest, see dist-tags), then run the codemod catalog from the project root:

pnpx @archibald/codemod .

The interactive prompt lists every codemod labelled [v9] <description>. transform and config codemods rewrite your files; detect codemods never write — they flag the call sites you have to migrate by hand. Pass --dry to preview any transform first.

Breaking changes and their codemods

Breaking changeCodemodKind
tsconfig moduleResolution must be bundlertsconfig-module-resolutionconfig
Storybook packages folded into corestorybook-core-importstransform
.storybook/main.ts uses defineConfig()storybook-define-configtransform
UserAuthProvider.logout takes ApiServiceTokensauth-provider-logout-tokenstransform
SessionClient<User> single generic, AuthService.logout(token)auth-oidc-signaturesdetect
AuthCredentials index signature removedauth-credentials-shapedetect
Product reviews response is { reviews: [] }product-reviews-shapedetect
project.platforms/project.tenants entries are objects (9.1)platform-tenant-namestransform

SessionClient takes two generics

SessionClient<User> is now SessionClient<User, Credentials>. Projects manually instantiating or extending the client must update their types. The auth-oidc-signatures codemod flags these sites (detect-only).

AuthCredentials no longer allows arbitrary keys

The base interface lost its [key: string]: any index signature — it is { authProtocol?: AuthProtocol } in v9, so arbitrary keys no longer typecheck. Use a specific implementation such as CookieAuthCredentialsPassword or CookieAuthCredentialsOidc, or declare the fields your project sends on an extending interface:

import type { AuthCredentials } from '@archibald/auth';

interface MyCredentials extends AuthCredentials {
customerId: string;
}

The auth-credentials-shape codemod lists the affected sites (detect-only).

AuthService.logout() takes no token

The signature changed from logout(token: string) to logout(). Flagged by auth-oidc-signatures.

UserAuthProvider interface

  • logout now accepts ApiServiceTokens ({ token, refreshToken }) instead of a single token.
  • loginUrl and token are now mandatory methods for providers.
  • loginUrl returns Promise<string> instead of string.

The auth-provider-logout-tokens codemod rewrites the declared parameter type and nests the token strings its callers pass:

// before
export class CDCUserAuthProvider extends UserAuthProvider<User, DefaultProviderOptions> {
public override async logout(claim: ApiServiceToken): Promise<boolean> { /* … */ }
}
await provider.logout({ token: 'access_token' });

// after
export class CDCUserAuthProvider extends UserAuthProvider<User, DefaultProviderOptions> {
public override async logout(claim: ApiServiceTokens): Promise<boolean> { /* … */ }
}
await provider.logout({ token: { token: 'access_token' } });

An empty-string token becomes token: null (still falsy). A positional token (provider.logout('access_token')) is left alone on purpose — SystemAuthProvider.logout() still takes a single ApiServiceToken; auth-oidc-signatures reports those. Since the rewrite only changes the type, review method bodies that used the parameter as a string.

Product reviews response restructured (ARC-1530)

The product reviews response is no longer an array — it is an object containing the reviews array ({ reviews: [] }). The product-reviews-shape codemod flags useReviews call sites (detect-only).

webpack support removed

v9 builds with rspack only. Custom webpack configuration has no effect anymore.

v8 deprecations removed

Everything deprecated through v8 is gone, including the default middleware kind — see Deprecated for each removal and its replacement.

Storybook 8 → 10

@archibald/storybook now requires Storybook 9 or 10, and storybook, @storybook/react, and your builder package (@storybook/react-webpack5 or @storybook/react-vite) are peer dependencies — add them to your own package.json. Two codemods do the migration:

  • storybook-define-config replaces a hand-written .storybook/main.ts config object with defineConfig() from @archibald/storybook/config, which picks the builder from the project's compiler backend and registers the framework's addons and story loader. Only keys that deviate from that base are kept. .storybook/tsconfig.json should extend the app's tsconfig so base-path imports resolve.
  • storybook-core-imports moves the Storybook 8 packages folded into core to their storybook/* subpaths (@storybook/manager-apistorybook/manager-api, @storybook/addon-actionsstorybook/actions, @storybook/teststorybook/test, …).

tsconfig moduleResolution

Storybook 9/10 ships exports only, with no top-level main/types; under moduleResolution: "node" every story fails with TS2307: Cannot find module '@storybook/react'. The tsconfig-module-resolution codemod switches the per-platform src/<platform>/<client|server>/tsconfig.json files to "moduleResolution": "bundler". A tsconfig with comments (JSONC) cannot be rewritten and is reported instead — add the option by hand there, and apply the same setting to any root-level tsconfig your IDE or lint uses.

Manual steps

  • If your own code imports jose (verifying a service token, decoding a JWT), declare it in your package.json — it is a dependency of @archibald/auth, not of your project, and the reinstall this upgrade runs can leave Cannot find module 'jose' behind.
  • The upgrade bumps companion dependency ranges you already declare (React 19, rspack 2, jest 30, …) but never adds a dependency for you.

Other notable changes

  • create @archibald supports npm, pnpm, yarn, and bun as package managers and detects the one that invoked it.
  • The native platform moves to Expo SDK 55 in 9.0; the 9.1 line moves to Expo SDK 56 (React Native 0.85). See Expo configuration.

9.1

9.1 renames file-shadowing configuration: project.theming becomes project.shadowing, where a rule is a single path template instead of a { test, replace } pair, and the useRustTheming flag is spelled useRustShadowing. The old block and spelling keep working (deprecated, removed in a future major). Migrate with:

pnpx @archibald/codemod . shadowing-config

The codemod moves the block, converts each pair to a template, renames the flag, and refuses to write if the migrated rules would resolve differently. See File shadowing and Deprecated.

Also since 9.1, project.platforms and project.tenants entries may be objects ({ name, extends? }) instead of plain strings, enabling cascading inheritance. Code that read entries as strings (config.project.platforms[0]) breaks; the platform-tenant-names codemod wraps such reads with the platformNames()/tenantNames() helpers from @archibald/build.