How to build a Book Cover Generator with Midjourney and Claude AI using Node.js
In this simple guide, we'll develop a Book Cover Generator using Midjourney and Claude with Node.js. Follow along, and you'll have a working app that turns book titles or summaries into custom cover images. Step 1: Setting Up a New Node.js Project To follow these steps, you need to have Node.js installed; if you don't get it from nodejs.org 1—Create a new folder for your project. I will call mine book-cover-generator, but you can give it any name. 2—Open your command line and go to this new folder. 3—Run the command npm init to initialize a new Node.js project. You'll be prompted to provide information about your project, such as its name, version, and entry point. You can press Enter to accept the default values for most prompts or run npm init -y to skip the prompts. 4—You'll have a package.json file in your folder when you're done. This file keeps track of all your project's packages and settings. Step 2: Gathering the needed API Kyes For this project, we need 2 API Keys: The first one is from Anthropic (Claude). You can get it here: https://console.anthropic.com The second one is from Apiframe (Midjourney API). You can get it here: https://apiframe.ai Now that you have your API Keys create a .env file in the project directory and store them there. ANTHROPIC_API_KEY=....... APIFRAME_API_KEY=...... Step 3: Let's install the necessary packages We'll need dotenv for environment variables, axios for API calls, and inquirer for getting input from the user. So run in the terminal: npm install dotenv axios inquirer Step 4: Writing the actual code First create an app.js file, and import and setup all the necessary packages: require('dotenv').config(); const axios = require('axios'); const inquirer = require('inquirer'); (async () => { // All the code we will be writing will be in here })(); 1— Get the user input for the book title or summary const { bookTitleOrSummary } = await inquirer.prompt([{ type: 'input', name: 'bookTitleOrSummary', message: 'Enter the book title or summary: ' }]) 2— Generate the prompt for Midjourney using Claude const ANTHROPIC_API_URL = 'https://api.anthropic.com/v1/messages'; const CLAUDE_PROMPT = `Create a Midjourney book cover prompt with visual elements, colors, composition, lighting. Choose any compelling genre and theme. The book title or summary is ${bookTitleOrSummary}. Don't use any dashes or hyphens or break lines!`; let MIDJOURNEY_PROMPT; console.log("Generating the prompt with Claude AI!"); try { const response = await axios.post(ANTHROPIC_API_URL, { model: 'claude-3-sonnet-20240229', max_tokens: 300, messages: [{ role: 'user', content: [{ type: 'text', text: CLAUDE_PROMPT }], }], }, { headers: { 'Content-Type': 'application/json', 'x-api-key': process.env.ANTHROPIC_API_KEY, 'anthropic-version': '2023-06-01' } }); MIDJOURNEY_PROMPT = response.data.content[0].text; console.log("MIDJOURNEY_PROMPT", MIDJOURNEY_PROMPT); } catch (e) { console.log(e); } // If the prompt was not generated, there is no need to continue if (!MIDJOURNEY_PROMPT) return; 3— Generate the book cover using Apiframe (Midjourney API) const APIFRAME_API_URL = 'https://api.apiframe.ai/imagine'; let bookCoverImages = []; console.log("Generating the Images with Midjourney!"); try { const response = await axios.post(APIFRAME_API_URL, { prompt: MIDJOURNEY_PROMPT, aspect_ratio: '2:3' }, { headers: { 'Content-Type': 'application/json', 'authorization': process.env.APIFRAME_API_KEY, } }); const taskId = response?.data?.task_id; // Now with this taskId we poll until we get the result // Using a webhook is the recommended way, but for the sake of making this tutorial simple, we will be polling let isReady = false; const APIFRAME_FETCH_API_URL = 'https://api.apiframe.ai/fetch'; do { console.log("Waiting for the Apiframe task to be complete!"); const response2 = await axios.post(APIFRAME_FETCH_API_URL, { task_id: taskId, }, { headers: { 'Content-Type': 'application/json', 'authorization': process.env.APIFRAME_API_KEY, } }); if (response2?.data?.status == "finished") { isReady = true; bookCoverImages = response2?.data?.image_urls; } else if (response2?.data?.status == "failed") { isReady = true; } else { // Wait for 2 seconds await new Promise((resolve) => setTimeout(resolve, 2000)); } } while(!isReady); } catch (e){ console.log(e); } console.log("Here are the generated images:", bookCoverImages)

