<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Bhadra Mohit</title>
    <description>The latest articles on DEV Community by Bhadra Mohit (@bhadramohit).</description>
    <link>https://dev.to/bhadramohit</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4099961%2F82350897-8c30-4240-9299-72b40bbb20bc.jpg</url>
      <title>DEV Community: Bhadra Mohit</title>
      <link>https://dev.to/bhadramohit</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bhadramohit"/>
    <language>en</language>
    <item>
      <title>A Complete Guide to Git: Commands, Usage, and Step-by-Step Workflow</title>
      <dc:creator>Bhadra Mohit</dc:creator>
      <pubDate>Sat, 29 Aug 2026 10:48:44 +0000</pubDate>
      <link>https://dev.to/bhadramohit/a-complete-guide-to-git-commands-usage-and-step-by-step-workflow-4m8n</link>
      <guid>https://dev.to/bhadramohit/a-complete-guide-to-git-commands-usage-and-step-by-step-workflow-4m8n</guid>
      <description>&lt;p&gt;Whether you're working solo on a side project or collaborating with a team of 50 developers, &lt;strong&gt;Git&lt;/strong&gt; is the backbone of modern software development. It tracks every change you make, lets you experiment safely with branches, and makes collaboration possible without stepping on each other's code.&lt;/p&gt;

&lt;p&gt;This guide walks through Git from the ground up — what it is, why you need it, and a detailed, hands-on breakdown of the commands you'll actually use every day, along with the ones you'll reach for once things get a little more advanced.&lt;/p&gt;




&lt;h3&gt;
  
  
  What is Git and Why Do You Need It?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Git&lt;/strong&gt; is a &lt;strong&gt;distributed version control system (VCS)&lt;/strong&gt; that tracks changes to files over time. "Distributed" means every developer has a full copy of the project's history on their own machine — not just the latest files, but every commit ever made. This is what makes Git fast, reliable, and usable even without an internet connection.&lt;/p&gt;

