Counter with innerHTML

Let’s build the exact same counter, but this time using innerHTML with template strings instead of the DOM API.

Rewriting with innerHTML

Replace the contents of src/main.js with the following (the HTML, CSS, and dev server stay the same):

import "./styles.css";

const app = document.getElementById("app");

// Set up the layout using innerHTML
app.innerHTML = `
  <div class="counter">
    <h1 id="display">Count: 0</h1>
    <button id="increment">+</button>
    <button id="decrement">&minus;</button>
    <button id="reset">Reset</button>
  </div>
`;

// Get references to elements
const display = document.getElementById("display");
const incrementBtn = document.getElementById("increment");
const decrementBtn = document.getElementById("decrement");
const resetBtn = document.getElementById("reset");

// State and update function
let count = 0;

function updateCounter() {
  display.textContent = "Count: " + count;
}

// Event listeners
incrementBtn.addEventListener("click", () => {
  count++;
  updateCounter();
});

decrementBtn.addEventListener("click", () => {
  count--;
  updateCounter();
});

resetBtn.addEventListener("click", () => {
  count = 0;
  updateCounter();
});

Refresh the browser. The counter works exactly the same.

Comparing the Two Approaches

The innerHTML version is much more readable. But it has its own downsides:

  • DOM API (createElement / appendChild): Safe and structured, but verbose. You have to create each element, set its properties, and manually wire everything together. It is hard to see what the UI looks like by reading the code.

  • innerHTML (template strings): Concise and readable. The HTML structure is right there in the string. But there is no validation. A typo in your HTML (a missing closing tag, a misspelled attribute) is a silent bug. You also need to query the DOM with getElementById to get references to elements for event handling.

So what we want is a syntax that reads like HTML but still gives us the safety and the power of JavaScript.

Checkpoint: Commit your progress.

git add .
git commit -m "counter-02: Rewrite counter with innerHTML"