Overview

JavaScript is a dynamic, cross-platform, multi-paradigm programming language that has become one of the foundations of Web development. Alongside HTML for structure and CSS for presentation, it can make a page interactive, respond to user actions, dynamically modify the interface, communicate with a server or build complete applications running inside the browser.

The language is no longer limited to front-end development. Environments such as Node.js, Deno or Bun can run JavaScript outside the browser to build servers, APIs, command-line tools, automation scripts and complete applications. JavaScript is also used in desktop, mobile, embedded and certain creative development environments.

The standardized language is officially called ECMAScript. The standard is developed by the TC39 committee of Ecma International and published in the ECMA-262 specification. JavaScript generally refers to the language as used by developers, while ECMAScript describes its standardized specification.

The currently published annual version is ECMAScript 2026 — ECMA-262, 17th edition, approved in June 2026. The project nevertheless continues to evolve between annual editions: proposals that reach the final stage are integrated into the living draft of the next specification.

It is also important to distinguish browser JavaScript from Web APIs. Objects such as Array, Map, Promise or Math belong to the ECMAScript language. The DOM, fetch(), localStorage, Canvas, Web Audio, WebGL or WebGPU are instead provided by the Web environment and are not part of the core language itself.

This distinction explains why the same JavaScript can run in different environments while not having access to exactly the same functionality.

Features

A dynamic and multi-paradigm language

JavaScript is a dynamically typed language.

A variable is not permanently associated with a type when it is declared: it can refer to different categories of values during program execution.

The language provides several primitive types, including:

  • string;
  • number;
  • bigint;
  • boolean;
  • undefined;
  • symbol;
  • null.

Objects then form a fundamental category used to represent data structures, arrays, functions, dates, collections or custom objects.

JavaScript can be used through several programming styles. It supports imperative, functional and object-oriented programming, with functions treated as first-class values.

This flexibility makes it possible to write both small scripts and large applications, but in return requires conventions and disciplined architecture as the codebase grows.

Variables, functions and closures

Modern variables are mainly declared with let and const.

const prevents reassignment of the variable itself, while let allows reassignment. The older var keyword remains valid but follows different scoping rules and is generally less common in modern JavaScript.

Functions occupy a central place in the language.

They can be declared conventionally, assigned to a variable, passed as arguments, returned by other functions or written as arrow functions.

JavaScript also supports closures: a function can retain access to its lexical environment even after the function that created it has finished executing.

This property forms the basis of many patterns used to encapsulate state, create callbacks, build configured functions or organize certain application components.

Objects, prototypes and classes

JavaScript’s object system is historically based on prototypes.

An object can inherit properties and methods from another object through a prototype chain.

Since ECMAScript 2015, the class, extends, constructor and super keywords provide a more familiar syntax for structuring object-oriented programming.

JavaScript classes nevertheless remain built on top of the language’s prototype system.

They can contain public methods, fields, private properties using #, getters, setters and static methods.

This system makes it possible to create conventional object hierarchies while retaining JavaScript’s flexibility.

Arrays, Map, Set and collections

JavaScript provides several built-in structures for organizing data.

Array represents an ordered collection and includes many methods such as map(), filter(), reduce(), find(), some() or every().

Map associates keys with values while accepting almost any type of key.

Set represents a collection of unique values.

WeakMap and WeakSet provide variants whose references do not prevent certain objects from being released by the garbage collector.

These structures cover a large portion of common needs without requiring an external library.

Promises, async and await

A large part of modern JavaScript relies on asynchronous programming.

Promise objects represent the future result of an operation that may succeed or fail.

They are especially used for network requests, file access in certain runtimes, databases or other operations whose duration is not immediate.

The async and await keywords provide a more readable syntax on top of promises.

A function marked async returns a promise. Inside it, await can suspend its execution until another promise settles without blocking the entire program.

JavaScript also provides tools such as:

  • Promise.all();
  • Promise.allSettled();
  • Promise.race();
  • Promise.any().

They make it possible to coordinate several asynchronous operations according to different needs.

It remains important to understand that await does not turn JavaScript into a synchronous execution language: it only suspends the relevant asynchronous task while the environment can continue processing other operations.

ES modules with import and export

JavaScript now includes a standardized module system.

A file can expose functions, classes or values with export, then retrieve them elsewhere with import.

Modules make it possible to split an application into independent components rather than placing all code in a single script.

