Skip to content

JavaScript Tutorial Practical Projects

Project 1: A Counter

Lesson 240 of 258 2 min read By Deepak Paswan Updated Oct 4, 2026

Your first project is small on purpose: a number you can increase, decrease and reset. It uses variables, functions, events and the DOM, the core of everything else.

What you will build

A counter with three buttons. It never goes below zero, and the page tells screen readers when the number changes.

index.html
HTML
<style>
  .counter { font-family: system-ui, sans-serif; text-align: center; max-width: 260px; margin: 0 auto; }
  .value { font-size: 56px; font-weight: 700; margin: 8px 0; }
  button { font: inherit; padding: 8px 16px; margin: 0 4px; border-radius: 6px; border: 2px solid #1a5276; background: #fff; cursor: pointer; }
  button:hover { background: #1a5276; color: #fff; }
  button:focus-visible { outline: 3px solid #d94a00; outline-offset: 2px; }
  button:disabled { opacity: .4; cursor: not-allowed; }
</style>

<div class="counter">
  <div class="value" id="value" role="status" aria-live="polite">0</div>
  <button id="down" aria-label="Decrease">−</button>
  <button id="reset">Reset</button>
  <button id="up" aria-label="Increase">+</button>
</div>

<script>
  let count = 0;

  const valueEl = document.querySelector("#value");
  const downBtn = document.querySelector("#down");

  function render() {
    valueEl.textContent = count;
    downBtn.disabled = count === 0;      // cannot go below zero
  }

  document.querySelector("#up").addEventListener("click", () => { count++; render(); });
  downBtn.addEventListener("click", () => { if (count > 0) { count--; render(); } });
  document.querySelector("#reset").addEventListener("click", () => { count = 0; render(); });

  render();
</script>

How it works

  • State: one variable, count, is the single source of truth.
  • render() updates the page from the state. Every button changes count and then calls render(). Keeping that rule makes the page and the data impossible to get out of sync.
  • The minus button is disabled at zero, a clearer experience than an error.
  • aria-live="polite" announces changes to screen readers, and the buttons have text labels (aria-label) because “−” and “+” are not meaningful alone.

Try changing it

  1. Add a step input so the buttons add 5 or 10.
  2. Add a maximum of 10 and disable the plus button there.
  3. Save the count with localStorage so it survives a reload (localStorage).
  4. Make the number turn red below 3 using a class (classList).

Exercise: keyboard shortcuts

Make the counter respond to the keys ArrowUp (increase), ArrowDown (decrease) and 0 (reset), without breaking the buttons.

Show a possible solution
script.js
JS
document.addEventListener("keydown", event => {
  if (event.key === "ArrowUp") { count++; render(); }
  else if (event.key === "ArrowDown" && count > 0) { count--; render(); }
  else if (event.key === "0") { count = 0; render(); }
});

Add this inside the script after render() is defined. See Keyboard Events.