Skip to content

Running Context Engineering locally ​

Use this page to run the summarization challenge you extracted from the Context Engineering module and watch it summarize a long conversation with your own OpenRouter key. The code runs as downloaded: you install the packages, add one .env file with your key and a model, and start it.

What you need first ​

Install a supported LTS version of Node.js. Node 24 is recommended and includes npm. The project uses Vite 7, which needs Node 22.12 or newer.

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

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

If node --version prints anything below v22.12.0, install Node 24 before you continue.

You also need an OpenRouter API key and a little credit on your OpenRouter account, because the app asks OpenRouter for every summary and reply. Create a key you will delete when you are done, and give it a low credit limit when you create it: this project calls OpenRouter straight from the browser, so the key ends up in the page.

JunoWhat you need first Install Node.js 24, which includes npm, and check that node --version prints v22.12.0 or higher.

Then add a little credit to your OpenRouter account (a dollar covers many summaries) and create a key with a low credit limit. That one key is all this project needs.

JunoWhat you need first The app makes two kinds of OpenRouter request: one asks the model for a summary of the older messages, and one streams the reply to your message. Both go out from your browser with the same key, so the key's credit limit caps what the page can spend.
JunoWhat you need first The Node floor comes from Vite 7, not from the app: its package.json asks for Node 20.19 or 22.12 and newer, and Node 20 is past end of life, so 22.12 is where to start.

Install the packages ​

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

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

npm ci installs exactly the versions listed in package-lock.json. npm finishes by reporting how many packages it added:

text
added 29 packages, and audited 30 packages in 6s

npm may also report vulnerabilities and suggest npm audit fix. Leave them for now: the fix can change the package versions the course was built on. npm may also warn about install scripts; that changes nothing here.

JunoInstall the packages Open the terminal in the folder that contains package.json, then run npm ci. npm ends by saying how many packages it added, and a node_modules folder appears.

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

JunoInstall the packagesnpm ci reads the lockfile instead of resolving versions again, so you get the same Vite, AI SDK and OpenRouter provider the challenge was written against. It also refuses to run if package.json and the lockfile disagree, which tells you early if a file was changed.
JunoInstall the packages The vulnerabilities npm lists are in vite and the build tools under it, and in ai and dompurify. Here they only affect a page served on your own computer while you learn; updating them is a separate change that moves you off the versions the lessons used.

Add your key and model to .env ​

The project reads two values: OPENROUTER_KEY and MODEL_ID. Scrimba's editor fills them in for you; on your computer they go in a file. Create .env beside package.json:

dotenv
OPENROUTER_KEY=your-openrouter-key-here
MODEL_ID=mistralai/ministral-3b-2512

Keep both names exactly as shown, with no VITE_ in front: the project's vite.config.js reads these two names and hands them to the browser code. mistralai/ministral-3b-2512 is a low-cost model on OpenRouter. Any OpenRouter model ID works; copy it exactly.

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.config.js writes both values into the code it sends to the browser, so anyone who opens this page can read your key. 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.

JunoAdd your key and model to .env Make a file called .env next to package.json with two lines: your key after OPENROUTER_KEY= and the model after MODEL_ID=. Then list .env in .gitignore so Git never saves it.

You don't need to change any JavaScript file.

JunoAdd your key and model to .envvite.config.js loads every value in .env, then defines process.env.OPENROUTER_KEY and process.env.MODEL_ID for the browser code in main.js and utils.js. That is why these names need no VITE_ prefix: the config file passes them on itself.
JunoAdd your key and model to .env In the development server, Vite sets the defined values on a process.env object in the page before your modules run, so the process.env reads in the source work as written. In a build, Vite replaces each read with the value itself. Either way, the key is plain text in what the browser loads.

Start the app and send a message ​

Start the development server:

bash
$ npm start

Vite prints the address to open:

text
  VITE v7.2.2  ready in 157 ms

  ➜  Local:   http://localhost:5173/

Open the exact Local address. The page opens on a long conversation that is already there, with the counters below it showing 26294 total tokens and 26294 context tokens. The app summarizes once the context passes 20,000 tokens, so your first message is enough.

Type any message and send it. The app shows Summarizing conversation while OpenRouter writes the summary. When it works, a Context Summary card appears under the counters (click it to read the summary), the context tokens count drops well below the total, and the reply to your message appears.

If you downloaded the challenge before finishing splitForSummary and generateSummary in summary.js, your first message gets stuck here: the app calls both as soon as it summarizes, and the console shows why.

If Summarizing conversation stays on screen and the send button stays grey, open your browser's developer tools (F12, or Cmd+Option+J in Chrome on a Mac) and read the Console tab. The reason is printed there, not on the page; the troubleshooting below matches each message. A red 404 for favicon.ico is harmless.

You don't need to restart anything after changing .env: when you save it, Vite restarts itself and the open page reloads with the new values. Stop the project with Ctrl+C.

JunoStart the app and send a message Run npm start, open the Local address, and send any message. Wait for the Context Summary card and the reply.

If it stays on Summarizing conversation, open the Console in your browser's developer tools and look for the red error that mentions OpenRouter or the API key.

JunoStart the app and send a message The page opening only proves that Vite works. The summary needs your browser's request to OpenRouter to succeed, so a page stuck on Summarizing conversation is a key, credit or model question, not an install one.
JunoStart the app and send a messagegenerateSummary runs before the try in handleUserMessage, so a rejected summary request becomes an uncaught promise rejection in the console and the input is never enabled again. Saving a fix to .env reloads the page and frees it. An error in the reply itself, after a summary works, shows in the chat as Error: instead.

Troubleshooting ​

The console says OPENROUTER_KEY env variable is not set, then OpenRouter API key is missing: The browser has no key. Check that .env is beside package.json and that the names are exactly OPENROUTER_KEY and MODEL_ID, then save it. The page reloads by itself.

The console shows 401 with User not found. or Missing Authentication header: The key reached OpenRouter, but OpenRouter did not accept it. Copy it again from your OpenRouter account and check that it has not been deleted. Missing Authentication header usually means .env still holds the example text instead of your key.

The console shows 402: The key works, but your account or the key's credit limit has no credit left. Add credit in OpenRouter, or raise the key's limit, then reload the page and send again.

The console says the model is not valid or not found: Check the MODEL_ID line in .env against the model's page on OpenRouter, letter for letter, including the part before the slash.

JunoTroubleshooting Find the red error in the Console that mentions the key, a 401 or a 402, and match it to a bold line above. After you edit .env and save it, wait for the page to reload, then send another message.
JunoTroubleshooting Keep two problems apart: Vite getting your values into the page, and OpenRouter accepting the key, the credit and the model. A missing key fails in your browser before any request; a status code means the request reached OpenRouter.
JunoTroubleshooting The AI SDK's OpenRouter provider throws API key is missing before sending anything when apiKey is undefined. Once a request goes out, the status is OpenRouter's: 401 for the key, 402 for credit, and a model error for the ID.