
JavaScript
First appeared 1995 · Brendan Eich
The only language that runs natively in every browser — and, since Node.js, on the server too.
Overview
JavaScript is a high-level, versatile programming language primarily used for web development. Created by Brendan Eich in 1995 while working at Netscape Communications, JavaScript allows developers to implement complex features on web pages, including dynamic content updates, interactive forms, animations, and client-server communication. Over the years, it has evolved into a full-fledged, multi-paradigm language capable of supporting object-oriented, functional, and event-driven programming. JavaScript is executed in web browsers but can also run on servers through environments like Node.js, making it essential for full-stack development. Its ecosystem includes countless libraries and frameworks such as React, Angular, and Vue.js for front-end development, and Express, NestJS, and Koa for back-end applications. JavaScript’s syntax is influenced by C and Java, while its dynamic typing and prototype-based object model give it great flexibility. Its asynchronous capabilities, event loops, and Promise-based handling of operations make it highly suitable for modern web applications. The language has become foundational to web technologies alongside HTML and CSS, and its popularity continues to grow due to its universal presence on the web, ease of use, and extensive developer community.
Key facts
The reference details, without the paragraph.
- First appeared
- 1995
- Designed by
- Brendan Eich at Netscape
- Typing
- Dynamic and weak, with implicit coercion between types
- Execution
- Just-in-time compiled by engines such as V8, SpiderMonkey and JavaScriptCore
- Memory model
- Automatic — generational, mark-and-sweep garbage collection
- Package manager
- npm, pnpm, yarn or bun, backed by the npm registry
- File extensions
- .js, .mjs, .cjs
- Standard
- ECMAScript, with a new edition ratified each June
- Concurrency
- Single-threaded event loop, plus Web Workers for true parallelism
- Licence
- Open specification (ECMA-262); engines are individually open source
History
How the language got here — the decisions that still shape how you write it.
JavaScript was created by Brendan Eich at Netscape Communications in 1995, initially under the name Mocha, later renamed to LiveScript, and finally JavaScript to align with the marketing of Java, which was gaining popularity at the time. Eich developed the first version of JavaScript in just 10 days to provide web browsers with a lightweight, interpreted language that could enhance web pages with interactive functionality. JavaScript quickly became a standard for client-side scripting, enabling developers to manipulate the Document Object Model (DOM), handle events, and perform asynchronous operations via AJAX. Over the years, JavaScript evolved significantly, with the introduction of ECMAScript standards to formalize its syntax and features. ECMAScript editions such as ES5, ES6 (ES2015), and subsequent versions added classes, modules, arrow functions, template literals, async/await, and many other modern programming constructs. The rise of Node.js in 2009 allowed JavaScript to move beyond browsers and run on servers, making it a full-stack language and expanding its capabilities for enterprise and cloud applications. Modern JavaScript frameworks and libraries, including React, Angular, Vue.js, and Svelte, have revolutionized front-end development by enabling component-based architectures, reactive programming, and modular design patterns. JavaScript’s asynchronous programming model, event loop, and promise-based operations facilitate handling of I/O-intensive and real-time applications efficiently. The language continues to evolve with annual ECMAScript updates, ensuring it remains relevant, efficient, and aligned with modern software engineering practices. Its global community organizes conferences, maintains extensive documentation, and provides thousands of open-source tools, which support learning and development. JavaScript’s universality, flexibility, and active ecosystem make it indispensable for web developers, powering nearly every interactive feature on the web today.
- 1995
Ten days in May
Brendan Eich writes the first prototype at Netscape in about ten days. It is named LiveScript, then renamed JavaScript for marketing reasons — it has no technical relationship to Java, a confusion that has lasted thirty years.
- 1997
ECMAScript standardised
The language is handed to Ecma International so competing browsers can implement the same thing. The awkward name 'ECMAScript' exists because 'JavaScript' was a Sun trademark.
- 2005
AJAX changes what a web page is
Gmail and Google Maps show that a page can fetch data and update itself without reloading. JavaScript stops being a language for form validation and starts being a language for applications.
- 2008
V8 and the JIT arms race
Google ships Chrome with the V8 engine, which compiles JavaScript to machine code. Performance improves by an order of magnitude and makes everything that follows plausible.
- 2009
Node.js puts JavaScript on the server
Ryan Dahl wraps V8 in an event loop and a standard library. One language now spans both ends of a web application, and npm becomes the largest package registry in existence.
- 2015
ES2015 (ES6) modernises the language
`let`/`const`, arrow functions, classes, template literals, destructuring, promises and modules land together. This is the line between 'old JavaScript' and the language people write today.
- 2017
async/await
Asynchronous code finally reads top to bottom. Callback pyramids become a historical curiosity.
- 2020
Optional chaining and nullish coalescing
`?.` and `??` remove a large share of defensive boilerplate, and the annual release cadence settles into steady, incremental improvement.
- 2024
The runtime field widens
Deno and Bun push Node.js on startup speed, built-in TypeScript support and batteries-included tooling, while Node adopts a native test runner and a stable ESM story.
What it is good at
The reasons teams pick it, stated concretely.
It runs everywhere, with no install step
Every browser on every device already executes JavaScript. No other language can be deployed to billions of machines by uploading a text file. That single fact explains most of its ecosystem's size.
One language across the whole stack
Browser, server, build tooling, mobile via React Native, desktop via Electron, and edge functions all speak the same language. Shared validation code and shared types across a front end and back end remove an entire class of integration bug.
The largest package registry in existence
npm hosts over three million packages. Whatever narrow problem you have, someone has published a solution — which is both the greatest strength and the source of the ecosystem's worst habits.
Genuinely fast for a dynamic language
Modern JIT engines with inline caching and hidden classes make idiomatic JavaScript competitive with other managed runtimes. Numeric-heavy work can go further with typed arrays and WebAssembly.
First-class functions and closures
Functions are values you can pass, return and capture state in. Callbacks, promises, middleware, hooks and functional array methods all fall out of that one design decision.
Trade-offs
Every language costs you something. Knowing what, before you commit, is the whole point.
Type coercion is genuinely surprising
`[] + {}`, `'5' - 2`, and `NaN !== NaN` are the famous examples. The rules are consistent but rarely what you expect. Use `===`, avoid implicit conversion, and let a linter catch the rest.
Dependency sprawl and supply-chain risk
A small application can pull in a thousand transitive packages from hundreds of maintainers. Audit what you add, prefer the standard library or a few well-maintained dependencies, and pin your lockfile.
Two module systems, still
CommonJS (`require`) and ES modules (`import`) coexist uneasily. Most friction in Node tooling traces back to this split, though the situation improves with each release.
Framework churn
The front-end tooling landscape turns over faster than any other ecosystem. Much of this is noise — the core language is stable and backwards compatible; it is the surrounding conventions that keep moving.
No static types out of the box
At any real scale most teams reach for TypeScript. That is a sign of the gap, not a criticism — but it does mean 'plain JavaScript at scale' requires unusual discipline.
Code examples
Not syntax tours — the idioms that make code read like the language rather than a translation of another one.
const orders = [
{ id: 1, total: 30, status: 'paid' },
{ id: 2, total: 55, status: 'pending' },
{ id: 3, total: 12, status: 'paid' },
];
const paidRevenue = orders
.filter((order) => order.status === 'paid')
.reduce((sum, order) => sum + order.total, 0);
const byStatus = Object.groupBy(orders, (order) => order.status);
console.log(paidRevenue); // 42
console.log(byStatus.paid.length); // 2const config = { host: 'localhost', port: 8080, tls: { enabled: true } };
// Pull out what you need, with defaults and renaming.
const { host, port = 3000, tls: { enabled: tlsOn } } = config;
// Optional chaining and nullish coalescing survive missing data.
const timeout = config.network?.timeout ?? 5000;
// Spread copies shallowly and merges.
const production = { ...config, host: 'api.example.com' };
console.log(host, port, tlsOn, timeout); // localhost 8080 true 5000async function loadUser(id) {
const response = await fetch(`/api/users/${id}`);
// fetch only rejects on network failure — a 404 is a resolved promise.
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
return response.json();
}
// Run independent requests concurrently, not one after another.
const [user, settings] = await Promise.all([
loadUser(1),
fetch('/api/settings').then((r) => r.json()),
]);function createRateLimiter(maxCalls, windowMs) {
let calls = [];
return function allow() {
const now = Date.now();
calls = calls.filter((time) => now - time < windowMs);
if (calls.length >= maxCalls) return false;
calls.push(now);
return true;
};
}
const limiter = createRateLimiter(2, 1000);
console.log(limiter(), limiter(), limiter()); // true true falseCommon pitfalls
The mistakes that cost everyone an afternoon at least once.
`==` versus `===`
Loose equality applies coercion rules almost nobody remembers correctly — `'' == 0` is true, `null == undefined` is true, `null == 0` is false. Use `===` unless you specifically want the `null`/`undefined` check.
`this` depends on how a function is called
Passing a method as a callback loses its receiver. Arrow functions capture `this` from the enclosing scope, which is why they are the right choice for callbacks and the wrong choice for object methods.
Forgetting `await` inside `map`
`array.map(async x => ...)` returns an array of promises, not values. Wrap it: `await Promise.all(array.map(async x => ...))`.
Mutating shared objects
Objects and arrays are passed by reference, and spread copies only one level deep. A nested object in a 'copy' is still the original — a frequent source of state bugs in UI code.
Floating point arithmetic
`0.1 + 0.2 !== 0.3`. This is IEEE-754, not a JavaScript quirk, but it bites hardest here because there is no built-in decimal type. Use integer cents for money, or a decimal library.
Blocking the event loop
A long synchronous loop freezes the entire page or stalls every request on a Node server. Break up heavy work, move it to a Web Worker, or hand it to a background job.
In production
Where it is running at scale, and what it is doing there.
Facebook (Meta)
Frontend and backend development (React framework).
Google
Frontend web applications, Angular framework, server-side with Node.js.
Netflix
Frontend user interfaces, streaming apps.
PayPal
Full-stack applications with Node.js and frontend web apps.
Learning path
A realistic order to learn things in, with something to build at each step.
- 1
Days 1–7
The language itself
Values and types, `const` over `let` (never `var`), functions and arrow functions, arrays and objects, and strict equality. Run everything in the browser console — the feedback loop is instant.
Build this: Build a page that takes a list of numbers and displays the total, average and largest.
- 2
Weeks 2–3
The browser
The DOM, event listeners, `fetch`, and where JavaScript sits relative to HTML and CSS. Learn the event loop conceptually now — it explains why your code runs in an order you did not expect.
Build this: Build a small app that fetches from a public API and renders the results, including loading and error states.
- 3
Week 4
Asynchrony properly
Promises, `async`/`await`, `Promise.all` and `Promise.allSettled`, and error handling across await boundaries. This is where most beginners' mental model breaks; slow down here.
Build this: Fetch from three endpoints concurrently and render whichever succeed, handling the failures gracefully.
- 4
Months 2–3
Tooling and one framework
npm and lockfiles, ES modules, a bundler such as Vite, and one component framework — React, Vue or Svelte. Learn why the framework exists before learning its API.
Build this: Rebuild your API app as a component-based project with a build step and deploy it.
- 5
Ongoing
Depth and safety
TypeScript, testing with Vitest or Playwright, Node.js for the server side, and the runtime internals — prototypes, `this` binding, the microtask queue — that explain the odd behaviour you will eventually hit.
Build this: Convert a project to TypeScript and add tests that would have caught a bug you actually shipped.
Ecosystem and tooling
The tools you will end up installing whichever project you join.
| Tool | Category | What it does |
|---|---|---|
| Node.js | Runtime | The mainstream server-side runtime, with the largest ecosystem and deployment support |
| Deno / Bun | Runtime | Modern alternative runtimes with built-in TypeScript, test runners and faster startup |
| npm / pnpm | Packaging | Package installation and lockfiles; pnpm saves significant disk space via a content-addressed store |
| Vite | Build | The default build tool for new front-end projects — instant dev server, optimised production bundle |
| ESLint | Code quality | Catches the language's genuine footguns before they reach review |
| Prettier | Code quality | Removes formatting from the list of things a team argues about |
| Vitest / Playwright | Testing | Fast unit testing and reliable cross-browser end-to-end testing |
| TypeScript | Language tooling | Optional static types layered on top; the default choice for teams and large codebases |
JavaScript libraries
59 catalogued, each with installation, worked examples and best practices.
MUI (Material-UI)
A comprehensive React component library implementing Material Design.
UI & GraphicsAnt Design
Ant Design is a React UI library with a set of high-quality components and design guidelines for building rich, enterprise-level web applications. It emphasizes consistency, usability, and customization.
UI & GraphicsChakra UI
Chakra UI is a simple, modular, and accessible component library for React applications. It provides composable components with built-in theming, responsive styles, and accessibility support by default.
UI & GraphicsHeadless UI
Headless UI is a set of completely unstyled, accessible UI components for React and Vue. It provides the functionality and accessibility features, leaving styling fully up to you.
UI & GraphicsRadix UI
Unstyled, accessible component primitives — behaviour without opinions about appearance.
UI & Graphicsshadcn/ui
Not a dependency — components you copy into your project and own outright.
UI & Graphics
Frequently asked
Should I learn JavaScript or go straight to TypeScript?
Learn JavaScript's fundamentals first — TypeScript is JavaScript plus a type layer, and type errors are confusing when you are still unsure what the runtime does. A few weeks in, switch. Almost every professional codebase you will join is TypeScript.
Is JavaScript really single-threaded?
Your code runs on one thread, but the runtime does not. Network requests, timers and file I/O are handled outside that thread and queue their callbacks back onto it. For genuine CPU parallelism, use Web Workers in the browser or `worker_threads` in Node.
React, Vue, Svelte or none?
For a page with a handful of interactive pieces, plain JavaScript is fine and much simpler. For an application with meaningful shared state, pick one: React has the largest job market and ecosystem, Vue is the gentlest to learn, Svelte produces the least code. The underlying concepts transfer between all three.
Node, Deno or Bun?
Node.js for anything with production or hiring constraints — the ecosystem and deployment support are unmatched. Bun for speed-sensitive tooling and scripts. Deno when you want TypeScript, a test runner and a permissions model with no configuration at all.
Is jQuery still relevant?
For new code, no. `querySelector`, `fetch`, `classList` and template literals cover what jQuery was invented to smooth over. It remains on a large share of existing sites, so you will still read it — but there is no reason to reach for it today.
How do I keep npm dependencies under control?
Commit your lockfile, run `npm audit` in CI, prefer packages with recent commits and few dependencies of their own, and ask whether ten lines of your own code would do instead. Every dependency is code you are responsible for but did not write.




