---
title: How to Build Your First Interactive To-Do List with Vanilla JavaScript
siteUrl: https://logzly.com/jsbeginnerhub
author: jsbeginnerhub (JS Beginner Hub)
date: 2026-06-22T10:05:46.068968
tags: [javascript, frontend, tutorial]
url: https://logzly.com/jsbeginnerhub/how-to-build-your-first-interactive-to-do-list-with-vanilla-javascript
---


Ever opened a new tab and thought, “I need a simple place to jot down today’s tasks, but I don’t want to sign up for another app?” That moment is why a tiny to‑do list built with plain JavaScript is a perfect first project. It teaches you the basics of the DOM, events, and state without any heavy frameworks. Let’s get that list up and running, step by step.

## What You’ll Need

Before we dive in, make sure you have:

* A text editor (VS Code, Sublime, or even Notepad will do)
* A modern web browser (Chrome, Firefox, Edge, etc.)
* A blank folder for the project

That’s it—no npm, no build tools, just the browser and a few files.

## Setting Up the Files

Create three files in your project folder:

1. `index.html` – the page structure
2. `styles.css` – a little styling to make it look nice
3. `app.js` – the JavaScript that will make the list interactive

### index.html

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>My First To‑Do List</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <div class="container">
    <h1>My To‑Do List</h1>
    <input type="text" id="new-task" placeholder="Add a new task...">
    <button id="add-btn">Add</button>
    <ul id="task-list"></ul>
  </div>
  <script src="app.js"></script>
</body>
</html>
```

A quick note: the `<ul>` element will hold each task as a list item (`<li>`). We give it an id so JavaScript can find it later.

### styles.css

```css
body {
  font-family: Arial, sans-serif;
  background: #f9f9f9;
  margin: 0;
  padding: 20px;
}
.container {
  max-width: 400px;
  margin: auto;
  background: #fff;
  padding: 20px;
  box-shadow: 0 0 10px rgba(0,0,0,0.1);
}
input, button {
  padding: 8px;
  margin: 5px 0;
}
li {
  display: flex;
  justify-content: space-between;
  padding: 5px 0;
}
.completed {
  text-decoration: line-through;
  color: #777;
}
```

Nothing fancy—just enough to keep the list readable. Feel free to tweak colors later.

## Writing the JavaScript

Open `app.js`. We’ll break the code into small, understandable chunks.

### Grab the Elements

```js
const input = document.getElementById('new-task');
const addBtn = document.getElementById('add-btn');
const taskList = document.getElementById('task-list');
```

`document.getElementById` is a DOM method that finds an element by its id attribute. Think of the DOM as the page’s tree of elements; we’re just picking the branches we need.

### Add a New Task

```js
function addTask() {
  const taskText = input.value.trim();
  if (taskText === '') return; // ignore empty input

  const li = document.createElement('li');

  const span = document.createElement('span');
  span.textContent = taskText;

  const deleteBtn = document.createElement('button');
  deleteBtn.textContent = '✖';
  deleteBtn.className = 'delete';

  li.appendChild(span);
  li.appendChild(deleteBtn);
  taskList.appendChild(li);

  input.value = '';
}
```

* `trim()` removes extra spaces at the start or end.
* `createElement` builds a new HTML element that we can later attach to the page.
* We add a delete button (the little “✖”) so each item can be removed.

### Hook Up the Add Button

```js
addBtn.addEventListener('click', addTask);
```

`addEventListener` tells the browser, “When this button is clicked, run the `addTask` function.” This is the core of interactivity.

### Make Tasks Clickable

We want two more interactions:

1. Clicking the text toggles a “completed” style.
2. Clicking the delete button removes the item.

```js
taskList.addEventListener('click', function(e) {
  const target = e.target;

  // If the user clicked the delete button
  if (target.classList.contains('delete')) {
    const li = target.parentElement;
    taskList.removeChild(li);
    return;
  }

  // If the user clicked the task text
  if (target.tagName === 'SPAN') {
    target.classList.toggle('completed');
  }
});
```

Why attach the listener to `taskList` instead of each `<li>`? Because the list may grow after the page loads. This technique, called **event delegation**, lets one listener handle many future items. It keeps the code simple and fast.

### Optional: Add “Enter” Key Support

```js
input.addEventListener('keypress', function(e) {
  if (e.key === 'Enter') {
    addTask();
  }
});
```

Now you can type a task and press Enter—no need to click the button.

## Test It Out

Open `index.html` in your browser. Try adding a few tasks, marking them as done, and deleting some. If everything works, congratulations! You just built a functional interactive app with only vanilla JavaScript.

## What Did We Learn?

* **DOM manipulation** – creating elements, setting text, and appending them.
* **Event handling** – listening for clicks and key presses.
* **State management** – the list itself is the state; we update it directly.
* **Event delegation** – a single listener can manage many dynamic items.

These are the building blocks for any web app. Once you’re comfortable here, you can start adding features like local storage (so the list persists after a page reload) or drag‑and‑drop reordering.

## A Little Personal Note

When I first started coding, I built a to‑do list that only let me add items. I spent a whole afternoon debugging why the delete button didn’t work—turns out I forgot to stop the click event from bubbling up. That little hiccup taught me the value of reading the console and stepping through code line by line. If you hit a snag, open the browser’s developer tools (F12) and watch the console. It’s like a friendly detective that tells you exactly where things went wrong.

## Next Steps

* **Persist data** – use `localStorage.setItem` and `localStorage.getItem` to save the list.
* **Add edit mode** – let users double‑click a task to change its text.
* **Style it up** – experiment with CSS variables or a light/dark theme toggle.

The sky’s the limit, but the best way to learn is by building. Keep tweaking, keep testing, and soon you’ll be comfortable adding more complex logic to your projects.

Happy coding from JS Beginner Hub!  