JavaScript for beginners: where to start in 2026
To learn JavaScript from scratch, start with the browser console and the VS Code editor, then work through variables, conditions and loops, functions, arrays and objects, the DOM, and finally fetch with async/await. With 30 to 60 minutes a day the basics usually take one to three months, and everything you need is free.
If you're still choosing a language, read where to start learning to code first.
What JavaScript is and why it makes a good first language
JavaScript (JS) is the language that brings web pages to life. HTML builds a page's structure, CSS handles its looks, and JavaScript adds behaviour: reacting to clicks, validating forms, fetching data from a server. It's a good first pick because it runs in every browser, costs nothing and shows results on screen straight away.
It was created at Netscape in 1995 and is now defined by the open ECMAScript standard, which gets a new edition every year. The same code also runs on servers through Node.js and in mobile and desktop apps. In the Stack Overflow Developer Survey 2025, 66% of respondents used JavaScript, more than any other language, so learning material and answers to common problems are easy to find.
The basics of HTML and CSS help first, since JS mostly works with page elements. Knowing tags, the id and class attributes and how a document is structured is enough, and you can polish CSS in parallel. If that's missing, start with the HTML and CSS basics guide.
A learning plan in eight steps
The most common mistake is jumping straight into React or TypeScript. Frameworks then look like magic and every error message like a riddle. Go through plain JavaScript first, in this order:
| Step | Topic | Mini project to finish the stage |
|---|---|---|
| 1 | Console, editor and Node.js | a greeting script |
| 2 | Variables and data types | a temperature converter |
| 3 | Conditions and loops | a number guessing game |
| 4 | Functions | a BMI calculator |
| 5 | Arrays and objects | a console shopping list |
| 6 | The DOM and events | an on-page to-do list |
| 7 | fetch and async/await | a weather app |
| 8 | Modules and debugging | a quiz split into files |
Along the way you'll find examples to run and links to free lessons from the CodeWorlds JavaScript course, if you'd rather practise with exercises. The examples also work on their own, and most need only a browser.
Setup: the browser, VS Code and Node.js
A browser is enough to begin. Open the developer tools (Ctrl+Shift+J in Chrome, Cmd+Option+J on a Mac), go to the Console tab and type 2 + 2. It's a full JavaScript environment and the quickest place to test an idea, as the lesson on first steps in the JavaScript console shows.
For longer code you need an editor such as the free Visual Studio Code with the Live Server extension, which reloads the page on every save. Your first project is two files in one folder:
<!-- index.html -->
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>First script</title>
<script src="script.js" defer></script>
</head>
<body>
<h1 id="title">Hello!</h1>
</body>
</html>// script.js
console.log("The script works");
document.querySelector("#title").textContent = "Hello from JavaScript!";The defer attribute runs the script only after the whole HTML has loaded, so the heading it changes already exists. The third piece is Node.js, which runs JavaScript outside the browser. Install the LTS version, check it with node --version, and run a hello.js file with node hello.js. Tools such as npm and Vite run on Node too.
| Environment | What you install | Good for | Limitations |
|---|---|---|---|
| Browser console | nothing | quick tests | variables vanish on reload |
| HTML file with a script | an editor | pages, the DOM and events | modules need a server |
| Node.js | Node.js LTS | scripts, tools, servers | no DOM or window |
| Bun or Deno | Bun or Deno | the same jobs as Node | courses usually assume Node |
The first two rows cover the basics. Leave Bun and Deno for later, since they run the same language and switching is easy.
Variables and data types
A variable is a named box for a value. Use const for a value you won't replace (the default) and let for one that changes. Leave the older var alone, because its scoping rules confuse beginners.
const userName = "Ada";
let score = 0;
score = score + 10;
console.log(`Hi, ${userName}! You have ${score} points.`);
console.log(typeof userName); // "string"
console.log(typeof score); // "number"
console.log(typeof true); // "boolean"Text in backticks is a template literal, and ${...} inserts values into it. Early on you'll meet text (string), numbers (number), true/false values (boolean), plus null and undefined, two ways of saying there's no value. Automatic type conversion causes the most trouble:
console.log("5" == 5); // true, because == converts types before comparing
console.log("5" === 5); // false, because the types differ
console.log("2" + 2); // "22", joined text
console.log("2" * 2); // 4, because multiplication turns text into a numberHence a simple rule: always compare with === and !==. Also note that const blocks reassignment but doesn't freeze an object, so you can still change its properties. Practise this in the lesson on variable declaration with var, let and const.
Conditions and loops
Conditions let a program make decisions, and loops let it repeat work without copying code.
const temperature = 23;
if (temperature > 25) {
console.log("It's hot, take some water");
} else if (temperature > 15) {
console.log("Perfect for a walk");
} else {
console.log("Take a jacket");
}
const tasks = ["shopping", "workout", "learning JavaScript"];
for (const task of tasks) {
console.log(`To do: ${task}`);
}
for (let i = 3; i > 0; i--) {
console.log(`Starting in ${i}...`);
}for...of walks through an array's elements and reads best at first. A classic for with a counter helps when you need the step number, and while when you don't know the number of repetitions.
An if condition needn't be a boolean. Values such as 0, the empty string "", null, undefined and NaN count as false, so if (userName) checks whether a name was given at all. The lesson on loops and iterations covers loops step by step.
Functions
A function is a named piece of code you call many times. It takes arguments and usually returns a result. You'll see two forms: the classic declaration with the function keyword and the shorter arrow function, handy for simple operations.
function greet(name) {
return `Hi, ${name}!`;
}
const applyDiscount = (price, percent = 10) => price - (price * percent) / 100;
console.log(greet("Ada")); // Hi, Ada!
console.log(applyDiscount(200)); // 180
console.log(applyDiscount(200, 25)); // 150percent = 10 is a default used when you skip the second argument. Variables created inside a function exist only there, so they don't clash with the rest of the program.
A good function does one thing, and its name says what. If describing it needs the word "and", it can usually be split in two. Breaking problems into small pieces matters more than knowing any syntax. See the lesson on functions for more examples.
Arrays and objects
An array stores an ordered list of values, and an object describes one thing through named properties. They usually appear together, as an array of objects such as products loaded from a server.
const products = [
{ name: "Keyboard", price: 199, inStock: true },
{ name: "Mouse", price: 89, inStock: false },
{ name: "Monitor", price: 899, inStock: true },
];
const available = products.filter((product) => product.inStock);
const names = available.map((product) => product.name);
const total = available.reduce((sum, product) => sum + product.price, 0);
console.log(names); // ["Keyboard", "Monitor"]
console.log(total); // 1098
const { name, price } = products[1];
const discounted = { ...products[1], price: 69 };
console.log(name, price, discounted.price); // Mouse 89 69filter keeps elements that pass a test, map turns each element into a new one, and reduce folds the array into a single value, here the total price. None of them changes the original array, which saves you from bugs that are hard to trace.
The end of the example shows destructuring, which pulls properties into separate variables, and the spread operator (...), which copies an object with chosen fields overwritten. You'll see both everywhere, especially in React. Practise with the lessons on forEach, map, filter and reduce and object properties and methods.
The DOM and events
The DOM (Document Object Model) is a tree-shaped representation of an HTML page that JavaScript can access. With it you find an element, change its content or react to a click, and you see the effect at once. The MDN DOM documentation has the full reference.
<!-- index.html -->
<form id="todo-form">
<input id="todo-input" placeholder="New task">
<button type="submit">Add</button>
</form>
<ul id="todo-list"></ul>// script.js
const form = document.querySelector("#todo-form");
const input = document.querySelector("#todo-input");
const list = document.querySelector("#todo-list");
form.addEventListener("submit", (event) => {
event.preventDefault();
const text = input.value.trim();
if (!text) return;
const item = document.createElement("li");
item.textContent = text;
list.append(item);
input.value = "";
input.focus();
});The pattern never changes: find an element with querySelector, attach an event handler with addEventListener and update the page inside it. event.preventDefault() stops the form from reloading the page, and trim() rejects entries made only of spaces.
Note textContent. It inserts plain text, so HTML tags typed into the field show up as text and never run. The tempting innerHTML parses content as HTML and, with user input, opens the door to XSS attacks. Practise events in the lesson on event listeners.
Fetching data with fetch and async/await
Server data such as a weather forecast or a product list arrives with a delay, and the page can't freeze meanwhile, so these operations are asynchronous. fetch returns a promise, a result available later, and await lets you wait for it in a readable way.
async function loadTodo(id) {
try {
const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${id}`);
if (!response.ok) {
throw new Error(`HTTP error: ${response.status}`);
}
const todo = await response.json();
console.log(todo.title);
} catch (error) {
console.error("Could not load the data:", error.message);
}
}
loadTodo(1);await works inside async functions and at the top level of modules. The key trap: fetch doesn't throw on a 404 or a 500, only on a network failure, so you must check response.ok yourself. The MDN guide to using fetch has the details.
The example URL points to JSONPlaceholder, a free test API with fake data. Once one request works, try sending several at once with Promise.all. The matching lessons are the Fetch API and async/await syntax.
Modules, or keeping files in order
As code grows, one file stops being enough. You then split it into modules, files that each export what they want to share.
// math.js
export function sum(numbers) {
return numbers.reduce((total, n) => total + n, 0);
}// main.js
import { sum } from "./math.js";
console.log(sum([4, 8, 15])); // 27In the browser you load the main file with <script type="module" src="main.js"></script>. Modules won't load from a file opened straight from disk (a file:// address), as the MDN guide to modules notes, so you need a server: Live Server or a Vite project will do. In Node.js, the simplest option is adding "type": "module" to package.json.
Debugging and reading errors
Errors are part of every programmer's day. Experienced people simply read the message instead of fearing it, and red text in the console tells you what the error is, what it concerns and on which line it happened.
const user = { name: "Ada" };
console.log(user.address?.city); // undefined
console.log(user.address.city);
// TypeError: Cannot read properties of undefined (reading 'city')The Chrome and Node.js message means you're reading city from something that is undefined, so the culprit is user.address, not city. The ?. operator (optional chaining) on the first line returns undefined in that case instead of stopping the program.
console.table([
{ task: "shopping", done: true },
{ task: "workout", done: false },
]);
function calculateAverage(numbers) {
debugger;
return numbers.reduce((sum, n) => sum + n, 0) / numbers.length;
}
calculateAverage([4, 8, 15]);console.table shows an array of objects as a readable table, and debugger pauses the code when the developer tools are open. The Sources panel then shows variable values and lets you step through line by line. Clicking a line number sets the same pause, a breakpoint. The Chrome DevTools documentation explains it, and the lesson on breakpoints and step-by-step execution lets you practise. When stuck, paste the exact message into a search engine, as someone has almost certainly hit it before.
First projects
Knowledge without projects doesn't stick. Start small and let each project add one new thing:
- A click counter. A button, a number on screen and a reset, covering variables, functions and events.
- A to-do list. Adding, marking and deleting tasks, then saving to
localStorageso the list survives a reload. - A quiz. Questions in an array of objects, points and a final score, covering arrays, conditions and DOM updates.
- A weather app. Data from a public API such as Open-Meteo, which needs no key, covering fetch, async/await and error handling.
Push every project to GitHub, even the small ones. In a few months you'll see how your code has changed, and the repositories become the start of a portfolio. We cover the road from learning to a first job in how to become a developer.
How to practise effectively
Short daily practice works best: 20 to 30 minutes a day builds the habit better than a weekly marathon. Test every new topic in code right away, change the examples, break them on purpose and watch what happens. Type code by hand instead of pasting it, since that makes you notice details. If you can explain to a friend or a rubber duck what your function does, you understand it. A weekly plan and ways to stay motivated are in how to learn to code.
Common beginner mistakes
- Confusing
=with===. A single=assigns and===compares. The conditionif (score = 10)always passes and overwrites the score as well. - Only watching courses. After every lesson, write something yourself, even ten lines.
- Skipping the basics. Without solid JavaScript, React looks like magic and every error like a riddle.
- Forgetting
await. You get aPromise { <pending> }object instead of data. - Copying AI code you don't understand. At the basics stage, ask the assistant for explanations rather than finished solutions.
What next: TypeScript, React and Node.js
The next step makes sense once you can write functions, process arrays of objects and fetch data without a cheat sheet. Then you have three natural directions.
React is a library for building interfaces from components, working with props, state and hooks. It's the natural pick for frontend work. In CodeWorlds it's taught in the Space Mission world, which assumes you know the JavaScript basics.
TypeScript adds types checked before the code runs and catches many mistakes before they reach the browser. You can learn basic annotations right after JavaScript, though if interfaces are the goal, React usually comes first and TypeScript follows once components and state stop surprising you. Just don't start with TypeScript before you know the language itself.
The third direction is backend work on Node.js: servers, APIs and databases, and later frameworks that combine frontend and backend, such as Next.js.
Practising with CodeWorlds
In CodeWorlds, JavaScript from scratch is taught in the Jurassic Park world, a beginner course with more than 600 exercises and roughly 60 to 90 hours of learning. It covers variables and functions, arrays, objects, the DOM and async code, then classes, modules and TypeScript basics. Its lessons have a built-in editor with a live preview, and every lesson linked in this article comes from this course.
You can read this course's lessons for free on the site, while its exercises in the app need the premium plan. The free plan covers the HTML and CSS course in the app and gives you 10 units of fuel a day, and fuel is simply a daily exercise limit, which fits the short daily sessions described above. Experience points, levels and learning streaks help keep you going.
FAQ
Is JavaScript hard for beginners?
No harder than other languages, and easier to start, since a browser and an editor are all you need. Type conversion and async code cause the most trouble, but you'll master both by running every example rather than only reading about it.
How long does it take to learn JavaScript?
The basics, meaning variables, functions, arrays, objects and the DOM, usually take one to three months of short daily sessions. Building React apps comfortably most often takes six months to a year.
JavaScript or Python to start with?
Both are good choices. JavaScript wins if you want websites and web apps, because you see results in the browser right away. Python is more common among people learning to code: in the 2025 Stack Overflow survey 72% of them used it, against 63% for JavaScript. Choose by what you want to build.
Can I learn JavaScript for free?
Yes. The MDN JavaScript Guide and the javascript.info tutorial are free. On CodeWorlds you can read the JavaScript course lessons in English and Polish for free, since they're public, but the course's exercises in the app need the premium plan. The free plan covers the HTML and CSS course in the app with 10 units of fuel a day.
What project should I build first?
Something small and useful: a click counter, a to-do list or a simple quiz. They practise variables, functions and the DOM together, and you can finish them in an evening or two. A finished small project teaches more than an abandoned ambitious one.