They support:

  • named exports;
  • default export;
  • re-exporting;
  • dynamic imports with import();
  • top-level await in certain modules;
  • import maps in compatible Web environments.

ES modules are now supported directly by modern browsers as well as the main JavaScript runtimes.

Historical ecosystems also use other systems, notably CommonJS in many older Node.js projects.

Iterators, generators and modern loops

JavaScript includes an iteration protocol used by several language structures.

The for...of loop can iterate over values from an iterable object such as an array, string, Map or Set.

Generators, declared with function*, can suspend and resume execution using yield.

They make it possible to produce values progressively rather than immediately computing an entire collection.

Custom iterators can also be built by implementing the relevant protocols.

These mechanisms are particularly useful for processing streams, generating sequences or building reusable traversal abstractions.

Typed Arrays and binary data manipulation

JavaScript is not limited to high-level structures.

Typed Arrays can manipulate raw binary data in memory areas represented notably by ArrayBuffer or SharedArrayBuffer.

Different views are available:

  • Uint8Array;
  • Int16Array;
  • Uint32Array;
  • Float32Array;
  • Float64Array;
  • and several other types.

These structures are important when JavaScript interacts with audio, video, network data, binary files, WebGL, WebGPU or WebAssembly.

They provide more control over memory representation than standard JavaScript arrays.

Error handling

JavaScript primarily uses throw, try, catch and finally for error handling.

A function can explicitly throw an error and higher-level calls can decide where to handle it.

The language provides several built-in classes such as:

  • Error;
  • TypeError;
  • RangeError;
  • ReferenceError;
  • SyntaxError.

Custom error classes can also be created to represent application-specific problems more precisely.

With asynchronous code, errors can reject a Promise and be handled with .catch() or with try...catch around an await.

JavaScript in the browser

Inside a browser, JavaScript is executed by a JavaScript engine.

The main ones include:

  • V8, used notably by Chrome and Chromium;
  • SpiderMonkey, used by Firefox;
  • JavaScriptCore, used by Safari.

These engines implement the ECMAScript standard, after which the browser environment adds its own Web APIs.

JavaScript can then manipulate the DOM, respond to events, send network requests, manage local storage, draw with Canvas, generate audio, display 3D with WebGL/WebGPU or communicate with various devices when the relevant APIs are available.

A function such as document.querySelector() therefore belongs to the DOM, not the ECMAScript language itself.

JavaScript on the server and outside the browser

JavaScript can also run without a browser through dedicated runtimes.

Node.js widely popularized JavaScript on the server. It can be used to build APIs, dynamic websites, real-time servers, CLI tools, build scripts and automation.

Other runtimes such as Deno and Bun provide their own approaches while using the same ECMAScript language.

These environments add capabilities that do not exist in core JavaScript, including filesystem access, processes, low-level networking or system tools.

A JavaScript script is therefore not automatically portable across every environment: the language may be the same, but the available APIs can change.

npm and an enormous software ecosystem

The JavaScript ecosystem relies heavily on package managers, especially npm.

A project can add specialized libraries for user interfaces, servers, testing, databases, validation, graphics, artificial intelligence, file processing or almost any other domain.

Many important frameworks and libraries rely on JavaScript or its ecosystem:

  • React;
  • Vue;
  • Angular;
  • Svelte;
  • Next.js;
  • Express;
  • Three.js;
  • Electron;
  • React Native.

This richness is one of JavaScript’s main strengths, but also a potential source of complexity.

A modern project can quickly accumulate hundreds of transitive dependencies, making version management, security audits and maintenance particularly important.

TypeScript as a typed extension of the ecosystem

TypeScript is not JavaScript, but it is closely connected to its ecosystem.

It notably adds a static type system on top of JavaScript and then transforms the code into executable JavaScript.

It can make large codebases easier to maintain through improved error detection, autocompletion and implicit documentation of data structures.

A JavaScript developer is not required to use TypeScript, but it has become very common in large Web projects, frameworks and libraries.

Understanding JavaScript itself remains fundamental, however: TypeScript ultimately compiles to JavaScript and retains much of its runtime behavior.

Use cases

Adding interactivity to a Web page

JavaScript can listen for a click, validate a form, open a menu, filter results or dynamically modify part of the document.

The code then interacts mainly with the DOM and browser-provided events.

For a simple website, a few JavaScript modules may be enough without requiring a complete framework.

