Try the finished version right now
This is fully working JavaScript, live on this page:
Building it step by step
Store tasks in an array
let tasks = []; โ an empty array that will hold every task as a simple string, or an object if you want to track "done" status per task.
Write an addTask function
Grabs the input's value, pushes it into the array, clears the input, and re-renders the list.
Write a render function
Clears the <ul>, then loops through the array with .forEach(), creating a new <li> for each task.
Wire up the button
addEventListener("click", addTask) on the Add button, calling everything above.
Add a delete button per task
Each rendered <li> gets its own delete button, removing that specific task from the array and re-rendering.
createElement and appendChild build new HTML elements directly from JavaScript, safely โ this is the preferred alternative to innerHTML when you're inserting dynamic content, since it avoids the security risk mentioned in Lesson 4.
Build it yourself
index.html, typing every line yourself instead of copy-pasting. Once it works, extend it: add a "mark as complete" button that adds a done CSS class (strikethrough text) instead of deleting the task โ you already have every tool needed from Lessons 1-5 to do this on your own.
What you actually just learned
- Storing changing data in an array (
tasks) - Functions that do one clear job each (
addTask,render) - Looping through data to build UI dynamically (
.forEach) - Responding to real user actions (
addEventListener) - Safely creating and removing elements (
createElement,appendChild)
This exact pattern โ data in an array, a render function, events triggering updates โ is the conceptual foundation behind every modern JavaScript framework (React, Vue, and the rest). You just built a simplified version of it by hand.