&lt;p&gt;Git lets you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Save "snapshots" of your project at any point (commits)&lt;/li&gt;
&lt;li&gt;Go back to a previous version if something breaks&lt;/li&gt;
&lt;li&gt;Work on new features without affecting the main codebase (branching)&lt;/li&gt;
&lt;li&gt;Merge work from multiple people without overwriting each other's changes&lt;/li&gt;
&lt;li&gt;Keep a full history of who changed what, and when, and why&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Git vs a Traditional Save System
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;Without Git&lt;/th&gt;
&lt;th&gt;With Git&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Change tracking&lt;/td&gt;
&lt;td&gt;Manual (copy-pasting folders like &lt;code&gt;project_final_v2&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Automatic, precise history of every change&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Collaboration&lt;/td&gt;
&lt;td&gt;Risk of overwriting others' work&lt;/td&gt;
&lt;td&gt;Merge and conflict resolution built in&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rollback&lt;/td&gt;
&lt;td&gt;Difficult or impossible&lt;/td&gt;
&lt;td&gt;Instant — revert to any previous commit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Branching&lt;/td&gt;
&lt;td&gt;Not possible without duplicating folders&lt;/td&gt;
&lt;td&gt;Native, lightweight branching&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Accountability&lt;/td&gt;
&lt;td&gt;No record of who changed what&lt;/td&gt;
&lt;td&gt;Full commit history with author and timestamp&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Offline work&lt;/td&gt;
&lt;td&gt;Depends on manual backups&lt;/td&gt;
&lt;td&gt;Full history available locally, no network needed&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  Git vs GitHub — A Common Point of Confusion
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frozyiap2ccnk2hj9xb06.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frozyiap2ccnk2hj9xb06.png" alt="Source: GitHub" width="770" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's worth clarifying this early: &lt;strong&gt;Git&lt;/strong&gt; is the version control tool itself (installed on your machine). &lt;strong&gt;GitHub&lt;/strong&gt; (along with GitLab, Bitbucket, etc.) is a cloud platform that &lt;em&gt;hosts&lt;/em&gt; Git repositories and adds collaboration features like pull requests, issues, and code review. You can use Git without ever touching GitHub — but GitHub makes sharing and collaborating far easier.&lt;/p&gt;




&lt;h3&gt;
  
  
  Installing and Setting Up Git
&lt;/h3&gt;

&lt;p&gt;Before using Git, install it for your OS (via git-scm.com, a package manager like &lt;code&gt;apt&lt;/code&gt;/&lt;code&gt;brew&lt;/code&gt;/&lt;code&gt;choco&lt;/code&gt;), then configure your identity — this information gets attached to every commit you make.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; user.name &lt;span class="s2"&gt;"Your Name"&lt;/span&gt;
git config &lt;span class="nt"&gt;--global&lt;/span&gt; user.email &lt;span class="s2"&gt;"you@example.com"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some other useful one-time configuration steps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; init.defaultBranch main     &lt;span class="c"&gt;# set default branch name to "main"&lt;/span&gt;
git config &lt;span class="nt"&gt;--global&lt;/span&gt; core.editor &lt;span class="s2"&gt;"code --wait"&lt;/span&gt;   &lt;span class="c"&gt;# set VS Code as your commit message editor&lt;/span&gt;
git config &lt;span class="nt"&gt;--global&lt;/span&gt; color.ui auto               &lt;span class="c"&gt;# enable colored output in the terminal&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check your current configuration anytime:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config &lt;span class="nt"&gt;--list&lt;/span&gt;          &lt;span class="c"&gt;# view all settings&lt;/span&gt;
git config user.name       &lt;span class="c"&gt;# view a specific setting&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Git config exists at three levels — &lt;code&gt;--local&lt;/code&gt; (this repo only), &lt;code&gt;--global&lt;/code&gt; (this user, all repos), and &lt;code&gt;--system&lt;/code&gt; (all users on the machine). Local settings override global, which override system.&lt;/p&gt;




&lt;h3&gt;
  
  
  Starting a Project: &lt;code&gt;init&lt;/code&gt; vs &lt;code&gt;clone&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;There are two ways to start working with Git on a project.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;git init&lt;/code&gt; — Start a New Repository
&lt;/h4&gt;

&lt;p&gt;Turns your current folder into a Git repository, creating a hidden &lt;code&gt;.git&lt;/code&gt; folder that stores all version history.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git init
git init my-project        &lt;span class="c"&gt;# create the folder and initialize it in one step&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;code&gt;git clone&lt;/code&gt; — Copy an Existing Repository
&lt;/h4&gt;

&lt;p&gt;Downloads a full copy of an existing repository (including all its history) from a remote source like GitHub.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/username/repository.git
git clone https://github.com/username/repository.git custom-folder-name
git clone &lt;span class="nt"&gt;--depth&lt;/span&gt; 1 https://github.com/username/repository.git   &lt;span class="c"&gt;# shallow clone, history only from the latest commit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;init&lt;/code&gt; vs &lt;code&gt;clone&lt;/code&gt; at a glance:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;code&gt;git init&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;git clone&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Creates a brand-new, empty repository&lt;/td&gt;
&lt;td&gt;Copies an existing repository&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Used when starting a project from scratch&lt;/td&gt;
&lt;td&gt;Used when joining an existing project&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No remote connection by default&lt;/td&gt;
&lt;td&gt;Automatically sets up the remote (&lt;code&gt;origin&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h3&gt;
  
  
  The Core Git Workflow
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxkdtuulqgdaw1as0ilhh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxkdtuulqgdaw1as0ilhh.png" alt="Source: Medium" width="602" height="509"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Understanding Git means understanding its &lt;strong&gt;three (or four) areas&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Working Directory&lt;/strong&gt; — Your actual project files, where you make edits&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Staging Area (Index)&lt;/strong&gt; — A holding area for changes you're about to commit&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Local Repository (.git)&lt;/strong&gt; — Where committed snapshots are permanently stored on your machine&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remote Repository&lt;/strong&gt; — The shared copy hosted on a server (e.g., GitHub), synced via &lt;code&gt;push&lt;/code&gt;/&lt;code&gt;pull&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here's the typical day-to-day flow, step by step:&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 1: Check the Status
&lt;/h4&gt;

&lt;p&gt;See what's changed, what's staged, and what's untracked.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git status              &lt;span class="c"&gt;# detailed status&lt;/span&gt;
git status &lt;span class="nt"&gt;-s&lt;/span&gt;           &lt;span class="c"&gt;# short, condensed format&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 2: Ignore Files You Don't Want Tracked
&lt;/h4&gt;

&lt;p&gt;Before staging, it's worth setting up a &lt;code&gt;.gitignore&lt;/code&gt; file so build artifacts, dependencies, and secrets never get committed by accident.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# .gitignore example
node_modules/
.env
*.log
dist/
.DS_Store
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Git will simply skip any file or folder pattern listed here when you run &lt;code&gt;git add&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 3: Stage Your Changes
&lt;/h4&gt;

&lt;p&gt;Move changes from the working directory into the staging area, preparing them for a commit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add filename.txt      &lt;span class="c"&gt;# stage a specific file&lt;/span&gt;
git add folder/           &lt;span class="c"&gt;# stage everything in a folder&lt;/span&gt;
git add &lt;span class="nb"&gt;.&lt;/span&gt;                 &lt;span class="c"&gt;# stage all changed files in the current directory and below&lt;/span&gt;
git add &lt;span class="nt"&gt;-A&lt;/span&gt;                &lt;span class="c"&gt;# stage all changes across the entire repo, including deletions&lt;/span&gt;
git add &lt;span class="nt"&gt;-p&lt;/span&gt;                &lt;span class="c"&gt;# interactively choose which changes (hunks) to stage&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;git add .&lt;/code&gt; vs &lt;code&gt;git add -A&lt;/code&gt;:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;code&gt;git add .&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;git add -A&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Stages new and modified files in current directory and below&lt;/td&gt;
&lt;td&gt;Stages all changes across the entire repository&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;May miss deleted files outside current directory&lt;/td&gt;
&lt;td&gt;Includes deletions everywhere&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  Step 4: Commit Your Changes
&lt;/h4&gt;

&lt;p&gt;Save a permanent snapshot of the staged changes, with a message describing what changed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Add login functionality"&lt;/span&gt;
git commit &lt;span class="nt"&gt;-am&lt;/span&gt; &lt;span class="s2"&gt;"Fix navbar alignment bug"&lt;/span&gt;     &lt;span class="c"&gt;# stage tracked files + commit in one step&lt;/span&gt;
git commit &lt;span class="nt"&gt;--amend&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Corrected commit message"&lt;/span&gt;   &lt;span class="c"&gt;# edit the most recent commit&lt;/span&gt;
git commit &lt;span class="nt"&gt;--amend&lt;/span&gt; &lt;span class="nt"&gt;--no-edit&lt;/span&gt;                  &lt;span class="c"&gt;# add staged changes to the last commit without changing its message&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Only amend commits that haven't been pushed yet — amending shared history causes conflicts for collaborators.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Good commit messages matter. A widely used convention:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;type&amp;gt;: &amp;lt;short summary&amp;gt;

&amp;lt;optional longer description&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example: &lt;code&gt;fix: correct off-by-one error in pagination logic&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Common types: &lt;code&gt;feat&lt;/code&gt;, &lt;code&gt;fix&lt;/code&gt;, &lt;code&gt;docs&lt;/code&gt;, &lt;code&gt;style&lt;/code&gt;, &lt;code&gt;refactor&lt;/code&gt;, &lt;code&gt;test&lt;/code&gt;, &lt;code&gt;chore&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 5: View History
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git log                       &lt;span class="c"&gt;# full commit history&lt;/span&gt;
git log &lt;span class="nt"&gt;--oneline&lt;/span&gt;             &lt;span class="c"&gt;# condensed, one line per commit&lt;/span&gt;
git log &lt;span class="nt"&gt;--oneline&lt;/span&gt; &lt;span class="nt"&gt;--graph&lt;/span&gt;     &lt;span class="c"&gt;# visual branch history&lt;/span&gt;
git log &lt;span class="nt"&gt;--author&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Mohit"&lt;/span&gt;      &lt;span class="c"&gt;# filter commits by author&lt;/span&gt;
git log &lt;span class="nt"&gt;-p&lt;/span&gt; filename.txt       &lt;span class="c"&gt;# show changes made to a specific file over time&lt;/span&gt;
git show &amp;lt;commit-hash&amp;gt;        &lt;span class="c"&gt;# show details and diff of one specific commit&lt;/span&gt;
git blame filename.txt        &lt;span class="c"&gt;# see who last modified each line of a file&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 6: Push to a Remote Repository
&lt;/h4&gt;

&lt;p&gt;Upload your local commits to a remote server like GitHub.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git push origin main
git push &lt;span class="nt"&gt;-u&lt;/span&gt; origin main        &lt;span class="c"&gt;# push and set upstream tracking (only needed once per branch)&lt;/span&gt;
git push                       &lt;span class="c"&gt;# after upstream is set, just this works&lt;/span&gt;
git push &lt;span class="nt"&gt;--force-with-lease&lt;/span&gt;    &lt;span class="c"&gt;# safer force-push that fails if remote has new commits you don't have&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Caution:&lt;/strong&gt; Avoid &lt;code&gt;git push --force&lt;/code&gt; on shared branches — it overwrites remote history and can wipe out teammates' work. &lt;code&gt;--force-with-lease&lt;/code&gt; is the safer alternative since it checks first.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Step 7: Fetch and Pull Updates
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git fetch origin           &lt;span class="c"&gt;# download remote changes WITHOUT merging them into your branch&lt;/span&gt;
git pull origin main       &lt;span class="c"&gt;# fetch AND merge remote changes into your current branch&lt;/span&gt;
git pull &lt;span class="nt"&gt;--rebase&lt;/span&gt;          &lt;span class="c"&gt;# fetch and rebase instead of merge, for a cleaner history&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;fetch&lt;/code&gt; vs &lt;code&gt;pull&lt;/code&gt;:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;code&gt;git fetch&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;git pull&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Downloads changes only&lt;/td&gt;
&lt;td&gt;Downloads AND merges changes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Safe — doesn't touch your working files&lt;/td&gt;
&lt;td&gt;Can create merge commits or conflicts immediately&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lets you review before merging&lt;/td&gt;
&lt;td&gt;Applies changes right away&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h3&gt;
  
  
  Branching: Working on Features Independently
&lt;/h3&gt;

&lt;p&gt;Branches let you work on new features or fixes without touching the main codebase until you're ready.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git branch                     &lt;span class="c"&gt;# list all local branches&lt;/span&gt;
git branch &lt;span class="nt"&gt;-a&lt;/span&gt;                  &lt;span class="c"&gt;# list all branches, including remote-tracking ones&lt;/span&gt;
git branch feature/login       &lt;span class="c"&gt;# create a new branch&lt;/span&gt;
git checkout feature/login     &lt;span class="c"&gt;# switch to that branch&lt;/span&gt;
git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; feature/login  &lt;span class="c"&gt;# create AND switch in one command&lt;/span&gt;
git switch feature/login       &lt;span class="c"&gt;# modern alternative to checkout&lt;/span&gt;
git switch &lt;span class="nt"&gt;-c&lt;/span&gt; feature/login    &lt;span class="c"&gt;# modern alternative to checkout -b&lt;/span&gt;
git branch &lt;span class="nt"&gt;-m&lt;/span&gt; old-name new-name   &lt;span class="c"&gt;# rename a branch&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Merging Branches
&lt;/h4&gt;

&lt;p&gt;Once your feature is ready, merge it back into the main branch.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout main
git merge feature/login
git merge &lt;span class="nt"&gt;--no-ff&lt;/span&gt; feature/login   &lt;span class="c"&gt;# always create a merge commit, even for fast-forward merges (preserves feature history)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Resolving Merge Conflicts
&lt;/h4&gt;

&lt;p&gt;Conflicts happen when the same lines of a file were changed differently on two branches. Git will pause the merge and mark the conflicting sections in the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; HEAD
your current branch's version
=======
the incoming branch's version
&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; feature/login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To resolve it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the file and manually edit it to keep the correct content (removing the &lt;code&gt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&lt;/code&gt;, &lt;code&gt;=======&lt;/code&gt;, &lt;code&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&lt;/code&gt; markers)&lt;/li&gt;
&lt;li&gt;Stage the resolved file — &lt;code&gt;git add filename.txt&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Complete the merge — &lt;code&gt;git commit&lt;/code&gt; (Git pre-fills a merge commit message for you)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you want to back out of a conflicted merge entirely:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git merge &lt;span class="nt"&gt;--abort&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Deleting a Branch
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git branch &lt;span class="nt"&gt;-d&lt;/span&gt; feature/login          &lt;span class="c"&gt;# safe delete (only if merged)&lt;/span&gt;
git branch &lt;span class="nt"&gt;-D&lt;/span&gt; feature/login          &lt;span class="c"&gt;# force delete (even if not merged)&lt;/span&gt;
git push origin &lt;span class="nt"&gt;--delete&lt;/span&gt; feature/login   &lt;span class="c"&gt;# delete the branch on the remote too&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;checkout&lt;/code&gt;/&lt;code&gt;switch&lt;/code&gt; vs &lt;code&gt;merge&lt;/code&gt;:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;git checkout&lt;/code&gt; / &lt;code&gt;git switch&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Moves you between branches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git merge&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Combines changes from one branch into another&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h3&gt;
  
  
  Undoing Changes: Choosing the Right Command
&lt;/h3&gt;

&lt;p&gt;Git offers multiple ways to undo work, depending on how far you want to go back.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;git restore&lt;/code&gt; — Undo Uncommitted Changes
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git restore filename.txt          &lt;span class="c"&gt;# discard changes in working directory&lt;/span&gt;
git restore &lt;span class="nt"&gt;--staged&lt;/span&gt; filename.txt &lt;span class="c"&gt;# unstage a file (keep the edits)&lt;/span&gt;
git restore &lt;span class="nt"&gt;--source&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;HEAD~1 filename.txt   &lt;span class="c"&gt;# restore a file to how it was one commit ago&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;code&gt;git reset&lt;/code&gt; — Move the Commit Pointer Backward
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git reset &lt;span class="nt"&gt;--soft&lt;/span&gt; HEAD~1    &lt;span class="c"&gt;# undo last commit, keep changes staged&lt;/span&gt;
git reset &lt;span class="nt"&gt;--mixed&lt;/span&gt; HEAD~1   &lt;span class="c"&gt;# undo last commit, keep changes unstaged (this is the default mode)&lt;/span&gt;
git reset &lt;span class="nt"&gt;--hard&lt;/span&gt; HEAD~1    &lt;span class="c"&gt;# undo last commit AND discard all changes permanently&lt;/span&gt;
git reset &amp;lt;commit-hash&amp;gt;    &lt;span class="c"&gt;# reset to a specific commit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;code&gt;git revert&lt;/code&gt; — Safely Undo a Commit (Recommended for Shared Branches)
&lt;/h4&gt;

&lt;p&gt;Instead of erasing history, &lt;code&gt;revert&lt;/code&gt; creates a &lt;strong&gt;new commit&lt;/strong&gt; that undoes a previous one — safer for branches others are working on.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git revert &amp;lt;commit-hash&amp;gt;
git revert HEAD               &lt;span class="c"&gt;# revert the most recent commit&lt;/span&gt;
git revert &lt;span class="nt"&gt;--no-commit&lt;/span&gt; &amp;lt;commit-hash&amp;gt;   &lt;span class="c"&gt;# revert changes without auto-committing, so you can review first&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;reset&lt;/code&gt; vs &lt;code&gt;revert&lt;/code&gt;:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;code&gt;git reset&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;git revert&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Rewrites history (dangerous on shared branches)&lt;/td&gt;
&lt;td&gt;Preserves history, adds a new "undo" commit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Good for local, unpushed commits&lt;/td&gt;
&lt;td&gt;Good for commits already pushed/shared&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Can permanently lose changes (&lt;code&gt;--hard&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Never loses commit history&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;git reflog&lt;/code&gt; — Your Safety Net
&lt;/h4&gt;

&lt;p&gt;Even after a &lt;code&gt;reset --hard&lt;/code&gt;, Git usually hasn't actually deleted your commits yet. &lt;code&gt;reflog&lt;/code&gt; shows a log of everywhere &lt;code&gt;HEAD&lt;/code&gt; has pointed, letting you recover "lost" commits.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git reflog
git checkout &amp;lt;commit-hash-from-reflog&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Working with Remotes
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git remote &lt;span class="nt"&gt;-v&lt;/span&gt;                                   &lt;span class="c"&gt;# view connected remotes and their URLs&lt;/span&gt;
git remote add origin &amp;lt;repository-url&amp;gt;          &lt;span class="c"&gt;# connect a remote repository&lt;/span&gt;
git remote remove origin                        &lt;span class="c"&gt;# disconnect a remote&lt;/span&gt;
git remote rename origin upstream               &lt;span class="c"&gt;# rename a remote&lt;/span&gt;
git remote show origin                          &lt;span class="c"&gt;# detailed info about a remote, including tracked branches&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Stashing: Temporarily Saving Work
&lt;/h3&gt;

&lt;p&gt;If you need to switch branches but aren't ready to commit, &lt;code&gt;stash&lt;/code&gt; saves your uncommitted changes without a commit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git stash                       &lt;span class="c"&gt;# save current changes&lt;/span&gt;
git stash save &lt;span class="s2"&gt;"WIP: navbar fix"&lt;/span&gt;   &lt;span class="c"&gt;# save with a descriptive message&lt;/span&gt;
git stash list                  &lt;span class="c"&gt;# view all stashes&lt;/span&gt;
git stash pop                   &lt;span class="c"&gt;# reapply the most recent stash and remove it from the list&lt;/span&gt;
git stash apply                 &lt;span class="c"&gt;# reapply a stash but keep it in the list&lt;/span&gt;
git stash apply stash@&lt;span class="o"&gt;{&lt;/span&gt;2&lt;span class="o"&gt;}&lt;/span&gt;       &lt;span class="c"&gt;# apply a specific stash by index&lt;/span&gt;
git stash drop stash@&lt;span class="o"&gt;{&lt;/span&gt;0&lt;span class="o"&gt;}&lt;/span&gt;        &lt;span class="c"&gt;# delete a specific stash&lt;/span&gt;
git stash clear                 &lt;span class="c"&gt;# delete all stashes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Comparing Changes
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git diff                     &lt;span class="c"&gt;# changes in working directory not yet staged&lt;/span&gt;
git diff &lt;span class="nt"&gt;--staged&lt;/span&gt;            &lt;span class="c"&gt;# changes staged but not yet committed&lt;/span&gt;
git diff branch1 branch2     &lt;span class="c"&gt;# differences between two branches&lt;/span&gt;
git diff HEAD~2 HEAD         &lt;span class="c"&gt;# differences between two commits&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Rewriting and Combining Commits
&lt;/h3&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;git rebase&lt;/code&gt; — Reapply Commits on Top of Another Branch
&lt;/h4&gt;

&lt;p&gt;Rewrites commit history to create a cleaner, linear project history (compared to merge, which preserves branch structure).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout feature/login
git rebase main
git rebase &lt;span class="nt"&gt;-i&lt;/span&gt; HEAD~3          &lt;span class="c"&gt;# interactive rebase — reorder, edit, squash, or drop the last 3 commits&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;During an interactive rebase, Git opens an editor listing your commits with options like &lt;code&gt;pick&lt;/code&gt;, &lt;code&gt;squash&lt;/code&gt;, &lt;code&gt;reword&lt;/code&gt;, and &lt;code&gt;drop&lt;/code&gt; next to each one — letting you clean up messy commit history before merging.&lt;/p&gt;

&lt;p&gt;If conflicts occur during a rebase:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# fix the conflicted files, then:&lt;/span&gt;
git add &lt;span class="nb"&gt;.&lt;/span&gt;
git rebase &lt;span class="nt"&gt;--continue&lt;/span&gt;
&lt;span class="c"&gt;# or to cancel entirely:&lt;/span&gt;
git rebase &lt;span class="nt"&gt;--abort&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;merge&lt;/code&gt; vs &lt;code&gt;rebase&lt;/code&gt;:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;code&gt;git merge&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;git rebase&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Preserves full branch history&lt;/td&gt;
&lt;td&gt;Creates a clean, linear history&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Adds a merge commit&lt;/td&gt;
&lt;td&gt;No extra merge commit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Safe for shared/public branches&lt;/td&gt;
&lt;td&gt;Best used on local, unpushed branches&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;git cherry-pick&lt;/code&gt; — Apply a Specific Commit from Another Branch
&lt;/h4&gt;

&lt;p&gt;Useful when you need just one specific fix from another branch, without merging everything.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git cherry-pick &amp;lt;commit-hash&amp;gt;
git cherry-pick &amp;lt;hash1&amp;gt; &amp;lt;hash2&amp;gt;     &lt;span class="c"&gt;# cherry-pick multiple commits&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Tagging Releases
&lt;/h3&gt;

&lt;p&gt;Tags mark specific points in history — commonly used for release versions (&lt;code&gt;v1.0&lt;/code&gt;, &lt;code&gt;v2.1.3&lt;/code&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git tag v1.0                        &lt;span class="c"&gt;# create a lightweight tag&lt;/span&gt;
git tag &lt;span class="nt"&gt;-a&lt;/span&gt; v1.0 &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Version 1.0"&lt;/span&gt;    &lt;span class="c"&gt;# create an annotated tag with a message&lt;/span&gt;
git tag                             &lt;span class="c"&gt;# list all tags&lt;/span&gt;
git push origin v1.0                &lt;span class="c"&gt;# push a specific tag&lt;/span&gt;
git push origin &lt;span class="nt"&gt;--tags&lt;/span&gt;              &lt;span class="c"&gt;# push all tags&lt;/span&gt;
git tag &lt;span class="nt"&gt;-d&lt;/span&gt; v1.0                     &lt;span class="c"&gt;# delete a local tag&lt;/span&gt;
git push origin &lt;span class="nt"&gt;--delete&lt;/span&gt; v1.0       &lt;span class="c"&gt;# delete a tag from the remote&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Bonus: Submodules and Aliases
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Git Submodules
&lt;/h4&gt;

&lt;p&gt;Submodules let you include one Git repository inside another — useful for shared libraries.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git submodule add https://github.com/user/library.git libs/library
git submodule update &lt;span class="nt"&gt;--init&lt;/span&gt; &lt;span class="nt"&gt;--recursive&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Git Aliases — Save Yourself Some Typing
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; alias.co checkout
git config &lt;span class="nt"&gt;--global&lt;/span&gt; alias.br branch
git config &lt;span class="nt"&gt;--global&lt;/span&gt; alias.st status
git config &lt;span class="nt"&gt;--global&lt;/span&gt; alias.cm &lt;span class="s2"&gt;"commit -m"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now &lt;code&gt;git st&lt;/code&gt; works exactly like &lt;code&gt;git status&lt;/code&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Common Git Commands Cheat Sheet
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git init&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Initialize a new repository&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git clone &amp;lt;url&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Copy an existing repository&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git status&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show current state of working directory&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git add .&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Stage all changes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git commit -m "message"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Save a snapshot with a message&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git push&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Upload commits to remote&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git fetch&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Download remote changes without merging&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git pull&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Download and merge remote changes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git branch&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List/create branches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;git checkout&lt;/code&gt; / &lt;code&gt;git switch&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Switch branches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git merge&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Combine branch changes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git log&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;View commit history&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git diff&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;View unstaged/staged differences&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git stash&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Temporarily save uncommitted changes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git reset&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Move commit pointer, optionally discarding changes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git revert&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Undo a commit safely with a new commit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git rebase&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Reapply commits for a linear history&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git cherry-pick&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Apply a specific commit to the current branch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git tag&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Mark a specific commit (e.g., a release)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git reflog&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Recover lost commits or view HEAD history&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h3&gt;
  
  
  A Realistic Step-by-Step Example
&lt;/h3&gt;

&lt;p&gt;Here's what a typical feature development flow looks like end to end:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Update your local main branch&lt;/strong&gt; — &lt;code&gt;git checkout main &amp;amp;&amp;amp; git pull origin main&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create a new branch&lt;/strong&gt; — &lt;code&gt;git checkout -b feature/user-profile&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Make your code changes&lt;/strong&gt; in your editor&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check what changed&lt;/strong&gt; — &lt;code&gt;git status&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stage the changes&lt;/strong&gt; — &lt;code&gt;git add .&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Commit with a clear message&lt;/strong&gt; — &lt;code&gt;git commit -m "feat: add user profile page"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Push the branch to remote&lt;/strong&gt; — &lt;code&gt;git push -u origin feature/user-profile&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open a Pull Request&lt;/strong&gt; on GitHub/GitLab for review&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Address review feedback&lt;/strong&gt; — make edits, then &lt;code&gt;git add .&lt;/code&gt; and &lt;code&gt;git commit --amend --no-edit&lt;/code&gt; or a new commit, then push again&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resolve any merge conflicts&lt;/strong&gt; if the main branch has moved forward&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Merge into main&lt;/strong&gt; once approved, then delete the feature branch — both locally and on the remote&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Wrapping Up
&lt;/h3&gt;

&lt;p&gt;Git can feel overwhelming at first because of how many commands it has, but in practice, you'll use a small core set daily: &lt;code&gt;status&lt;/code&gt;, &lt;code&gt;add&lt;/code&gt;, &lt;code&gt;commit&lt;/code&gt;, &lt;code&gt;push&lt;/code&gt;, &lt;code&gt;pull&lt;/code&gt;, &lt;code&gt;branch&lt;/code&gt;, and &lt;code&gt;merge&lt;/code&gt;. The rest — &lt;code&gt;stash&lt;/code&gt;, &lt;code&gt;rebase&lt;/code&gt;, &lt;code&gt;cherry-pick&lt;/code&gt;, &lt;code&gt;revert&lt;/code&gt;, &lt;code&gt;reflog&lt;/code&gt; — become genuinely useful as your projects grow and your collaboration needs get more complex.&lt;/p&gt;

&lt;p&gt;The best way to get comfortable with Git isn't memorizing every command — it's using it daily on real projects until the workflow becomes second nature. Break something, fix it, and you'll understand Git faster than any tutorial can teach you.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;&lt;em&gt;Made with care by Mohit Bhadra. If this guide helped you understand Git a little better, feel free to share it with someone who's still afraid of the command line.&lt;/em&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvzd4z37c0h2c9yd59xog.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvzd4z37c0h2c9yd59xog.png" alt="Source: Github" width="800" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
      <category>cli</category>
      <category>programming</category>
    </item>
    <item>
      <title>Test Automation Tools: A Complete Guide to Selenium, JUnit, and TestNG</title>
      <dc:creator>Bhadra Mohit</dc:creator>
      <pubDate>Sat, 29 Aug 2026 10:24:42 +0000</pubDate>
      <link>https://dev.to/bhadramohit/test-automation-tools-a-complete-guide-to-selenium-junit-and-testng-47mi</link>
      <guid>https://dev.to/bhadramohit/test-automation-tools-a-complete-guide-to-selenium-junit-and-testng-47mi</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F90f0cvy4sq3l1phugp6d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F90f0cvy4sq3l1phugp6d.png" alt="Selenium, JUnit and TestNG" width="800" height="437"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Manual testing alone can't keep up with modern software delivery. Every sprint, every release, and every hotfix demands repeated checks — and doing that by hand, again and again, is slow, expensive, and error-prone. That's where test automation tools step in.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;In this guide, we'll walk through the fundamentals of test automation, compare it with manual testing, and then dive into three of the most widely used tools in the Java testing ecosystem: &lt;strong&gt;Selenium&lt;/strong&gt;, &lt;strong&gt;JUnit&lt;/strong&gt;, and &lt;strong&gt;TestNG&lt;/strong&gt;. By the end, you'll understand not just &lt;em&gt;what&lt;/em&gt; these tools do, but &lt;em&gt;how&lt;/em&gt; they fit together to build a real automation workflow.&lt;/em&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  Introduction to Test Automation
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Test automation&lt;/strong&gt; is the practice of using specialized software to execute test cases, compare actual outcomes with expected results, and report the outcome — all without a human manually clicking through the application.&lt;/p&gt;

&lt;p&gt;Instead of a tester repeating the same steps every time a new build is released, an automation script does it in seconds, consistently and accurately.&lt;/p&gt;
&lt;h4&gt;
  
  
  Why Do We Need Automation in Software Testing?
&lt;/h4&gt;

&lt;p&gt;As applications grow bigger and release cycles get shorter (thanks to Agile and DevOps practices), manual testing starts to hit real limits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Repetitive regression testing&lt;/strong&gt; — Every new feature can break existing functionality. Re-testing the entire application manually for every release isn't scalable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speed of delivery&lt;/strong&gt; — Teams push code multiple times a day. Manual testers simply cannot verify builds that fast.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Human error&lt;/strong&gt; — Repetitive manual work leads to fatigue, and fatigue leads to missed bugs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-browser and cross-device coverage&lt;/strong&gt; — Testing an app across 10 browser/OS combinations manually is extremely time-consuming.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost over time&lt;/strong&gt; — While automation has an upfront investment, it pays off quickly for tests that get executed repeatedly.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  The Automation Testing Life Cycle
&lt;/h4&gt;

&lt;p&gt;Automation isn't just "write a script and run it." It follows a structured life cycle:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Test Tool Selection&lt;/strong&gt; — Choosing the right automation tool based on the application type (web, mobile, desktop) and team's tech stack.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Defining the Scope of Automation&lt;/strong&gt; — Deciding &lt;em&gt;what&lt;/em&gt; to automate. Not everything should be automated — highly repetitive, stable, and business-critical flows are ideal candidates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Planning, Design, and Development&lt;/strong&gt; — Creating the test strategy, automation framework structure, and writing reusable test scripts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test Execution&lt;/strong&gt; — Running the automated scripts, either on demand or as part of a CI/CD pipeline.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Result Analysis and Reporting&lt;/strong&gt; — Reviewing pass/fail reports, logs, and screenshots to identify defects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintenance&lt;/strong&gt; — Updating test scripts as the application evolves (UI changes, new features, updated flows).&lt;/li&gt;
&lt;/ol&gt;


&lt;h3&gt;
  
  
  Manual Testing vs Automation Testing
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;Manual Testing&lt;/th&gt;
&lt;th&gt;Automation Testing&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Execution&lt;/td&gt;
&lt;td&gt;Performed by a human tester&lt;/td&gt;
&lt;td&gt;Performed by scripts/tools&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Speed&lt;/td&gt;
&lt;td&gt;Slower, especially for large test suites&lt;/td&gt;
&lt;td&gt;Much faster, especially for repetitive tests&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Accuracy&lt;/td&gt;
&lt;td&gt;Prone to human error and fatigue&lt;/td&gt;
&lt;td&gt;Highly consistent and precise&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Initial Cost&lt;/td&gt;
&lt;td&gt;Low setup cost&lt;/td&gt;
&lt;td&gt;Higher upfront investment (tools, scripting)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best Suited For&lt;/td&gt;
&lt;td&gt;Exploratory, usability, ad-hoc testing&lt;/td&gt;
&lt;td&gt;Regression, load, repetitive functional testing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reusability&lt;/td&gt;
&lt;td&gt;Limited — steps repeated manually each time&lt;/td&gt;
&lt;td&gt;High — scripts can be reused across builds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Human Judgment&lt;/td&gt;
&lt;td&gt;Strong (intuition, visual/UX checks)&lt;/td&gt;
&lt;td&gt;Weak (can't judge subjective quality)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h4&gt;
  
  
  Benefits of Test Automation
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Faster feedback&lt;/strong&gt; on code quality with every build&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reusable test scripts&lt;/strong&gt; across multiple test cycles&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Broader test coverage&lt;/strong&gt; in less time&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reduced human error&lt;/strong&gt; in repetitive checks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Easy integration&lt;/strong&gt; with CI/CD pipelines for continuous testing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Detailed, consistent reporting&lt;/strong&gt; for every run&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Challenges of Test Automation
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;High initial investment&lt;/strong&gt; in tools, framework setup, and skilled resources&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintenance overhead&lt;/strong&gt; — scripts break when the UI or application logic changes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not suitable for all test types&lt;/strong&gt; — exploratory and usability testing still need humans&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Requires programming skills&lt;/strong&gt; to write and maintain scripts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;False confidence risk&lt;/strong&gt; — passing automated tests don't guarantee bug-free software if coverage is poor&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;
  
  
  Selenium: Automating the Browser
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Selenium&lt;/strong&gt; is one of the most popular open-source frameworks for automating web browsers. It allows testers to simulate real user interactions — clicking buttons, filling forms, navigating pages — entirely through code.&lt;/p&gt;
&lt;h4&gt;
  
  
  What Makes Up the Selenium Framework?
&lt;/h4&gt;

&lt;p&gt;Selenium isn't a single tool; it's a suite of components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Selenium WebDriver&lt;/strong&gt; — The core component used to directly communicate with the browser and control it programmatically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Selenium Grid&lt;/strong&gt; — Allows running tests in parallel across multiple machines and browsers simultaneously.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Selenium IDE&lt;/strong&gt; — A browser extension for recording and playing back simple test scripts (great for beginners).&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Understanding Selenium WebDriver
&lt;/h4&gt;

&lt;p&gt;WebDriver acts as a bridge between your test script and the actual browser. It sends commands directly to the browser (Chrome, Firefox, Edge, Safari) using browser-specific drivers, which makes it fast and reliable compared to older approaches that relied on JavaScript injection.&lt;/p&gt;

&lt;p&gt;A simple example of Selenium WebDriver in Java:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;WebDriver&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ChromeDriver&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://example.com"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;WebElement&lt;/span&gt; &lt;span class="n"&gt;loginButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findElement&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;By&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"login"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="n"&gt;loginButton&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;click&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This script opens Chrome, navigates to a website, finds an element by its ID, and clicks it — exactly what a human tester would do manually, but automatically.&lt;/p&gt;

&lt;h4&gt;
  
  
  Advantages of Selenium for Web Application Testing
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Open-source and free&lt;/strong&gt; — no licensing cost&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-browser support&lt;/strong&gt; — Chrome, Firefox, Edge, Safari, and more&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-language support&lt;/strong&gt; — Java, Python, C#, JavaScript, Ruby&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-platform&lt;/strong&gt; — Windows, macOS, Linux&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Strong community support&lt;/strong&gt; and extensive documentation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Easy integration&lt;/strong&gt; with frameworks like JUnit, TestNG, and CI/CD tools like Jenkins&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  JUnit: The Foundation of Java Testing
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;JUnit&lt;/strong&gt; is a widely used unit testing framework for Java applications. It provides a simple, annotation-based way to write and run repeatable tests, and it's often the first testing framework Java developers learn.&lt;/p&gt;

&lt;h4&gt;
  
  
  Core Concepts of JUnit
&lt;/h4&gt;

&lt;p&gt;JUnit tests are written as regular Java methods, marked with special &lt;strong&gt;annotations&lt;/strong&gt; that tell JUnit how and when to run them.&lt;/p&gt;

&lt;p&gt;Common JUnit annotations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;@Test&lt;/code&gt; — Marks a method as a test case&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@BeforeEach&lt;/code&gt; — Runs before every test method (setup)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@AfterEach&lt;/code&gt; — Runs after every test method (cleanup)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@BeforeAll&lt;/code&gt; — Runs once before all tests in the class&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@AfterAll&lt;/code&gt; — Runs once after all tests in the class&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@Disabled&lt;/code&gt; — Skips a test temporarily&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Assertions in JUnit
&lt;/h4&gt;

&lt;p&gt;Assertions are how JUnit verifies whether the actual outcome matches the expected outcome. If an assertion fails, the test fails.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;static&lt;/span&gt; &lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;junit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jupiter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;api&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Assertions&lt;/span&gt;&lt;span class="o"&gt;.*;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.junit.jupiter.api.Test&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CalculatorTest&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;testAddition&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Calculator&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Calculator&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"2 + 3 should equal 5"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Common assertion methods include &lt;code&gt;assertEquals()&lt;/code&gt;, &lt;code&gt;assertTrue()&lt;/code&gt;, &lt;code&gt;assertFalse()&lt;/code&gt;, &lt;code&gt;assertNull()&lt;/code&gt;, and &lt;code&gt;assertThrows()&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Executing Test Cases in JUnit
&lt;/h4&gt;

&lt;p&gt;JUnit tests can be executed through:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;IDEs like IntelliJ IDEA or Eclipse (right-click → Run Test)&lt;/li&gt;
&lt;li&gt;Build tools like &lt;strong&gt;Maven&lt;/strong&gt; (&lt;code&gt;mvn test&lt;/code&gt;) or &lt;strong&gt;Gradle&lt;/strong&gt; (&lt;code&gt;gradle test&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;CI/CD pipelines, where tests run automatically on every code push&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  TestNG: A More Powerful Testing Framework
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;TestNG&lt;/strong&gt; (Test Next Generation) was built to overcome some of the limitations of older Java testing frameworks. It's inspired by JUnit but adds more flexibility and features, making it a favorite for large-scale automation projects — especially when combined with Selenium.&lt;/p&gt;

&lt;h4&gt;
  
  
  Advantages of TestNG
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Flexible test configuration&lt;/strong&gt; using XML files&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Built-in support for parallel test execution&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Grouping of test cases&lt;/strong&gt; (e.g., run only "smoke" tests or only "regression" tests)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data-Driven Testing&lt;/strong&gt; support out of the box&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Better reporting&lt;/strong&gt; with detailed HTML test reports&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dependency management&lt;/strong&gt; between test methods&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  TestNG Annotations
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;@Test&lt;/code&gt; — Marks a method as a test&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@BeforeMethod&lt;/code&gt; / &lt;code&gt;@AfterMethod&lt;/code&gt; — Runs before/after each test method&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@BeforeClass&lt;/code&gt; / &lt;code&gt;@AfterClass&lt;/code&gt; — Runs before/after all methods in a class&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@BeforeSuite&lt;/code&gt; / &lt;code&gt;@AfterSuite&lt;/code&gt; — Runs before/after the entire test suite&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@Test(priority = 1)&lt;/code&gt; — Controls execution order&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@Test(groups = "smoke")&lt;/code&gt; — Groups related tests&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Assertions in TestNG
&lt;/h4&gt;

&lt;p&gt;TestNG uses a similar assertion style to JUnit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.testng.Assert&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.testng.annotations.Test&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LoginTest&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;verifyLoginTitle&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;actualTitle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Login Page"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="nc"&gt;Assert&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;assertEquals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;actualTitle&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Login Page"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Title mismatch!"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Data-Driven Testing with TestNG
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;One of TestNG's standout features is the &lt;code&gt;@DataProvider&lt;/code&gt; annotation, which lets you run the same test method multiple times with different sets of input data — extremely useful for testing forms, login flows, or search functionality with various inputs.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@DataProvider&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"loginData"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;[][]&lt;/span&gt; &lt;span class="nf"&gt;getLoginData&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;[][]&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"user1"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"pass123"&lt;/span&gt;&lt;span class="o"&gt;},&lt;/span&gt;
        &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"user2"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"wrongpass"&lt;/span&gt;&lt;span class="o"&gt;},&lt;/span&gt;
        &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"admin"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"adminpass"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;};&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;@Test&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dataProvider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"loginData"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;testLogin&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// login logic using username and password&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Integrating TestNG with Selenium
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;TestNG and Selenium work together beautifully: Selenium handles the browser interaction, while TestNG manages test structure, execution order, grouping, and reporting.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LoginTest&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nc"&gt;WebDriver&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@BeforeMethod&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setUp&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;driver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ChromeDriver&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://example.com/login"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;testValidLogin&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findElement&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;By&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"username"&lt;/span&gt;&lt;span class="o"&gt;)).&lt;/span&gt;&lt;span class="na"&gt;sendKeys&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"testuser"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findElement&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;By&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="o"&gt;)).&lt;/span&gt;&lt;span class="na"&gt;sendKeys&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"password123"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findElement&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;By&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"loginBtn"&lt;/span&gt;&lt;span class="o"&gt;)).&lt;/span&gt;&lt;span class="na"&gt;click&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;currentUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getCurrentUrl&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;Assert&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;assertTrue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;currentUrl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"dashboard"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@AfterMethod&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;tearDown&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;quit&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;This structure — Selenium for browser control, TestNG for test orchestration — is one of the most common combinations used in real-world automation frameworks.&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Creating and Executing Automated Test Scripts
&lt;/h3&gt;

