Skip to content

Running Intro to Mistral AI locally ​

Use this page to run the extracted Intro to Mistral AI project on your computer and get an answer from Mistral with your own key. Two things differ from Scrimba's editor: one line in index.js must read the key Vite's way, and the answer appears in your browser's console, not on the page. The project asks Mistral its question as soon as the page loads, so there is no button to click.

What you need first ​

Install a supported LTS version of Node.js. Node 24 is recommended and includes npm.

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 a Mistral API key, because the project asks Mistral for its answer. Create one in Mistral's console by following Mistral's API key steps. Give it an expiration date a few days away and copy it straight away: Mistral shows the full key only once. This project calls Mistral from the browser, so the key ends up in the page.

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 a Mistral API key with a short expiry and copy it somewhere safe before you close the dialog. You can't see it again afterwards.

JunoWhat you need first Your browser does all the work here: it loads the page, then sends your key and the question to Mistral itself. Node and npm are only needed to install the packages and run Vite, which serves the page.
JunoWhat you need first Each page load sends one request, then one more for every function Mistral asks for, up to five, so every reload spends requests from your key.

Install the packages ​

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

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

npm finishes by reporting how many packages it added:

text
added 20 packages, and audited 21 packages in 9s
JunoInstall the packages Open the terminal in the folder that contains package.json and run npm install. It should end by saying how many packages it added.

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

JunoInstall the packages npm installs two packages and what they need: Mistral's JavaScript SDK, which sends the chat requests, and Vite, which serves the page and later puts your key into it.
JunoInstall the packages The SDK is pinned to 0.1.3, the version the course was recorded with, while Vite is latest. Keep the SDK version: newer major versions export a different client, and the course code would stop working.

Change one line in index.js ​

Scrimba's editor fills in process.env.MISTRAL_API_KEY for you. The browser has no process, and Vite does not create one, so the key read must change.

Open index.js and change the third line from:

js
const client = new MistralClient(process.env.MISTRAL_API_KEY);

to:

js
const client = new MistralClient(import.meta.env.VITE_MISTRAL_API_KEY);

Vite hands browser code only the variables whose names start with VITE_, which is why the name gains that prefix. The rest of the file stays as the course wrote it.

JunoChange one line in index.js In index.js, replace process.env.MISTRAL_API_KEY with import.meta.env.VITE_MISTRAL_API_KEY and save the file.

That one line is the only code change this project needs.

JunoChange one line in index.js When Vite serves index.js, it 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.
JunoChange one line in index.js The SDK's constructor falls back to process.env.MISTRAL_API_KEY when it is given undefined. So a key Vite cannot find fails with the same message as an unchanged line: process is not defined, thrown from inside the SDK.

Add your key to .env ​

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

dotenv
VITE_MISTRAL_API_KEY=your-mistral-api-key-here

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. 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 to .env Make a file called .env next to package.json with your key on one line, then list .env in .gitignore so Git never saves it.
JunoAdd your key to .env Vite watches .env. Save a change while the project runs and Vite prints .env changed, restarting server..., then reloads the page, which asks Mistral again with the new key.
JunoAdd your key to .env The VITE_ prefix is an exposure allowlist, not secret storage: the key sits in the module Vite serves and in the Authorization header of every request the browser sends to Mistral.

Start the app and read the answer ​

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 app. Below it, Vite prints the address to open:

text
  VITE v8.3.4  ready in 740 ms

  ➜  Local:   http://localhost:5173/

Open the exact Local address. The page shows only the Mistral logo, and that is all it will ever show. The answer goes to the console, so open your browser's developer tools (F12, or Cmd+Option+J in Chrome on a Mac) and select the Console tab.

Within a few seconds the console prints Mistral's answer to "when was the transaction T1001 paid?": a sentence giving the payment date, October 5, 2021 (stored in tools.js as 2021-10-05). The wording is the model's own. That sentence means your key, the model and the function call all worked.

If no answer appears, the reason is in the console in red. Vite also copies the error into the terminal where it runs, on a line containing [vite] (client). The troubleshooting below matches each message.

Each time the page loads, including when Vite reloads it after you save a file, it asks Mistral again. Stop the project with Ctrl+C.

JunoStart the app and read the answer Run npm start, ignore the config warning if it appears, and open the Local address. Seeing only the logo is right.

Open the Console in your browser's developer tools and wait a few seconds for the answer about transaction T1001.

JunoStart the app and read the answer Mistral doesn't know the payment date. It asks for one of the functions in tools.js, such as getPaymentDate, the page runs it on the data there and sends back the result, and only then does Mistral write its sentence. The date in the answer comes from your code.
JunoStart the app and read the answerindex.js awaits the agent at the top level of the module with no try/catch, so a failed request becomes an uncaught error in the console and nothing on the page changes. Success and failure look the same until you read the console.

Troubleshooting ​

The console says process is not defined: Either index.js still reads process.env, or Vite found no key. Check the third line of index.js first. If it already reads import.meta.env.VITE_MISTRAL_API_KEY, check that .env is beside package.json and the name is exactly VITE_MISTRAL_API_KEY, then save .env: Vite restarts and the page asks Mistral again.

The console shows HTTP error! status: 401 and Invalid API Key: The key reached Mistral, but Mistral did not accept it. Check that .env holds the whole key, with no spaces around it. If the key has expired or been deleted in Mistral's console, create a new one. Save .env: Vite restarts and the page asks Mistral again.

The console shows another HTTP error! status:: Read the Response: text after it. It is Mistral's own explanation, and it says what to fix. If it names the model, compare mistral-large-latest in index.js with Mistral's models page and change only the model name. Keep the SDK at 0.1.3.

The console says Max retries reached, after about half a minute: Mistral kept answering with a rate limit or a server error. Wait a minute, then reload the page once.

JunoTroubleshooting Find the line in the Console that mentions process, HTTP error or Max retries and match it to a bold heading above.
JunoTroubleshootingprocess is not defined means no request left your browser. An HTTP error means one did and Mistral answered it, so the problem is the key, the model or the account, not your code.
JunoTroubleshooting A 429 or server error is retried up to five times with growing waits, then ends as Max retries reached. Any other failed status is thrown at once as an HTTP error, logged first as Request failed:, so it appears twice.