Skip to content
Volume J · The TensorCore.si Library

JavaScript

The language of the web, and now of AI apps too.

JavaScript runs in every web browser and, through Node.js, on servers. It powers the chat interfaces, AI-powered websites and agent back ends that put models in front of billions of people.

Prologue

Why learn JavaScript?

If you want people to use your AI, they will probably use it through a browser. JavaScript is the only language every browser runs natively, and the same language works on the server, so one language covers the whole app.

  • Runs everywhere: browsers, servers, desktop apps (Electron) and mobile (React Native).
  • AI in the browser: libraries like Transformers.js run models on the user's own device with WebGPU.
  • First-class AI SDKs: OpenAI, Anthropic, Google and Vercel all publish JavaScript and TypeScript SDKs.
  • The npm registry is the largest package collection in the world.
Prologue

Set up and run your first program

You can start in any browser: press F12 and open the Console. For real projects, install Node.js (the LTS version) from nodejs.org, which also gives you npm for packages.

terminal
node --version
mkdir my-ai-app && cd my-ai-app
npm init -y
npm pkg set type=module      # use modern import/export
hello.js
console.log("Hello, AI!");
const name = "Ada";
console.log(`Welcome to JavaScript, ${name}.`);
TipRun it with node hello.js. Setting "type": "module" in package.json lets you use import and top-level await.
Chapter 1

Variables and data types

Declare values with const (cannot be reassigned) or let (can change). Avoid the old var. The basic types are number, string, boolean, null, undefined, bigint and symbol; everything else is an object.

Template literals use backticks and ${} to insert values into text.

variables.js
const model = "llama3.1";      // string
let tokens = 512;              // number (all numbers are floating point)
const streaming = true;        // boolean
let reply = null;              // intentionally empty
let next;                      // undefined

tokens += 128;
console.log(typeof tokens);    // "number"
console.log(`${model} can return ${tokens} tokens`);
console.log(Number("42") + 1); // 43
console.log("5" + 1, "5" - 1); // "51" and 4: watch out for type coercion
Chapter 2

Decisions and loops

if/else and switch choose a path. Use === (strict equality), never ==, to avoid surprising type conversions. for...of loops over values in arrays and strings.

control.js
const score = 0.82;
if (score >= 0.9) {
  console.log("Excellent");
} else if (score >= 0.7) {
  console.log("Good");
} else {
  console.log("Keep training");
}

for (const gpu of ["H100", "B200"]) console.log(gpu);
for (let i = 0; i < 3; i++) console.log("step", i);

switch (process.platform) {
  case "win32": console.log("Windows"); break;
  case "darwin": console.log("macOS"); break;
  default: console.log("Linux or other");
}
Chapter 3

Functions and closures

Functions are values: you can store them, pass them and return them. Arrow functions (=>) are the short modern form. A closure is a function that remembers variables from where it was created.

functions.js
function accuracy(correct, total = 100) {
  return (correct / total) * 100;
}
const double = (x) => x * 2;

function makeCounter() {
  let count = 0;                 // remembered by the closure
  return () => ++count;
}
const next = makeCounter();
next(); next();
console.log(next());             // 3

const apply = (fn, value) => fn(value);
console.log(apply(double, 21));  // 42
console.log(accuracy(45, 50));   // 90
Chapter 4

Arrays, objects, Map and Set

Arrays hold ordered lists and come with powerful methods: map, filter, reduce, find. Objects hold named properties. Map and Set are better when keys are not simple strings or values must be unique.

Destructuring and the spread operator ... unpack and copy data concisely.

collections.js
const gpus = [
  { name: "RTX 4090", vram: 24 },
  { name: "H100", vram: 80 },
  { name: "MI300X", vram: 192 },
];
const big = gpus.filter((g) => g.vram >= 80).map((g) => g.name);
const total = gpus.reduce((sum, g) => sum + g.vram, 0);
console.log(big, total);          // [ 'H100', 'MI300X' ] 296

const { name, vram } = gpus[1];   // destructuring
const copy = { ...gpus[0], vram: 32 };
const seen = new Set(["a", "b", "a"]);   // Set { 'a', 'b' }
const cache = new Map([["prompt-1", "answer"]]);
console.log(name, vram, copy, seen.size, cache.get("prompt-1"));
Chapter 5

Classes and objects

Classes are a clear syntax over JavaScript's prototype system. Use constructor for set-up, extends to inherit, and # for truly private fields.

classes.js
class Model {
  #apiKey;                                   // private field
  constructor(name, params) {
    this.name = name;
    this.params = params;
    this.#apiKey = "secret";
  }
  memoryGB(bytes = 2) { return this.params * bytes; }
  static fromString(s) { const [n, p] = s.split(":"); return new Model(n, Number(p)); }
}

class ChatModel extends Model {
  reply(text) { return `${this.name}: you said "${text}"`; }
}

const m = new ChatModel("Llama 3.1 8B", 8);
console.log(m.memoryGB(), m.reply("hi"));
console.log(Model.fromString("Qwen3:32").params);   // 32
Chapter 6

Handling errors

Throw an Error (or your own subclass) when something goes wrong and catch it with try/catch. With async code, await inside try catches rejected promises too.

errors.js
class OutOfMemory extends Error {}

function load(modelGB, vramGB) {
  if (modelGB > vramGB) throw new OutOfMemory(`needs ${modelGB} GB`);
  return "loaded";
}

try {
  load(140, 24);
} catch (err) {
  if (err instanceof OutOfMemory) console.log("Too big:", err.message);
  else throw err;
} finally {
  console.log("done");
}
Chapter 7

Modules and npm

ES modules split code into files with export and import. npm installs third-party packages into node_modules and records them in package.json.

main.js
// utils.js
export const toGB = (bytes) => bytes / 1e9;
export default function greet(name) { return `Hi ${name}`; }

// main.js
import greet, { toGB } from "./utils.js";
import { readFile } from "node:fs/promises";   // built-in Node module

console.log(greet("Ada"), toGB(8e9));

// terminal: npm install openai   then   import OpenAI from "openai";
Chapter 8

Files and JSON in Node.js

Node's fs/promises module reads and writes files without blocking. JSON.stringify and JSON.parse convert between objects and text.

files.js
import { readFile, writeFile } from "node:fs/promises";

const results = { model: "llama3.1", accuracy: 0.91 };
await writeFile("results.json", JSON.stringify(results, null, 2));

const data = JSON.parse(await readFile("results.json", "utf8"));
console.log(data.accuracy);
Chapter 9

Promises, async and await

JavaScript runs on a single thread with an event loop: slow tasks like network requests return a Promise and the program carries on. async/await lets you write that code in a readable top-to-bottom style. Promise.all runs several requests at once.

async.js
const wait = (ms) => new Promise((r) => setTimeout(r, ms));

async function ask(model) {
  await wait(1000);                  // stands in for a network call
  return `${model} answered`;
}

const answers = await Promise.all([ask("a"), ask("b"), ask("c")]);
console.log(answers);                // about 1 s in total, not 3 s

const res = await fetch("https://api.github.com/repos/pytorch/pytorch");
const repo = await res.json();
console.log(repo.stargazers_count);
Key ideafetch is built into browsers and Node.js 18+, so you can call AI APIs without installing anything.
Chapter 10

JavaScript in the browser

In a web page, JavaScript reads and changes the page through the DOM and reacts to events such as clicks and key presses. This is how chat interfaces show messages as they stream in.

index.html
<input id="q" placeholder="Ask something">
<button id="send">Send</button>
<div id="out"></div>
<script type="module">
  const out = document.querySelector("#out");
  document.querySelector("#send").addEventListener("click", () => {
    const p = document.createElement("p");
    p.textContent = "You: " + document.querySelector("#q").value;
    out.append(p);
  });
</script>
Chapter 11

Testing and tools

Node has a built-in test runner (node --test). ESLint finds bugs, Prettier formats code, and many teams move to TypeScript for type checking as projects grow.

utils.test.js
// utils.test.js   (run with: node --test)
import { test } from "node:test";
import assert from "node:assert/strict";
import { toGB } from "./utils.js";

test("converts bytes to GB", () => {
  assert.equal(toGB(2e9), 2);
});
Part II · AI with JavaScript

AI with JavaScript

JavaScript does AI in two ways. On the server, it calls model APIs and orchestrates agents. In the browser, it can run smaller models directly on the user's device using WebGPU or WebAssembly: private, offline and free to serve.

The essential libraries

Transformers.jsHugging Face models running in the browser or Node.js.
ONNX Runtime WebRun ONNX models with WebGPU or WebAssembly.
TensorFlow.jsTrain and run neural networks in JavaScript.
Vercel AI SDKStreaming chat UIs and tool calling for many providers.
LangChain.jsChains, retrieval and agents.
OpenAI / Anthropic SDKsOfficial clients for hosted models.
WebLLMLarge language models running fully in the browser.
Ollama JSClient for local models served by Ollama.

Run a model in JavaScript with Transformers.js

This classifies the sentiment of a sentence. The model downloads once, then runs locally, in Node.js or in the browser.

sentiment.js
// npm install @huggingface/transformers
import { pipeline } from "@huggingface/transformers";

const classify = await pipeline("sentiment-analysis");
const result = await classify("Tensor Cores make training so much faster!");
console.log(result);   // [ { label: 'POSITIVE', score: 0.99... } ]
Part III · Build an AI agent

Build an AI agent in JavaScript

The agent loop is the same in every language: send the conversation and your tool descriptions, run any tool the model asks for, send the result back, repeat. In JavaScript you need nothing but the built-in fetch.

Your goal→Model plans→Tool call→Your code runs the tool→Result back to model→Final answer
agent.js
const URL = "http://localhost:11434/v1/chat/completions";
const MODEL = "llama3.1";

const tools = {
  get_weather: ({ city }) => `It is 24°C and sunny in ${city}.`,
};
const toolSpecs = [{
  type: "function",
  function: {
    name: "get_weather",
    description: "Get the current weather for a city",
    parameters: {
      type: "object",
      properties: { city: { type: "string" } },
      required: ["city"],
    },
  },
}];

const messages = [{ role: "user", content: "Should I take an umbrella in Lahore today?" }];

while (true) {
  const res = await fetch(URL, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ model: MODEL, messages, tools: toolSpecs }),
  });
  const msg = (await res.json()).choices[0].message;
  messages.push(msg);
  if (!msg.tool_calls?.length) {          // final answer
    console.log(msg.content);
    break;
  }
  for (const call of msg.tool_calls) {
    const args = JSON.parse(call.function.arguments);
    const result = tools[call.function.name](args);
    messages.push({ role: "tool", tool_call_id: call.id, content: result });
  }
}

To put this agent on a website, run it on your server (never expose API keys in the browser) and stream answers to the page. The Vercel AI SDK and the OpenAI Agents SDK for JavaScript package this pattern with streaming and memory.

Run it locallyInstall Ollama, run ollama pull llama3.1, and keep it running. The code talks to its OpenAI-compatible API at http://localhost:11434/v1, so the same program also works with vLLM, llama.cpp server or a cloud API by changing the URL, model name and adding an API key.
Part IV · Your path

JavaScript learning roadmap

Tick items off as you go. Your progress is saved in this browser.

Beginner

Intermediate

Advanced

Part IV · Your path

Projects to build

To-do appAdd, tick and delete tasks in the browser, saved with localStorage.
Weather dashboardFetch a weather API and show a forecast with charts.
Browser AIClassify images from your webcam with Transformers.js, fully offline.
Streaming chatbotA chat page that streams replies from a local LLM.
Agent with web toolsA Node.js agent that can search and summarise pages.
Discord or Telegram botA bot that answers questions using an AI model.
Reference

JavaScript cheat sheet

TaskSyntax
Variableconst a = 1; let b = 2;
Template string`Hi ${name}`
Strict equalitya === b
Arrow functionconst f = (x) => x * 2;
Array methodsxs.map(f).filter(g)
Destructureconst { a, b } = obj;
Spreadconst c = { ...obj, a: 3 };
Optional chaininguser?.address?.city
Default valuevalue ?? "fallback"
Async functionasync function f() { await g(); }
Fetch JSONconst d = await (await fetch(url)).json();
Importimport { x } from "./x.js";
Reference

Common mistakes

  • Using == instead of ===: loose equality converts types, so "0" == false is true.
  • Forgetting await: you get a Promise object instead of the value.
  • Putting API keys in front-end code: anyone can read them. Call AI APIs from your server.
  • Changing arrays you are looping over: create a new array with map or filter instead.
  • Floating-point surprises: 0.1 + 0.2 is 0.30000000000000004. Round when displaying money.
Reference

Where to go next

On TensorCore.si: How AI works, LLM sampling simulator, AI Model Explorer.

Keyboard: [ previous language · ] next language · / search the library