The language therefore remains just as useful for a small interface enhancement as for a complex application.

Building a complete front-end application

A Web application can use JavaScript to manage navigation, state, forms, remote data and interface updates.

Frameworks such as React, Vue, Angular or Svelte can structure the project, but the executed code still relies heavily on the fundamental mechanisms of the language.

Promises, modules, objects, arrays, functions and events therefore remain essential even when a framework hides part of their direct use.

Developing an API or server with Node.js

JavaScript can be used on the server to receive HTTP requests, query a database and return responses to a client application.

This approach lets a team share the same language between front-end and back-end.

Developers can also reuse certain data structures, validation tools or types across different parts of the project.

The runtime still provides the server capabilities: ECMAScript alone does not allow a file to be opened or a network port to be listened to.

Automating tasks and creating CLI tools

JavaScript can be used to rename files, convert data, launch builds, analyze content or automate a development workflow.

With Node.js, Deno or Bun, a script can access the filesystem and many system tools.

This use is especially common in front-end build pipelines where JavaScript drives bundlers, tests, linters, generators and deployment tools.

Creating graphical, 3D or interactive experiences

Through Web APIs and specialized libraries, JavaScript can control Canvas, WebGL, WebGPU, Web Audio or WebXR.

Three.js, for example, simplifies the creation of 3D scenes in the browser, while other libraries are used for data visualization, animation or games.

JavaScript then becomes the language organizing the experience, while graphics APIs provide access to the GPU and other browser capabilities.

Conclusion

JavaScript has evolved from a language intended to add a few interactions to Web pages into a general-purpose language present across a large part of the modern software stack.

Its role remains essential in the browser: it is the native language used to program the behavior of a Web page alongside HTML and CSS.

Its adoption no longer ends with front-end development, however. Node.js and later runtimes extended it to back-end development, development tooling, system scripts, desktop applications and many other areas.

The language itself has also become considerably more structured. Modules, classes, collections, promises, async/await, typed arrays, iterators and many other features now make it possible to build applications far more ambitious than early Web scripts.

This power still comes with a few particularities. Dynamic typing, implicit conversions, the prototype system and some historical behaviors can be surprising. The huge npm ecosystem provides enormous possibilities but can also introduce dependencies, frequent updates and security risks.

It is also essential to distinguish JavaScript, ECMAScript and environment APIs. Promise belongs to the language; document, fetch or WebGL are provided by the environment where the language runs.

For Web development, understanding this distinction and the fundamentals of the language is often more durable than knowing a particular framework.

With ECMAScript 2026 as the current annual edition of the standard, JavaScript continues to evolve without breaking the huge amount of code already deployed. This compatibility, combined with the language’s native presence in browsers, explains why it remains one of the central technologies of software development today.

Points to consider

  • JavaScript and ECMAScript refer closely to the same language, but ECMAScript is the official name of the standard defined in ECMA-262.

  • The current annual version of the standard is ECMAScript 2026 — ECMA-262, 17th edition, published in June 2026.

  • The ECMAScript draft evolves continuously between annual editions as proposals reach the final stage of the TC39 process.

  • JavaScript does not automatically include the DOM, fetch(), WebGL or other Web APIs. These features are provided by the browser or another execution environment.

  • The language uses dynamic typing, which provides flexibility but can also cause certain errors to appear only at runtime.

  • JavaScript relies on prototype-based inheritance, even when the class syntax is used.

  • ES modules with import and export are now the language’s standard module system, although CommonJS remains present in the Node.js ecosystem.

  • async and await are built on promises and do not block the entire JavaScript engine while waiting.

  • Compatibility depends on each feature and each JavaScript engine. A new standard feature may not be immediately available in every browser or runtime.

  • Node.js, Deno and Bun use JavaScript but add their own APIs. A program may therefore require adaptations when moving between runtimes.

  • The npm ecosystem is extremely large, but dependencies need to be monitored: versions, maintenance, vulnerabilities and transitive dependencies can become important in a large project.

  • TypeScript complements JavaScript but does not replace it. A solid understanding of JavaScript’s actual runtime behavior remains necessary to understand the generated code.

  • JavaScript is free to use and charges no royalties, but frameworks, cloud services, development tools and platforms used around the language may have their own terms.

  • The language runs across practically all major modern platforms through browsers and runtimes, but the available APIs always depend on the execution environment.