In this simple guide, we'll develop a Book Cover Generator using Midjourney and Claude with Node.js. Follow along, and you'll have a working app that turns book titles or summaries into custom cover images.
Step 1: Setting Up a New Node.js Project
To follow these steps, you need to have Node.js installed; if you don't get it from nodejs.org
1—Create a new folder for your project. I will call mine book-cover-generator, but you can give it any name.
2—Open your command line and go to this new folder.
3—Run the command npm init
to initialize a new Node.js project. You'll be prompted to provide information about your project, such as its name, version, and entry point. You can press Enter to accept the default values for most prompts or run npm init -y
to skip the prompts.
4—You'll have a package.json file in your folder when you're done. This file keeps track of all your project's packages and settings.
Step 2: Gathering the needed API Kyes
For this project, we need 2 API Keys:
The first one is from Anthropic (Claude). You can get it here: https://console.anthropic.com
The second one is from Apiframe (Midjourney API). You can get it here:
https://apiframe.ai
Now that you have your API Keys create a .env file in the project directory and store them there.
ANTHROPIC_API_KEY=.......
APIFRAME_API_KEY=......
Step 3: Let's install the necessary packages
We'll need dotenv
for environment variables, axios
for API calls, and inquirer
for getting input from the user.
So run in the terminal:
npm install dotenv axios inquirer
Step 4: Writing the actual code
First create an app.js
file, and import and setup all the necessary packages:
require('dotenv').config();
const axios = require('axios');
const inquirer = require('inquirer');
(async () => {
// All the code we will be writing will be in here
})();
1— Get the user input for the book title or summary
const { bookTitleOrSummary } = await inquirer.prompt([{
type: 'input',
name: 'bookTitleOrSummary',
message: 'Enter the book title or summary: '
}])
2— Generate the prompt for Midjourney using Claude
const ANTHROPIC_API_URL = 'https://api.anthropic.com/v1/messages';
const CLAUDE_PROMPT = `Create a Midjourney book cover prompt with visual elements, colors, composition, lighting. Choose any compelling genre and theme. The book title or summary is ${bookTitleOrSummary}. Don't use any dashes or hyphens or break lines!`;
let MIDJOURNEY_PROMPT;
console.log("Generating the prompt with Claude AI!");
try {
const response = await axios.post(ANTHROPIC_API_URL, {
model: 'claude-3-sonnet-20240229',
max_tokens: 300,
messages: [{
role: 'user',
content: [{
type: 'text',
text: CLAUDE_PROMPT
}],
}],
}, {
headers: {
'Content-Type': 'application/json',
'x-api-key': process.env.ANTHROPIC_API_KEY,
'anthropic-version': '2023-06-01'
}
});
MIDJOURNEY_PROMPT = response.data.content[0].text;
console.log("MIDJOURNEY_PROMPT", MIDJOURNEY_PROMPT);
} catch (e) {
console.log(e);
}
// If the prompt was not generated, there is no need to continue
if (!MIDJOURNEY_PROMPT) return;
3— Generate the book cover using Apiframe (Midjourney API)
const APIFRAME_API_URL = 'https://api.apiframe.ai/imagine';
let bookCoverImages = [];
console.log("Generating the Images with Midjourney!");
try {
const response = await axios.post(APIFRAME_API_URL, {
prompt: MIDJOURNEY_PROMPT,
aspect_ratio: '2:3'
}, {
headers: {
'Content-Type': 'application/json',
'authorization': process.env.APIFRAME_API_KEY,
}
});
const taskId = response?.data?.task_id;
// Now with this taskId we poll until we get the result
// Using a webhook is the recommended way, but for the sake of making this tutorial simple, we will be polling
let isReady = false;
const APIFRAME_FETCH_API_URL = 'https://api.apiframe.ai/fetch';
do {
console.log("Waiting for the Apiframe task to be complete!");
const response2 = await axios.post(APIFRAME_FETCH_API_URL, {
task_id: taskId,
}, {
headers: {
'Content-Type': 'application/json',
'authorization': process.env.APIFRAME_API_KEY,
}
});
if (response2?.data?.status == "finished") {
isReady = true;
bookCoverImages = response2?.data?.image_urls;
} else if (response2?.data?.status == "failed") {
isReady = true;
} else {
// Wait for 2 seconds
await new Promise((resolve) => setTimeout(resolve, 2000));
}
} while(!isReady);
} catch (e){
console.log(e);
}
console.log("Here are the generated images:", bookCoverImages);
Step 5 - Running the app
In the terminal we've been using all along, run node app.js
. You should be prompted with the "Enter the book title or summary" message. After entering a book title or summary, the app will first use Claude AI to generate a prompt and then use it to generate the image using Apiframe, the API for Midjourney.
node app.js
Enter the book title or summary: a book about dogs
Generating the prompt with Claude AI!
MIDJOURNEY_PROMPT ......
Generating the Images with Midjourney!
Waiting for the Apiframe task to be complete!
Waiting for the Apiframe task to be complete!
Book cover images generated! true
Here are the generated images: [
'https://cdn.apiframe.pro/images/84189746933404518545974939685331-1.png',
'https://cdn.apiframe.pro/images/84189746933404518545974939685331-2.png',
'https://cdn.apiframe.pro/images/84189746933404518545974939685331-3.png',
'https://cdn.apiframe.pro/images/84189746933404518545974939685331-4.png'
]
Here is one of the generated images:
Yay, You are done! ✅
We now have a fully functional Book Cover Generator that uses Midjourney and Claude along with Node.js. You can definitely improve the app by:
Add a UI (User Interface) using any frontend stack
Improve the Claude prompt