Skip to content
EzzyWeb

Level 5, Professional Practice, Chapter 21 of 24

Developer Workflow — npm, Git & Build Tools

Why this matters

Every project you've built so far has probably lived in a single folder you edited directly, hoping nothing broke. That works for small experiments, but it falls apart the moment you collaborate with anyone else, need to undo a mistake from three days ago, or want to reuse a library someone else has already written instead of rebuilding it from scratch. Professional developers rely on a small set of tools — package managers, version control, and build tools — to solve exactly these problems, and they're not optional extras reserved for large teams. Even solo, one-page projects benefit enormously from them.

This chapter introduces npm, Git, and modern build tools as a connected workflow rather than three unrelated topics. Once you're comfortable with this trio, you'll be equipped to work the way real teams do: pulling in code others have written, tracking every change you make with the ability to undo any of it, and bundling your project efficiently for the browser.

The lesson

npm and the world of packages

You've written your own JavaScript modules and used import/export to organize code across files. npm (Node Package Manager) extends that same idea to code written by other people. Instead of copying a date-formatting library's source into your project by hand, you run a single command, and npm downloads it, tracks its version, and records it as a dependency in a file called package.json. This file is the identity card of your project: it lists the project's name, version, scripts, and every package it depends on, so anyone (including future you) can recreate the exact same environment by running one install command.

A typical package.json
JSON
1{2  "name": "portfolio-site",3  "version": "1.0.0",4  "scripts": {5    "dev": "vite",6    "build": "vite build",7    "test": "vitest run"8  },9  "dependencies": {10    "date-fns": "^3.6.0"11  },12  "devDependencies": {13    "vite": "^5.2.0",14    "vitest": "^1.6.0"15  }16}
dependencies are needed to run the app; devDependencies are only needed while building or testing it.

When you run npm install, npm reads package.json, downloads every listed package (and everything those packages depend on) into a folder called node_modules, and records the exact versions installed in package-lock.json. You never commit node_modules to version control; it's regenerated from the lockfile whenever needed, which keeps repositories small and installs reproducible. npm run <script-name> executes any command listed under scripts, which is why you'll often see npm run dev or npm run build rather than long raw commands.

Git: a save system for your entire project

Git is a version control system that takes snapshots, called commits, of your project over time. Each commit records exactly what changed, who changed it, and why, based on the message you write. This means you can always look back at any previous state of your project, compare two versions to see exactly what changed line by line, and safely experiment on a separate branch without risking your working code. If you've ever renamed a file script-final-v2-ACTUAL.js out of fear of losing a working version, Git replaces that entire anxious habit with a structured, searchable history.

A typical Git workflow
Terminal
1git status                          # see what changed2git add index.html style.css        # stage specific files3git commit -m "Add responsive nav"  # save a snapshot with a message4git push origin main                # send commits to the remote repo
This sequence stages your changes, records them with a message, and pushes them to a remote repository like GitHub.
  • git init starts tracking a new project; git clone <url> copies an existing repository.
  • Branches let you build a feature in isolation with git checkout -b feature-name, then merge it back once it works.
  • A .gitignore file tells Git which files to never track, like node_modules or local environment secrets.
  • Commit messages should describe what changed and why, since you'll read them again months later with no memory of the details.

Build tools: bridging your code and the browser

In earlier chapters, you wrote JavaScript modules and linked them directly with <script type="module">. That works, but it doesn't scale well: browsers must fetch each imported file separately, some newer JavaScript syntax isn't supported everywhere, and features like importing CSS or images directly into JavaScript aren't native browser behavior at all. Build tools like Vite solve this by taking your source files, resolving all the imports, transforming any modern or unsupported syntax, and bundling everything into a small number of optimized files ready for production. During development, Vite also gives you instant reloading, so saving a file updates the browser in a fraction of a second without a full page refresh.

Starting a new Vite project
Terminal
1npm create vite@latest my-app -- --template vanilla2cd my-app3npm install4npm run dev
This scaffolds a project structure, installs dependencies, and starts a local dev server with live reload.

Understanding what a build step actually does demystifies a lot of what happens behind the scenes in modern web development. When you run npm run build, the tool reads your entry file, follows every import statement to build a dependency graph, minifies the JavaScript and CSS by stripping whitespace and shortening variable names, and outputs a small set of files in a dist folder ready to deploy. Nothing magical is happening; it's an automated, faster version of tasks you could technically do by hand, similar to how you already understood what fetch was doing instead of treating it as a black box.

Try it yourself

This sandbox simulates a package.json file and a simple build script. Read through the JS, which acts like a tiny simplified 'bundler': it resolves fake module imports and reports the build order. Modify the module dependency graph and predict the output order before running it.

Live preview

Chapter boss project

Boss Project: Set Up a Real Project From Scratch

Create a brand-new project using a build tool (Vite is recommended) instead of plain linked files. Initialize it with npm create vite@latest, choose the vanilla JavaScript template, and get the dev server running with live reload.

Turn the project into a Git repository, make an initial commit, and then make at least five more meaningful commits as you build out a small page (reuse a project idea from an earlier chapter if you like). Write clear, specific commit messages for each one.

Add at least one real npm package as a dependency (a date library, a small utility library, or similar), import it properly in your JavaScript, and use it for something visible on the page. Push the finished repository to GitHub.

  • If `npm create vite@latest` prompts for a framework, choose 'Vanilla' and then 'JavaScript' to match what you already know.
  • Run `git init` before your first commit if you didn't create the repository through GitHub first, and check your `.gitignore` includes `node_modules`.
  • Search npm's website (npmjs.com) for a small utility package like `date-fns` or `nanoid` to practice installing and importing a real dependency.
  • Commit early and often. A commit after every small working change is far more useful later than one giant commit at the end.

Level-up checklist

Tick these off once each one is true for you.