&lt;p&gt;Bringing everything together, here's a practical step-by-step approach to building your first automated test script:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Set up your project&lt;/strong&gt; — Use Maven or Gradle to manage dependencies (Selenium WebDriver, TestNG/JUnit).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add browser drivers&lt;/strong&gt; — Download the correct WebDriver (e.g., ChromeDriver) matching your browser version, or use a driver manager library to handle this automatically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write the test class&lt;/strong&gt; — Structure your test using annotations (&lt;code&gt;@BeforeMethod&lt;/code&gt;, &lt;code&gt;@Test&lt;/code&gt;, &lt;code&gt;@AfterMethod&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Locate web elements&lt;/strong&gt; — Use locators like &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;className&lt;/code&gt;, &lt;code&gt;cssSelector&lt;/code&gt;, or &lt;code&gt;xpath&lt;/code&gt; to find elements on the page.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Perform actions and assertions&lt;/strong&gt; — Simulate user actions (click, type, select) and verify results using assertions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run the tests&lt;/strong&gt; — Execute via IDE, build tool command, or CI/CD pipeline.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Review reports&lt;/strong&gt; — Check TestNG/JUnit-generated reports to identify passed, failed, or skipped tests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintain and refactor&lt;/strong&gt; — As the application changes, update locators and test logic to keep scripts reliable.&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Wrapping Up
&lt;/h3&gt;

