Skip to content

Running Multimodality locally ​

Use this page to run the extracted image-generation project or the extracted vision project from the Multimodality course on your computer, with your own OpenAI key. Three things differ from Scrimba's editor: the OpenAI package needs updating, the model each project asks for has been retired, and the key in index.js needs Vite's syntax.

What you need first ​

Install a supported LTS version of Node.js. Node 24 is recommended and includes npm. Anything older than Node 22.12 is too old for the packages these projects install.

Check that both commands work. Your version numbers may be different:

bash
$ node --version
v24.18.0
$ npm --version
11.18.0

You also need an OpenAI API key on an account with billing set up. Create a key you will delete when you are done, and set a low monthly budget for the project in the OpenAI dashboard; the danger box below says why. For the image-generation project, OpenAI may ask you to verify your organization in the dashboard before its image models will answer.

JunoWhat you need first Install the LTS version of Node.js, which includes npm, and check that node --version and npm --version both print a version.

Then create an OpenAI API key on an account with billing, and set a low budget. If you have the image-generation project, check whether the dashboard asks you to verify your organization.

JunoWhat you need first Node and npm install and serve the project, and never look at your key. OpenAI checks the key, the billing and the organization only when the page sends a request.
JunoWhat you need first Both projects create the OpenAI client with dangerouslyAllowBrowser: true. Without that option the SDK refuses to run in a browser, which is the SDK's own sign that this setup is for your computer only.

Install the packages ​

Open a terminal in the extracted project folder. It is the one containing package.json and index.js:

bash
$ cd path-to-your-extracted-project

Install the project's packages, then replace its OpenAI package with the current one. The course's version comes from 2023, before the models you are about to switch to:

bash
$ npm install
$ npm install openai@latest

The first command reports added 61 packages. The second reports added 1 package, removed 45 packages, changed 1 package, because the current OpenAI package needs far fewer helpers. On a Mac, the second one may end with an allow-scripts warning about fsevents; it does not stop the project.

JunoInstall the packages Open the terminal in the folder that contains package.json, run npm install, then run npm install openai@latest.

If npm says it cannot find package.json, you are in the wrong folder.

JunoInstall the packages The first install brings in Vite and the course's OpenAI package. The second swaps that package for the newest release and writes the new version into package.json, so a later npm install keeps it.
JunoInstall the packagespackage.json pins openai to exactly 4.20.0, so only an explicit @latest moves it. Vite is listed as latest, so it already resolves to the newest version on every fresh install.

Change the model ​

Open index.js. It tells you which project you have: if it calls openai.images.generate, it is the image-generation project; if it calls openai.chat.completions.create, it is the vision project. Make only your project's change below.

Image generation. The project asks for dall-e-3, which OpenAI has retired. Its replacement, gpt-image-2, sends the picture back as base64 text instead of a link, so two parts of generatePoster change. Change the request from:

js
const image = await openai.images.generate({
   model: "dall-e-3",
   prompt
});

to:

js
const image = await openai.images.generate({
  model: "gpt-image-2",
  prompt,
  size: "1024x1024",
})

Then change the line that reads the image from:

js
const imgURL = image.data[0].url;

to:

js
const imgURL = `data:image/png;base64,${image.data[0].b64_json}`;

The line after it, which puts imgURL into the page, stays as it is.

Vision. The project asks for gpt-4-vision-preview, which OpenAI has retired. Change:

js
model: "gpt-4-vision-preview",

to the image-capable gpt-4o-mini:

js
model: "gpt-4o-mini",

The rest of the request, the text and the image link, stays as the course wrote it.

JunoChange the model Find which project you have from the call in index.js. For image generation, change the model, add the size line and change the imgURL line; with the old .url line, the poster shows as a broken image. For vision, change the one model line.
JunoChange the model The poster page shows the picture with an img tag, which needs an address; the data URL carries the whole picture inside that address. The vision request sends one message with a text part and an image link, and gpt-4o-mini reads both, so only its name changes.
JunoChange the model GPT Image models return b64_json rather than a hosted URL, so the old line writes src="undefined" and the catch never runs, because nothing threw. In the vision project, OpenAI downloads the image link itself, so a localhost address or a file from images would not reach it as a plain URL.

Give the project your key ​

Scrimba's editor fills in process.env.OPENAI_API_KEY for you. The browser has no process, and Vite does not create one, so the key line near the top of index.js must change from:

js
apiKey: process.env.OPENAI_API_KEY,

to:

js
apiKey: import.meta.env.VITE_OPENAI_API_KEY,

Vite hands browser code only the variables whose names start with VITE_, which is why the name gains that prefix. Leave the dangerouslyAllowBrowser: true line below it as it is.

Then create .env beside package.json and put your key in it:

