A thenable is any object with a callable then() method. Promises are thenable, but not every thenable is a real Promise. JavaScript treats thenables as promise-like values and can adopt them with Promise.resolve() or await.
This matters when you work with libraries, custom async wrappers, or objects that behave like promises without being created by the Promise constructor. For related promise behavior, see JavaScript Promise.resolve() and JavaScript Promise.reject().
Tested On: The examples were tested with Node.js v20.18.1 on a Linux system. Promise and thenable adoption behavior works the same way in modern browsers and JavaScript runtimes.
Method 1: Create a Thenable Object
A thenable only needs a then() method.
const thenable = {
then(resolve) {
resolve("thenable resolved");
},
};Promise.resolve() can adopt this object even though it is not a real Promise instance.
Method 2: Resolve a Thenable with Promise.resolve()
Promise.resolve(thenable).then((value) => {
console.log("thenable:", value);
});Tested output:
thenable: thenable resolvedThis is the main reason thenables are useful. JavaScript can normalize them into promise chains.
Method 3: Await a Thenable
await also adopts thenables.
async function run() {
const value = await thenable;
console.log(value);
}Output:
thenable resolvedThis is why many libraries can return promise-like objects without using native promises directly.
Method 4: Thenable vs Promise
A Promise is a built-in async object. A thenable is any object with a then() method.
const promise = Promise.resolve("ready");
const customThenable = { then(resolve) { resolve("ready"); } };Use a Promise when you want standard async behavior and a thenable when you need promise-like compatibility. If you are normalizing data from unknown sources, Promise.resolve() is usually the safest bridge because it adopts both promises and thenables into the same flow.
Common Questions About Thenables
What is a thenable in JavaScript?
A thenable is an object that has a then() method and can be treated like a promise-like value.
Is every promise a thenable?
Yes. A Promise has a then() method, so it is thenable. The reverse is not true.
What is the difference between thenable and promise?
A Promise is a native JavaScript async object. A thenable is any object that implements then() and can be adopted by Promise APIs.
When should I use Promise.resolve with a thenable?
Use Promise.resolve() when a library or helper returns a promise-like object and you want to treat it like a normal promise in your own code.
Summary
A JavaScript thenable is a promise-like object with a then() method. Use Promise.resolve() or await to adopt thenables into normal promise flow. This pattern is important when you work with custom async wrappers or libraries that return promise-compatible objects instead of native promises, especially when you need to compare the behavior with Promise.resolve() and Promise.reject().