&lt;p&gt;_Test automation isn't about replacing manual testers — it's about freeing them from repetitive work so they can focus on exploratory testing, usability, and edge cases that truly need human judgment. _&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Selenium&lt;/strong&gt; gives you the power to automate real browser interactions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JUnit&lt;/strong&gt; provides a solid, simple foundation for writing and running Java tests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TestNG&lt;/strong&gt; builds on that foundation with more advanced features like grouping, parallel execution, and data-driven testing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Together, these tools form the backbone of most Java-based test automation frameworks used in the industry today. Mastering them is a genuinely valuable skill — whether you're a student building your first automation project or a developer setting up a CI/CD testing pipeline.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>software</category>
      <category>performance</category>
      <category>testing</category>
      <category>selenium</category>
    </item>
    <item>
      <title>A Beginner's Guide to Starting with HTML, CSS, and JavaScript</title>
      <dc:creator>Bhadra Mohit</dc:creator>
      <pubDate>Sat, 29 Aug 2026 08:21:21 +0000</pubDate>
      <link>https://dev.to/bhadramohit/a-beginners-guide-to-starting-with-html-css-and-javascript-2paj</link>
      <guid>https://dev.to/bhadramohit/a-beginners-guide-to-starting-with-html-css-and-javascript-2paj</guid>
      <description>&lt;h3&gt;
  
  
  Everything you need to go from a blank text editor to a working, useful webpage
