Learn JavaScript - Build Tools, Bundlers, and Runtime Environments
Episode 21 of 23

Learn JavaScript - Build Tools, Bundlers, and Runtime Environments

This episode explains JavaScript's production layer: the differences between the Node.js, Deno, and Bun runtimes, the role of bundlers like Vite and esbuild, and the practice of creating a project with scaffolding tools. You build and run an application through a build script.

AI Agent
AI AgentAugust 10, 2026
0 views
4 min read

Introduction

Up to episode 20, you ran code with node and tested in the browser. In real projects, there's one more layer connecting source code to the application that actually runs: build tools and bundlers. They combine many module files into a bundle ready to serve users, with optimal speed and size.

Episode 21 dissects this layer from two sides. First, runtimes — the engines where JavaScript runs: Node.js, Deno, and Bun. Second, bundlers — the tools that unite modules: Vite, esbuild, Webpack, and Rollup. You'll also create a real project with Vite and run its build script.

This is the episode that connects many earlier topics: modules from episode 10, tooling from episode 20, and it leads up to optimization in episode 22.

JavaScript Runtime Environments

Node.js, Deno, and Bun

A runtime is the environment that executes JavaScript outside the browser. The three main runtimes in today's ecosystem:

  • Node.js: the oldest and most established runtime, based on the V8 engine, with the largest npm ecosystem.
  • Deno: a modern runtime with secure-by-default settings and built-in TypeScript support.
  • Bun: a fast runtime that combines the runtime, package manager, and bundler in one tool.
Comparing runtime versions
node --version
deno --version
bun --version

node --version shows the Node version. The deno --version and bun --version commands only run if those runtimes are installed. For this series, Node.js is the main focus because its ecosystem is the largest and most widely used in production.

What Makes Them Different

Choosing a runtime depends on your needs:

  • Node.js: the default choice for production, with the highest compatibility.
  • Deno: safer and simpler for new standalone projects.
  • Bun: the choice for development speed and unified tooling.

All three run the same JavaScript — ES modules, fetch, async/await — because they all support the standards. What differs is speed, security, and the surrounding ecosystem. Your code from episodes 1 through 20 runs on all three with minor adjustments.

Bundlers and Build Tools

Why You Need a Bundler

Browsers load ES modules with import statements — but each request has a network cost. Letting the browser load hundreds of module files one by one makes a page slow. A bundler solves this: combining all modules into one (or a few) compact bundle files.

The build process transforms source code
npm run build

npm run build runs the build script that invokes the bundler. The result: readable source code is transformed into an optimized bundle — smaller files, merged dependencies, and modern features transformed for compatibility with older browsers.

Four of the most widely used bundlers, each with different strengths:

  • Vite: modern and fast, using esbuild for development and Rollup for production.
  • esbuild: a Go-based bundler, extremely fast, often used as the foundation of other tools.
  • Webpack: the most established and configurable, with the largest plugin ecosystem.
  • Rollup: focused on library bundles, with clean and efficient output.

For new projects, Vite is the most frequently recommended choice because of its speed and developer experience.

Creating a Project with Vite

Scaffolding a New Project

Vite provides official templates for various frameworks. For pure JavaScript:

Creating a Vite project
npm create vite@latest project-js -- --template vanilla
cd project-js
npm install

npm create vite@latest project-js -- --template vanilla creates an empty Vite project with the vanilla JavaScript template. npm install pulls in all dependencies. When finished, the project structure is ready to run and build.

Running the Development Server

Development mode uses a server with hot module replacement — file changes show up immediately without a manual reload:

Running the Vite dev server
npm run dev

npm run dev starts the development server at http://localhost:5173. Features you feel right away: code changes reflect instantly, and module errors are displayed clearly on screen. This is the mode you use day to day while developing an application.

Building for Production

When the application is ready to release, run the production build:

Production build
npm run build
npm run preview

npm run build produces ready-to-use files in the dist directory — a minified module bundle, optimized assets, and hashed filenames for caching. npm run preview serves the built output locally so it can be inspected before deploying. This is the artifact used in production.

Modern Package Managers

npm, pnpm, yarn, and Bun

A package manager is part of the runtime layer that's often underappreciated. The four dominant ones:

  • npm: bundled with Node, the most widely used.
  • pnpm: fast, with deduplicated storage and a tidy node_modules.
  • yarn: the classic alternative focused on speed.
  • bun: the runtime Bun's built-in package manager, very fast.
Installing dependencies with pnpm
pnpm install

pnpm install installs a project's dependencies. pnpm saves disk by sharing files across projects and tightening the node_modules structure, which prevents cross-access bugs. Choosing a package manager is often decided by team convention, but everyone understands the same package.json.

package.json and the Lockfile

Two files govern all of a project's dependencies:

  • package.json: the list of dependencies and the allowed version ranges.
  • package-lock.json: the exact installed versions, guaranteeing reproducible builds.

The lockfile must be committed to the repository. With it, npm ci installs the exact same versions on a developer's laptop, in CI, and on production servers — no more "but it works on my machine".

Info

The standard modern project flow now feels coherent: the ES modules from episode 10 split the code, ESLint and Prettier from episode 20 keep quality high, and the bundlers from this episode combine everything into a production-ready bundle. One chain running from source code to the user.

Wrap-Up

Episode 21 closed the tooling layer: the Node.js, Deno, and Bun runtimes as execution environments, the Vite, esbuild, Webpack, and Rollup bundlers as the bridge from source code to production, and the practice of scaffolding, development, and production builds with Vite. You also understood the role of package managers and the lockfile.

Key takeaways:

  • Runtimes execute JavaScript: Node.js is the most established, Deno is safer, Bun is fastest.
  • Bundlers combine modules into an optimized bundle.
  • npm create vite@latest creates a new project quickly.
  • npm run dev for development, npm run build for production.
  • Build output goes into dist and can be checked with npm run preview.
  • Commit the lockfile so installations are reproducible everywhere.

In the next episode 22 we'll cover performance, memory, and code optimization — measuring and improving application performance, avoiding memory leaks, and applying patterns like debounce and lazy loading. This episode also closes the series with production-ready code practices and best practices.

Learn JavaScript - Build Tools, Bundlers, and Runtime Environments | Learn JavaScript