dotenv
VITE_OPENAI_API_KEY=your-openai-api-key

Create .gitignore beside package.json and add:

txt
.env
node_modules/

A key that reaches a Git repository stays in its history even after you delete the file. The Git handbook covers the habit in ignoring files and good habits.

This key is visible in the browser

Vite writes every VITE_ value into the code it sends to the browser, so anyone who opens this page can read your key, and every poster or description is charged to your account. Keep this version on your own computer: never deploy or share it, and never commit .env. A version you publish needs a backend or serverless function that keeps the key on the server.

JunoGive the project your key Change the apiKey line to the import.meta.env form and leave the line under it alone. Then make a file called .env next to package.json with your key on one line, and list .env in .gitignore so Git never saves it.
JunoGive the project your key Vite replaces each import.meta.env.VITE_... read with the value from .env. A name without the prefix is hidden from browser code, so it arrives as undefined rather than as an error. When you save .env while the project runs, Vite restarts itself and serves the new value.
JunoGive the project your key The client is built at the top of index.js, so a leftover process.env throws before anything after it runs. In the image-generation project that means the form's submit handler is never attached.

Start the project ​

Start the development server:

bash
$ npm start

Vite may first print a warning that begins (!) Your Vite config uses features. It does not stop the project. Below it, Vite prints the address to open:

text
  VITE v8.3.4  ready in 1825 ms

  ➜  Local:   http://localhost:5173/

Open the exact Local address. If you create or save .env while the project runs, the terminal shows [vite] .env changed, restarting server... and the page picks up the new key.

Image generation. The page is titled Film-Fusion. Type a movie title, choose an art style, and click Generate Poster. The form clears and the box below it shows Generating poster for "…" in the style of …. The poster replaces that line when OpenAI answers, which can take a while. If the box shows Sorry, an error occurred while generating the poster. instead, the reason is in the browser console.

Vision. The project sends its request as soon as the page opens, so the page stays blank while OpenAI looks at the picture. When the answer arrives, the picture of a building appears and the answer is printed in the browser console, not on the page. The console shows it folded up: click the arrow beside it, then the one beside message, to read content, the description. Every reload sends a new request, and Vite reloads the page each time you save index.js.

To read the console, open your browser's developer tools (F12, or Cmd+Option+J in Chrome on a Mac) and choose the Console tab. A red 404 for favicon.ico is harmless; the troubleshooting below matches the other messages.

Stop the project with Ctrl+C.

JunoStart the project Run npm start, ignore the config warning if it appears, and open the Local address.

For image generation, submit a title and a style and wait for the poster. For vision, open the Console and wait for the answer. If neither appears, read the red error in the Console.

JunoStart the project The page opening only proves that Vite works. The poster or the description needs a request from your browser to OpenAI to succeed, so a missing result is a key, account or model question, not an install one.
JunoStart the project The vision request is a top-level await with no try/catch. A failure stops the module before it adds the picture, which is why a failed request leaves the page blank and puts an uncaught error in the console.

Troubleshooting ​

Generate Poster only clears the form: The address gains ?art-styles=… and no Generating poster line appears. The code stopped while the page was loading, before the button was wired up; the console says which of the next two problems it is.

The console says process is not defined: The apiKey line in index.js still reads process.env. Change it to the import.meta.env form and save.

The console says Missing credentials: The browser has no key. Check that .env is beside package.json and that the name is exactly VITE_OPENAI_API_KEY, then save it. The message suggests OPENAI_API_KEY; keep the VITE_ name.

The console says 401 Incorrect API key provided: The key arrived, but OpenAI did not accept it. Copy it again from your OpenAI dashboard and check that it has not been deleted.

The console says 429 You exceeded your current quota: The key works, but the account has no credit to spend. Add credit under Billing in the OpenAI dashboard, then try again.

The console mentions organization verification or model access: Your account cannot use the image model yet. Verify your organization in the OpenAI dashboard, wait for it to take effect, then try again.

The poster is a broken image: The imgURL line still reads .url. Change it to the b64_json line shown above.

The console says the model does not exist: Check that index.js asks for gpt-image-2 or gpt-4o-mini, not the old model. OpenAI plans to stop serving gpt-4o-mini on January 14, 2027; after that, use the replacement its deprecations page names.

JunoTroubleshooting Find the red error in the Console, skip the favicon.ico one, and match it to a bold heading above. Most of these are one line in index.js or .env that still needs changing.
JunoTroubleshootingprocess is not defined and Missing credentials stop the page before any request leaves. A 401, a 429, a verification or a model error is OpenAI turning down a request that went out.
JunoTroubleshooting A 401 means the request reached OpenAI with a key it rejected, so Vite's replacement worked. Missing credentials comes from the SDK itself: with no key, it throws while building the client and sends nothing.