It's already 2026, but the question about promisification still pops up in interviews, mostly for Junior-інтервʼю. To understand how this workaround works, we first need to look at the problem it solves.
Callback hell
This is a situation where, because of many asynchronous calls based on callbacks, the code turns into a піраміду of nested functions. This makes it hard to read, debug, and handle errors properly.
In Node.js, callbacks are built like this: the first argument is помилка або null, if there is one. The second argument is дані, and a typical method that uses a callback looks like this:
Taken on its own, this function looks fine. But as soon as we get closer to a real project, where there can be many interdependent calls, callback hell begins.
This is where promisification comes in
Promisification is wrapping a callback-based function in a Promise. Then, instead of nested callbacks, you can conveniently write .then/.catch or async/await. This technique is usually used in two cases:
When Node.js had just released Promises - naturally, after the release not all libraries quickly switched their API from callback-based to Promise-based, so you had to wrap them this way to make them more convenient to work with.
Legacy - nowadays it's most often used for wrapping various legacy code. For example, your system has a method written by your great-grandfather, which of course used the callback-based approach.
This method has 2000 lines of code and nobody is going to rewrite it, but promisifying it to avoid callbacks is entirely doable. And very often this was part of a refactoring, since working with Promises is much simpler and more pleasant. Let's go back to the getUser method we looked at in the beginning. We can turn it into a Promise very quickly.
Now let's see what callback hell looks like once it's promisified: