The third language of the web
A page built with only HTML and CSS is a poster — it looks good but doesn't react. JavaScript adds logic and interactivity: respond to clicks, change content on the fly, validate forms, load data, and animate things in response to the user.
React to users
Run code when someone clicks, types, scrolls, or submits a form.
Change the page
Update text, images, and styles after the page has loaded — no refresh.
Add logic
Make decisions with if, repeat work with loops, store data in variables.
Talk to servers
Fetch live data from APIs and show it without leaving the page.
Where JavaScript goes
Like CSS, you can write JS inline, but the right way is an external .js file linked
with a <script> tag — placed just before </body>
so the HTML exists before your code runs.
<body> <h1>Hello</h1> <!-- Load JS last so the page is ready --> <script src="js/script.js"></script> </body>
// This runs in the browser console.log("Hello from JavaScript!"); // Open DevTools (F12) → Console tab to see it
F12) so you can see what your code is doing.Variables & data types
Variables store values. Use const by default (a value that won't be reassigned) and
let when it will change. Avoid the old var.
const name = "Ada"; // string (text) let age = 30; // number const isStudent = true; // boolean (true / false) const hobbies = ["code", "art"]; // array (a list) const user = { name: "Ada", age: 30 }; // object (key/value) age = 31; // OK — let can change // name = "Bob"; ← ERROR — const can't be reassigned
Functions — reusable blocks of code
A function is a named set of steps you can run whenever you want. Pass it inputs (parameters) and it can return a result. Click below to run a real one.
// Define once… function greet(person) { return "Hello, " + person + "! 👋"; } // …then run it — here, on a button click const out = document.getElementById("greetOut"); document.getElementById("greetBtn").addEventListener("click", () => { out.textContent = greet("friend"); // "Hello, friend! 👋" }); document.getElementById("greetClear").addEventListener("click", () => { out.textContent = "Output will appear here…"; }); // Modern "arrow function" — same thing, shorter const greet2 = (person) => `Hello, ${person}!`;
<div class="d-row"> <button class="btn" id="greetBtn">Run greet("friend")</button> <button class="btn ghost" id="greetClear">Clear</button> </div> <div class="out" id="greetOut">Output will appear here…</div>
.d-row { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; } .btn { padding: 10px 18px; border-radius: 8px; border: none; cursor: pointer; font: inherit; font-weight: 700; background: linear-gradient(135deg,#eab308,#f59e0b); color: #1a1a1a; } .btn.ghost { background: transparent; border: 1px solid #eab308; color: #fde047; } .out { margin-top: 14px; padding: 14px 16px; border-radius: 8px; background: #0d0d12; border: 1px solid rgba(255,255,255,.1); font-family: 'SF Mono', Consolas, monospace; font-size: 0.88rem; color: #a7f3d0; min-height: 48px; white-space: pre-wrap; }
Your first interaction
Here's everything working together: a variable holds a count, a function changes it, and a click runs the function. This is the heartbeat of every interactive page.
<div class="d-row"> <button class="btn ghost" id="minus">−</button> <span class="count-big" id="countView">0</span> <button class="btn" id="plus">+</button> </div>
let count = 0; const view = document.getElementById("countView"); document.getElementById("plus").addEventListener("click", () => { count = count + 1; view.textContent = count; // update what's on screen }); document.getElementById("minus").addEventListener("click", () => { count = count - 1; view.textContent = count; // update what's on screen });
.d-row { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; } .btn { padding: 10px 18px; border-radius: 8px; border: none; cursor: pointer; font: inherit; font-weight: 700; background: linear-gradient(135deg,#eab308,#f59e0b); color: #1a1a1a; } .btn.ghost { background: transparent; border: 1px solid #eab308; color: #fde047; } .count-big { font-size: 2rem; font-weight: 800; color: #fde047; min-width: 56px; text-align: center; }
getElementById and
addEventListener are the DOM in action — learn them properly in
DOM & Events, then build engaging UI in
Interactive Effects.The different kinds of JavaScript
It's all one language — but you'll hear many names. They're just different tools and ways of using JavaScript. Here's what each is for, so the words stop being scary.
Vanilla JS
Plain JavaScript, no add-ons — exactly what you wrote above. Runs in every browser. Start here; you can do a lot with it alone.
Libraries
Pre-written code you drop in for one job: Three.js (3D), GSAP (animation), Chart.js (charts), Leaflet (maps), jQuery (older DOM helper).
Frameworks
Structure for whole apps: React, Vue, Angular, Svelte. They manage big, data-driven UIs so you write less repetitive DOM code.
Node.js
JavaScript outside the browser — on servers and your own machine. Powers back-ends, APIs, and the build tools behind most modern sites.
TypeScript
JavaScript plus a type system that catches bugs before you run the code. It compiles back down to plain JS. Common on larger teams.
WebGL & Canvas
Browser drawing APIs for graphics and games. Three.js sits on top of WebGL to make 3D far easier — see it in action below.
What a library unlocks — Three.js in action
A library hands you superpowers. Three.js is a library for 3D: in a few dozen lines it builds a real 3D scene and animates it at 60 fps. Here's a little train looping a track — all rendered live with Three.js.
The train, track, and scenery are all 3D objects — Three.js draws them every frame, ~60 times a second.
Open the full demo// Simplified excerpt to show the shape of Three.js code — the full, runnable // version is the live demo above (click "Open the full demo"). // A library means someone already wrote the hard 3D math. import * as THREE from "three"; const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(50, w/h, 0.1, 100); camera.position.set(0, 4.5, 6); const renderer = new THREE.WebGLRenderer({ canvas }); // A round track + a train made of little boxes const R = 2.4; const track = new THREE.Mesh( new THREE.TorusGeometry(R, 0.07, 12, 80), new THREE.MeshStandardMaterial({ color: "#9aa3b2" }) ); track.rotation.x = -Math.PI / 2; // lay it flat scene.add(track); // Each frame: move every car a little further around the circle function tick() { theta += 0.012; cars.forEach((car, i) => { const a = theta - i * 0.32; car.position.x = Math.cos(a) * R; // x on the circle car.position.z = Math.sin(a) * R; // z on the circle car.rotation.y = -a; // face the way it's going }); renderer.render(scene, camera); requestAnimationFrame(tick); // ~60 times a second } tick();
The essentials
const x = 5; // value that won't change let y = 10; // value that will change if (x < y) { /* … */ } else { /* … */ } // decisions for (let i = 0; i < 3; i++) { console.log(i); } // loop function add(a, b) { return a + b; } // function const mul = (a, b) => a * b; // arrow function console.log("debug:", x, y); // print to Console