← All provider guides

OpenAI Node SDK v3 to v4 migration: the six rewrites and what a codemod can safely do

openai sdk migration 26 tracked change records

The openai-node v4 release was not an incremental bump. It replaced the client model (Configuration + OpenAIApi are gone), renamed every completion method into a resource namespace, and removed the axios-style .data wrapper from responses. Code written against v3 fails at require time, and code that survives the import fails again one property access later. The failure surface is wide but repetitive, which makes it a codemod job rather than a weekend of hand edits.

The six mechanical rewrites

This list is read directly from the mendapi migration pack registry (openai-v3-to-v4) at page build time, so it matches what the codemod actually does:

  • Replace Configuration/OpenAIApi require with OpenAI default import
  • Replace Configuration + OpenAIApi instantiation with new OpenAI()
  • createChatCompletion -> chat.completions.create (syntax-aware)
  • createCompletion -> completions.create (syntax-aware)
  • createEmbedding -> embeddings.create (syntax-aware)
  • Drop axios-style .data wrapper on responses

The one that survives review and fails at runtime is the last: in v3 every response arrived wrapped as response.data.choices, in v4 it is response.choices. An editor find-and-replace on the method names alone leaves the .data accesses behind, and the code throws TypeError: Cannot read properties of undefined only on the first live call. The pack rewrites the method rename and the wrapper drop together, so the two halves of the same breaking change cannot get out of sync.

What the codemod refuses to touch

The method renames are syntax-aware, not string matches: a call like openai.createChatCompletion( is rewritten, but the same words inside a string literal, a comment, or a log line are left exactly where they are. On the bundled fixture that discipline is part of the golden regression: a legacy-hint string mentioning createChatCompletion( must survive the migration byte-for-byte or our build fails. Every rule in the pack is locked by fixture tests with negative controls, which is what keeps a rewrite that starts over-firing from ever reaching your repo.

Preview the whole migration as one diff

The pack runs locally as a dry run by default. On the bundled v3 fixture repo it rewrites one service file across five rule hits and writes a unified patch you can read before anything is applied:

npx mendapi scan
# -> which files touch the openai SDK, with line numbers
mendapi fix --migration openai-v3-to-v4
# -> dry run: changes.patch + fix-report.json, nothing applied
mendapi fix --migration openai-v3-to-v4 --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 client-model rewrites. It does not decide for you how to adopt v4-only behavior. The streaming API changed shape, error classes moved, and the SDK's Node version floor rose with later majors (the tracked OpenAI history counts 3 breaking or deprecation entries, and the runtime-requirement ones stay not code-fixable by verdict). If your v3 code implemented retry logic around axios error objects, that logic needs a human rewrite against v4's typed errors, and pretending otherwise 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.