Callback to ES6 Promise Converter
Convert callback-based JavaScript functions to ES6 Promises and async/await syntax. Supports error-first convention, multiple arguments, and bind patterns.
About
Legacy Node.js and browser codebases rely on error-first callbacks: fn(err, result). Migrating these to ES6 Promises is not a cosmetic change. Incorrect wrapping causes silent swallowed errors, unhandled rejections that crash processes, and subtle race conditions when multiple callbacks fire. This tool parses your callback-based JavaScript and generates correct Promise-wrapped equivalents using promisify patterns, inline new Promise constructors, or full async/await refactors. It handles single-result callbacks, multi-argument callbacks with named destructuring, and .bind() context patterns.
The converter assumes the Node.js error-first convention where the first callback argument is always err. Functions that deviate from this pattern (e.g., event emitters, streams with multiple events) require manual refactoring. The tool does not execute your code. It performs string-level pattern transformation. Always review generated output before deploying to production.
Formulas
The core transformation follows the error-first callback unwrapping pattern. Given a function fn that accepts arguments followed by a callback cb(err, result), the promisified version is constructed as:
Where fn = original callback-accepting function, args = all arguments except the trailing callback, err = first callback parameter (error or null), result = second callback parameter (success value).
For multi-argument callbacks with n results, the resolution maps named keys:
The detection algorithm scores callback likelihood using: position of parameter (last = +3), naming convention matching cb/callback/done/next (= +2), error-first pattern in body (= +2). A score ≥ 4 triggers automatic conversion.
Reference Data
| Pattern | Callback Signature | Promise Equivalent | Notes |
|---|---|---|---|
| Simple error-first | fn(cb) | await promisify(fn)() | Most common Node.js pattern |
| With arguments | fn(arg1, cb) | await promisify(fn)(arg1) | Callback is always last parameter |
| Bound method | obj.fn.bind(obj) | promisify(obj.fn.bind(obj)) | Preserves this context |
| Multi-result | cb(err, a, b) | Resolves to {a, b} | Named via argumentNames symbol |
| No error param | fn(result) | Manual wrap required | Non-standard, flagged as warning |
| Nested callbacks | fn1(fn2(fn3)) | Chained await calls | Eliminates callback hell |
| fs.readFile | fs.readFile(path, cb) | await readFile(path) | Node.js 16+ has native fs/promises |
| setTimeout | setTimeout(cb, ms) | new Promise(r ⇒ setTimeout(r, ms)) | Special case, no error argument |
| Event-style | emitter.on(event, cb) | Not directly promisifiable | Use once from events module |
| Conditional callback | if (cb) cb() | Requires manual refactor | Optional callbacks are ambiguous |
| Express middleware | fn(req, res, next) | Wrap in async handler | next is not error-first |
| Promisify whole module | Multiple methods | Loop + promisify each | Use promisifyAll pattern |