&lt;/h3&gt;




&lt;p&gt;Every website you've ever visited — no matter how complex — is built on three foundations: HTML, CSS, and JavaScript. Frameworks and libraries sit on top of these three; they don't replace them. This guide goes deep into each one individually, then walks through building a genuinely useful project — a personal task tracker — combining everything you've learned.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Grab a text editor (VS Code is the standard choice, free, and works on every OS) and a browser. That's the entire toolchain required for everything below.&lt;/em&gt;&lt;/p&gt;






&lt;h2&gt;
  
  
  Part 1: HTML — Structure
&lt;/h2&gt;

&lt;p&gt;HTML (HyperText Markup Language) describes what exists on a page. It isn't a programming language — there's no logic, no calculations — just structure, expressed through &lt;strong&gt;tags&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  1.1 Anatomy of an HTML Document
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;My First Page&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Welcome to My Website&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;This is my first paragraph.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Breaking this down line by line:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/code&gt; — tells the browser this is a modern HTML5 document. Always the first line, always exactly this.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;html lang="en"&amp;gt;&lt;/code&gt; — the root element wrapping everything; the &lt;code&gt;lang&lt;/code&gt; attribute helps screen readers and search engines.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; — metadata that isn't visible on the page itself: character encoding, the page title (shown in the browser tab), linked CSS/JS files, and SEO tags.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;meta name="viewport"...&amp;gt;&lt;/code&gt; — without this line, your page won't resize properly on mobile devices. It's easy to forget and causes real problems later — include it in every project from day one.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; — everything the user actually sees goes here.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1.2 Tags, Elements, and Attributes
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;tag&lt;/strong&gt; is the markup itself (&lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt;). An &lt;strong&gt;element&lt;/strong&gt; is the tag plus its content and closing tag (&lt;code&gt;&amp;lt;p&amp;gt;Hello&amp;lt;/p&amp;gt;&lt;/code&gt;). An &lt;strong&gt;attribute&lt;/strong&gt; provides extra information inside the opening tag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://example.com"&lt;/span&gt; &lt;span class="na"&gt;target=&lt;/span&gt;&lt;span class="s"&gt;"_blank"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Visit Example&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, &lt;code&gt;href&lt;/code&gt; and &lt;code&gt;target&lt;/code&gt; are attributes — &lt;code&gt;href&lt;/code&gt; sets the link destination, &lt;code&gt;target="_blank"&lt;/code&gt; opens it in a new tab.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Most tags come in pairs (&lt;code&gt;&amp;lt;p&amp;gt;...&amp;lt;/p&amp;gt;&lt;/code&gt;). A handful are &lt;strong&gt;self-closing&lt;/strong&gt; because they don't wrap content: &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;br&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;meta&amp;gt;&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1.3 The Essential Tags
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Tags&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Text&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt;–&lt;code&gt;&amp;lt;h6&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;strong&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;em&amp;gt;&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Headings, paragraphs, inline emphasis&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Structure&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;header&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;main&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;section&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;footer&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;nav&amp;gt;&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Grouping and page layout regions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lists&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;&amp;lt;ul&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;ol&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Unordered/ordered lists&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Links &amp;amp; media&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Navigation and embedded content&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Forms&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;textarea&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;select&amp;gt;&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Collecting user input&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tables&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;&amp;lt;table&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;tr&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;td&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;th&amp;gt;&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Tabular data (not for layout)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A note on &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; versus the semantic tags (&lt;code&gt;&amp;lt;header&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;main&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;section&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;footer&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;nav&amp;gt;&lt;/code&gt;): a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; carries no meaning — it's a generic box. The semantic tags describe &lt;em&gt;what&lt;/em&gt; a section of the page actually is, which helps accessibility tools, search engines, and other developers (including future you) understand the page's structure at a glance. Prefer semantic tags where one fits; fall back to &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; for anything generic.&lt;/p&gt;

&lt;h3&gt;
  
  
  1.4 Forms — Where Most Real Interactivity Starts
&lt;/h3&gt;

&lt;p&gt;Almost every useful webpage eventually needs to collect input. A basic form looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;form&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"taskInput"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;New Task:&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"taskInput"&lt;/span&gt; &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"Enter a task..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Add&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;label for="taskInput"&amp;gt;&lt;/code&gt; links to the &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; with the matching &lt;code&gt;id&lt;/code&gt; — clicking the label focuses the input, and it's important for accessibility.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;type="text"&lt;/code&gt; is one of many input types (&lt;code&gt;email&lt;/code&gt;, &lt;code&gt;number&lt;/code&gt;, &lt;code&gt;checkbox&lt;/code&gt;, &lt;code&gt;date&lt;/code&gt;, &lt;code&gt;password&lt;/code&gt; all change behavior and mobile keyboard layout).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;button type="submit"&amp;gt;&lt;/code&gt; submits the form by default; you'll often override this behavior with JavaScript, which we'll do in the project below.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1.5 Practicing HTML Alone
&lt;/h3&gt;

&lt;p&gt;Before adding any CSS or JS, build a static page with: a heading, a short bio paragraph, a list of three hobbies, a link to another site, and an image. This forces you to use headings, paragraphs, lists, links, and images without anything else to lean on — the fastest way to get comfortable with structure before layering on style and behavior.&lt;/p&gt;






&lt;h2&gt;
  
  
  Part 2: CSS — Style
&lt;/h2&gt;

&lt;p&gt;CSS (Cascading Style Sheets) controls appearance: color, spacing, fonts, sizing, and layout.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.1 Three Ways to Add CSS
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- 1. Inline (avoid except for quick testing) --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"color: blue;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Text&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- 2. Internal (fine for small pages) --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- 3. External (the standard for real projects) --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"style.css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;_&lt;br&gt;
External stylesheets keep structure and style separate, which matters the moment your project grows past a single page._&lt;/p&gt;
&lt;h3&gt;
  
  
  2.2 Selectors
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#333&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;                 &lt;span class="c"&gt;/* every &amp;lt;p&amp;gt; */&lt;/span&gt;
&lt;span class="nc"&gt;.highlight&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;yellow&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c"&gt;/* any element with class="highlight" */&lt;/span&gt;
&lt;span class="nf"&gt;#main-title&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;   &lt;span class="c"&gt;/* the one element with id="main-title" */&lt;/span&gt;
&lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="nt"&gt;h2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;  &lt;span class="c"&gt;/* an &amp;lt;h2&amp;gt; inside an element with class="card" */&lt;/span&gt;
&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;     &lt;span class="c"&gt;/* a button, only while hovered */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Classes vs IDs:&lt;/strong&gt; use classes (&lt;code&gt;.classname&lt;/code&gt;) for anything reused across multiple elements, and IDs (&lt;code&gt;#idname&lt;/code&gt;) only for a single, unique element per page — often one you'll also target from JavaScript.&lt;/p&gt;
&lt;h3&gt;
  
  
  2.3 The Box Model
&lt;/h3&gt;

&lt;p&gt;Every HTML element is a rectangular box made of four layers, from the inside out:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────┐
│           margin             │
│  ┌─────────────────────────┐ │
│  │         border           │ │
│  │  ┌─────────────────────┐ │ │
│  │  │       padding         │ │ │
│  │  │  ┌─────────────────┐ │ │ │
│  │  │  │     content     │ │ │ │
│  │  │  └─────────────────┘ │ │ │
│  │  └─────────────────────┘ │ │
│  └─────────────────────────┘ │
└─────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.box&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;200px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;      &lt;span class="c"&gt;/* space inside the border */&lt;/span&gt;
    &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#333&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;        &lt;span class="c"&gt;/* space outside the border */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default, &lt;code&gt;width&lt;/code&gt; only sets the &lt;em&gt;content&lt;/em&gt; width — padding and border add on top, which trips up nearly every beginner at some point. Fix it globally with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;box-sizing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;border-box&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;This makes &lt;code&gt;width&lt;/code&gt; include padding and border, so a &lt;code&gt;200px&lt;/code&gt; box stays &lt;code&gt;200px&lt;/code&gt; no matter how much padding you add. Add this at the top of every project.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2.4 Flexbox — Modern Layout in a Few Lines
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;space-between&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* horizontal alignment */&lt;/span&gt;
    &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;             &lt;span class="c"&gt;/* vertical alignment */&lt;/span&gt;
    &lt;span class="py"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;                       &lt;span class="c"&gt;/* space between children */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;display: flex&lt;/code&gt; turns a container into a flex container — its direct children automatically line up in a row (by default) and can be aligned, spaced, and reordered without floats or manual positioning. This single property replaces most of the layout hacks that used to dominate CSS.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.5 Responsive Design With Media Queries
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;600px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Media queries apply CSS conditionally based on screen size — here, stacking a row layout into a column on small screens. Combined with the viewport &lt;code&gt;&amp;lt;meta&amp;gt;&lt;/code&gt; tag from Part 1, this is the foundation of mobile-friendly design.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2.6 Practicing CSS Alone
&lt;/h3&gt;

&lt;p&gt;Take the static page you built in Part 1 and style it: add a background color, style the heading with a custom font size and color, put the hobbies list items in a flex row with spacing between them, and add a hover effect on the link. No JavaScript yet — the goal is getting comfortable translating a visual idea into CSS properties.&lt;/p&gt;






&lt;h2&gt;
  
  
  Part 3: JavaScript — Behavior
&lt;/h2&gt;

&lt;p&gt;JavaScript is a real programming language — variables, functions, conditionals, and loops all apply, on top of the ability to read and change the page itself.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.1 Variables
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;          &lt;span class="c1"&gt;// can be reassigned later&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Mohit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;// cannot be reassigned&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use &lt;code&gt;const&lt;/code&gt; by default, and &lt;code&gt;let&lt;/code&gt; only when you know the value will change. Avoid &lt;code&gt;var&lt;/code&gt; — it behaves inconsistently compared to &lt;code&gt;let&lt;/code&gt; and &lt;code&gt;const&lt;/code&gt; and has no place in modern code.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.2 Functions
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`Hello, &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;!`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;greetArrow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`Hello, &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;!`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// arrow function, same result&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Functions group reusable logic. Arrow functions are a shorter syntax you'll see constantly in modern JavaScript and in every framework built on top of it.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.3 Conditionals and Loops
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hour&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hour&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Good morning&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hour&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Good afternoon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Good evening&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tasks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Buy milk&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Walk the dog&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Write blog post&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;task&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.4 The DOM — JavaScript's View of Your HTML
&lt;/h3&gt;

&lt;p&gt;The DOM (Document Object Model) is how JavaScript sees your page: not as text, but as a tree of objects it can read and modify live.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;h1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;          &lt;span class="c1"&gt;// first matching element&lt;/span&gt;
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.item&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;    &lt;span class="c1"&gt;// all matching elements (a list)&lt;/span&gt;
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;main-title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// element with that exact id&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you have an element, you can read or change it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;heading&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;h1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;heading&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Updated Heading&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;// change the text&lt;/span&gt;
&lt;span class="nx"&gt;heading&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;blue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;              &lt;span class="c1"&gt;// change a style directly&lt;/span&gt;
&lt;span class="nx"&gt;heading&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;highlight&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;        &lt;span class="c1"&gt;// add a CSS class&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.5 Events — Responding to the User
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Button was clicked!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;addEventListener&lt;/code&gt; is the core pattern of interactive JavaScript: pick an element, pick an event (&lt;code&gt;click&lt;/code&gt;, &lt;code&gt;submit&lt;/code&gt;, &lt;code&gt;keydown&lt;/code&gt;, &lt;code&gt;input&lt;/code&gt;, &lt;code&gt;change&lt;/code&gt;), and provide a function to run when it happens.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.6 Arrays and Common Array Methods
&lt;/h3&gt;

&lt;p&gt;Most real UI work involves lists of things — tasks, products, comments — stored as arrays:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tasks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Buy milk&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Walk the dog&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="nx"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Write blog post&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;     &lt;span class="c1"&gt;// add to the end&lt;/span&gt;
&lt;span class="nx"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;splice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;                 &lt;span class="c1"&gt;// remove 1 item at index 1&lt;/span&gt;

&lt;span class="nx"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// run code for each item&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;upper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// transform each item into a new array&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;forEach&lt;/code&gt; and &lt;code&gt;map&lt;/code&gt; will come up constantly once you start rendering lists of data onto a page — they're worth being genuinely comfortable with before moving on.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.7 Practicing JavaScript Alone
&lt;/h3&gt;

&lt;p&gt;Using the page from Parts 1 and 2, add a button that, when clicked, changes the heading's text and background color. Then add a second button that adds a new item to your hobbies list. This is deliberately close to what real UI code does constantly: respond to a click, then update the DOM.&lt;/p&gt;






&lt;h2&gt;
  
  
  Part 4: The Project — A Task Tracker
&lt;/h2&gt;

&lt;p&gt;Time to combine everything into something genuinely useful: a task tracker that lets you add tasks, mark them complete, delete them, and see a live count — all saved so it doesn't disappear on refresh.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.1 The HTML
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;My Task Tracker&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"style.css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"app"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Task Tracker&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"taskForm"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"taskInput"&lt;/span&gt; &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"Add a new task..."&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Add&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"taskCount"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;0 tasks remaining&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"taskList"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"script.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.2 The CSS
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;box-sizing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;border-box&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;'Segoe UI'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Arial&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;sans-serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#f4f6f8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;padding-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;40px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.app&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;30px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;400px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#2c3e50&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;#taskForm&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;12px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;#taskInput&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#ccc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;14px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#3498db&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;14px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#2980b9&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;#taskCount&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#7f8c8d&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;14px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;#taskList&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;list-style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.task-item&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;space-between&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#eee&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.task-item&lt;/span&gt; &lt;span class="nt"&gt;span&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.task-item.completed&lt;/span&gt; &lt;span class="nt"&gt;span&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;text-decoration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;line-through&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#aaa&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.delete-btn&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#e74c3c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;12px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.delete-btn&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#c0392b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.3 The JavaScript
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;taskForm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;taskForm&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;taskInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;taskInput&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;taskList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;taskList&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;taskCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;taskCount&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Load saved tasks, or start with an empty list&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;tasks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tasks&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;saveTasks&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tasks&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;updateCount&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;remaining&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;completed&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;taskCount&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;remaining&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; task&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;remaining&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;s&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; remaining`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;renderTasks&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;taskList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nx"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;li&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;li&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;li&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;task-item&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;completed&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; completed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;span&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;span&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;toggleComplete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;deleteBtn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;deleteBtn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Delete&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;deleteBtn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;delete-btn&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;deleteBtn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;deleteTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

        &lt;span class="nx"&gt;li&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;li&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deleteBtn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;taskList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nf"&gt;updateCount&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;addTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;completed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nf"&gt;saveTasks&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nf"&gt;renderTasks&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;toggleComplete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;completed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;completed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;saveTasks&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nf"&gt;renderTasks&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;deleteTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;splice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;saveTasks&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nf"&gt;renderTasks&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;taskForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;submit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// stop the page from reloading on submit&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;taskInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nf"&gt;addTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;taskInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nf"&gt;renderTasks&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// render whatever was loaded from storage on page load&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.4 How This All Fits Together
&lt;/h3&gt;

&lt;p&gt;Walking through what happens when you use this app ties every earlier section together:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;On page load&lt;/strong&gt;, JavaScript checks &lt;code&gt;localStorage&lt;/code&gt; for previously saved tasks and renders them — this is why refreshing the page doesn't wipe your list.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Typing and submitting the form&lt;/strong&gt; triggers the &lt;code&gt;submit&lt;/code&gt; event listener. &lt;code&gt;event.preventDefault()&lt;/code&gt; stops the browser's default behavior (reloading the page), which is essential — without it, every submission would refresh and lose your JavaScript state.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;addTask&lt;/code&gt;&lt;/strong&gt; pushes a new object into the &lt;code&gt;tasks&lt;/code&gt; array, saves the whole array to &lt;code&gt;localStorage&lt;/code&gt; as a JSON string, and calls &lt;code&gt;renderTasks()&lt;/code&gt; to redraw the list.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;renderTasks&lt;/code&gt;&lt;/strong&gt; clears the existing list and rebuilds it from scratch using &lt;code&gt;forEach&lt;/code&gt;, creating real DOM elements (&lt;code&gt;createElement&lt;/code&gt;) for each task rather than writing raw HTML strings — a safer, more standard approach.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clicking a task's text&lt;/strong&gt; calls &lt;code&gt;toggleComplete&lt;/code&gt;, flipping its &lt;code&gt;completed&lt;/code&gt; flag, which the CSS then reflects instantly (&lt;code&gt;.completed span&lt;/code&gt; gets a strikethrough) because &lt;code&gt;renderTasks&lt;/code&gt; re-applies the &lt;code&gt;completed&lt;/code&gt; class.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clicking Delete&lt;/strong&gt; calls &lt;code&gt;deleteTask&lt;/code&gt;, which uses &lt;code&gt;splice&lt;/code&gt; to remove that one item from the array before re-rendering.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Every concept from Parts 1–3 shows up here: semantic HTML and a form (Part 1), Flexbox and the box model for layout (Part 2), and DOM manipulation, events, arrays, and functions tying it all together (Part 3).&lt;/p&gt;



&lt;h3&gt;
  
  
  What to Build Next
&lt;/h3&gt;

&lt;p&gt;Once this project makes sense end-to-end, natural next steps that build on the same patterns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add an "edit task" feature (click a task to turn it into an editable input)&lt;/li&gt;
&lt;li&gt;Add categories or priority levels with different colors&lt;/li&gt;
&lt;li&gt;Add a "clear completed" button&lt;/li&gt;
&lt;li&gt;Fetch a real to-do list from a public API instead of starting empty&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Each of these reuses the exact same core loop — read the DOM, update an array, re-render, save — which is, not coincidentally, the same core loop every JavaScript framework (React included) is built to manage for you automatically once your projects grow large enough to need it.&lt;/em&gt;&lt;/p&gt;



&lt;h3&gt;
  
  
  Final Thoughts
&lt;/h3&gt;

&lt;p&gt;HTML, CSS, and JavaScript aren't a "beginner phase" to rush past on the way to frameworks — they're the actual foundation everything else sits on. The task tracker above is intentionally simple, but it's a genuinely complete, working, useful piece of software: it takes input, stores data, updates the interface, and persists state across page reloads. That's the same fundamental loop behind almost every web application you'll ever build, no matter how much more complex the tools around it eventually get.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Save the three files, open &lt;code&gt;index.html&lt;/code&gt; in your browser, and you have a working app — built entirely from the ground up.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
      <category>education</category>
    </item>
  </channel>
</rss>
