← All provider guides

AWS SDK v2 to v3 migration (JavaScript): what actually breaks and what a codemod can fix

aws sdk migration 14 tracked change records

AWS SDK for JavaScript v2 entered maintenance mode, and v3 is not a version bump — it is a different client model. Every service gets its own package, every operation becomes a command object, and the response types change shape. The migration touches every call site, which is exactly why teams postpone it, and exactly why most of it should be done by a codemod rather than by hand.

The four mechanical breakages

Strip away the marketing and the v2 to v3 migration for a service like S3 is four repeating rewrites. This list is read directly from the mendapi migration pack registry (aws-sdk-v2-to-v3-s3), so it matches what the codemod actually does:

  • Rewrite s3.<op>(params).promise() to s3.send(new <Op>Command(params))
  • Rewrite response Body.toString() to Body.transformToString() (v3 Body is a stream)
  • Replace new AWS.S3() client with new S3Client()
  • Replace aws-sdk require with modular @aws-sdk/client-s3 imports (only when no other AWS.* usage remains)

The first one is the bulk of the work: s3.getObject(params).promise() becomes s3.send(new GetObjectCommand(params)), once per call site, across the whole repo. The second is the one that passes review and fails in production: v3 response bodies are streams, so Body.toString() returns [object Object] instead of your file — the fix is Body.transformToString(), and nothing in the type of a quick edit warns you.

What a codemod should refuse to touch

A migration tool earns trust by what it leaves alone. The mendapi pack rewrites the require('aws-sdk') line into modular @aws-sdk/client-s3 imports only when no other AWS.* usage remains in the file — if your file also builds a DynamoDB client, the import line stays and the report says so. Guessing there would produce a broken build; staying silent is the correct verdict. The same fail-closed policy runs through every mendapi pack: each rule is locked by golden-fixture regression tests with negative controls, so a rule that starts over-firing fails our build before it reaches your repo.

Preview the whole migration as one diff

The pack runs locally as a dry run by default. On the bundled v2 fixture repo it rewrites two files across seven rule hits and writes a unified patch you can read before anything is applied:

npx mendapi scan
# -> which files touch aws-sdk, with line numbers
mendapi fix --migration aws-sdk-v2-to-v3-s3
# -> dry run: changes.patch + fix-report.json, nothing applied
mendapi fix --migration aws-sdk-v2-to-v3-s3 --apply
# -> applies the reviewed diff

Nothing leaves your machine at any step — zero network calls is the default and only mode. The report records which rule fired where, so review is a read of the patch, not an audit of the tool.

The part no codemod fixes

Honest scope: the pack handles the mechanical rewrites. It does not restructure code that depends on v2-only behavior — global configuration via AWS.config, implicit credential chains that v3 resolves differently, or code that passes clients across module boundaries and mixes services in one file. Those need a human decision, and the tracked AWS change history (4 breaking or deprecation entries in the database) shows the same split: runtime and platform requirement changes stay not code-fixable by verdict, because pretending a codemod covers them is how migrations go wrong.

Related

Every entry on this page is generated from the mendapi change database at build time and links its upstream source.