Skip to content

Running Embeddings and Vector Databases locally

Use this page to run the extracted course chatbot on your computer. It installs two packages the download leaves out, adapts the chatbot's OpenAI and Supabase settings for Vite, and starts the browser project against the database you built during the course.

What you need first

Install a supported LTS version of Node.js. Node 24 is recommended and includes npm. You also need an OpenAI API key and an existing Supabase project containing the course data.

For Supabase, use a publishable key (it starts with sb_publishable_) or the legacy anon key. These keys are designed to appear in browser code: anyone who copies one can only do what your Row Level Security policies, Supabase's per-row access rules, permit. Supabase is retiring the legacy keys by the end of 2026, so prefer the publishable key when your project shows one. Never put a secret key or service_role key in this browser project. See Supabase API keys for the current key types.

The OpenAI key has no equivalent scoping: any copy of it can make requests billed to your account, so in production it never belongs in client code. This learning setup sends it to the browser anyway, and the warning in the Vite section below explains the limits of doing that. The Vercel AI SDK project shows the server-side arrangement: it uses a Supabase secret key, which is acceptable there because that project runs on a server and its keys never reach a browser.

JunoWhat you need first Install Node.js LTS, then have your OpenAI key and the Supabase project you built during the course ready.

For Supabase, use a publishable or anon key, the kind designed for browsers, never a server secret.

JunoWhat you need first This project needs Node plus two live services: OpenAI and the Supabase database from the course.

The Supabase key you configure becomes readable in client code, so it must be a publishable or anon key whose access Row Level Security limits. Keep every server-side key out of this project.

JunoWhat you need first A copied publishable or anon key can only do what your Row Level Security policies permit, which is why that key type is made for browser code. The OpenAI key has no such scoping and spends your money until you revoke it.

So a Supabase key in client code is a policy question, while an OpenAI key in production client code is a mistake.

Open the project folder

Open a terminal in the extracted chatbot folder containing package.json:

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

To confirm you have the right download, open package.json: the chatbot declares Vite, and the source beside it includes the config.js and index.js files the next section edits. These instructions fit the completed chatbot, whose code imports both openai and @supabase/supabase-js; the folder name alone does not distinguish it from an earlier lesson's download.

JunoOpen the project folder Work in the extracted folder that holds package.json; every install and every file on this page belongs there.

If the terminal is anywhere else, the commands run in the wrong folder. Check the folder listing for package.json before you type anything.

JunoOpen the project folder Confirm the folder before editing anything: package.json at the top level with Vite declared inside it, and config.js and index.js beside it.

Every command on this page assumes you are in this folder.

JunoOpen the project folder Read the imports before you repair anything. These steps fit the download whose source imports both OpenAI and Supabase and runs the completed chatbot flow.

An earlier lesson's download looks nearly identical by folder name, and applying these edits to it fixes problems it does not have.

Prepare the project for Vite

Install the declared Vite dependency, then the two packages the source imports but the downloaded package.json does not declare:

bash
$ npm install
$ npm install openai @supabase/supabase-js

Open config.js and replace every Scrimba environment read. Keep the existing imports, exports, and validation, but replace three environment names across four occurrences:

js
process.env.OPENAI_API_KEY
import.meta.env.VITE_OPENAI_API_KEY

process.env.SUPABASE_API_KEY
import.meta.env.VITE_SUPABASE_API_KEY

process.env.SUPABASE_URL
import.meta.env.VITE_SUPABASE_URL

The two OPENAI_API_KEY reads sit in the validation check and the OpenAI client, so change both.

Open index.js and change the chat model from gpt-4 to gpt-4o-mini. Leave the supplied text-embedding-ada-002 embedding model unchanged while following the course. Existing vectors in the course database must have the same dimensions as the query embeddings; changing that model is a separate database migration, not part of local setup.

Create .env beside package.json:

dotenv
VITE_OPENAI_API_KEY=your-openai-api-key
VITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_API_KEY=your-publishable-or-anon-key

Also create .gitignore:

txt
.env
node_modules/

Sending .env to a Git repository is the most common way a key leaks; ignoring files and good habits covers the habit in full.

These credentials are visible in the browser

Vite copies VITE_ values into the frontend bundle. Use restricted learning credentials, enable Row Level Security in Supabase, and never publish this version. A production app must move the OpenAI request to a backend.

JunoPrepare the project for Vite Install the missing packages, replace every old environment read with its Vite equivalent, and put your keys in .env with a browser-safe Supabase key.

Then add .gitignore so .env stays out of Git.

JunoPrepare the project for Vite The source imports two SDKs the download never declared and reads Scrimba's environment names, so install both packages and change all four reads before starting Vite.

A read you miss fails when the page runs, not when Vite starts. The .env and .gitignore pair finishes the repair.

JunoPrepare the project for Vite Installing the SDKs fixes the imports; the VITE_ names are what place the values in the bundle, which also delivers the OpenAI key to browser code.

That is acceptable for a lesson and disqualifying for production, so move the OpenAI call behind a backend before real users reach this chatbot.

Run the project

bash
$ npm start

Open the Local URL printed by Vite and ask the chatbot a question covered by the course data. A useful answer shows that the page, Supabase retrieval, and OpenAI request are all working. Restart the command after changing .env, and stop it with Ctrl+C.

JunoRun the project Run npm start, open the Local URL, and ask the chatbot something the course data covers.

If you change .env, restart the command so Vite reads the new values. Press Ctrl+C when you finish.

JunoRun the project Vite starting cleanly proves the repaired project bundles; a useful answer proves the rest.

One good question tests OpenAI access and the Supabase rows and policies together, so treat it as your integration test. Restart after any .env change.

JunoRun the project A page that loads is not a passing test. Local serving, Supabase retrieval, embedding lookup, and answer generation are separate checkpoints, and each can fail behind a normally rendered page.

Troubleshooting

Failed to resolve import "openai" or "@supabase/supabase-js": Run both of the install commands shown earlier on this page, in the folder that contains package.json.

process is not defined: A process.env reference remains in config.js. Replace it with the matching import.meta.env.VITE_... value.

Supabase returns no rows or a permissions error: Confirm the project URL, use a publishable or anon key, and check that the course table and Row Level Security policies exist in that same project.

OpenAI rejects the model or key: Confirm billing and key access in the OpenAI account. Use a current model available to that project.

JunoTroubleshooting Read the error as a clue: a missing import means the extra packages are not installed, process is not defined means a Vite name is still wrong, and empty answers usually point to Supabase data or permissions.

Fix one at a time and run the page again after each.

JunoTroubleshooting Check in dependency order: package resolution, then all four environment substitutions, then the Supabase URL and RLS policies, then the OpenAI key and model.

Each layer depends on the one before it, so stop at the first broken layer and repair it there.

JunoTroubleshooting A chatbot with no useful answer fails in one of three layers: the browser bundle, Supabase permissions and rows, or the OpenAI request. Check them in that order; a page that opens proves only that Vite is running.