← Back to Tutorials Chapter 13

Projects

Building real projects is the best way to solidify your JavaScript skills. This chapter presents five mini-project ideas and walks through the development of a complete to-do list application.

Mini Project Ideas

1. To-Do List

A classic CRUD application. Users can add, complete, and delete tasks. Persist tasks with localStorage. Filter by all / active / completed.

2. Calculator

Build a four-function calculator with a clean UI. Handle chained operations, decimal points, and keyboard input. Display the current expression and result.

3. Weather App

Use the Fetch API to call a free weather API (e.g., OpenWeatherMap). Show temperature, humidity, conditions, and a forecast. Add an input field to search by city name.

4. Quiz Game

A multiple-choice quiz that tracks the score and shows progress. Fetch questions from an API or use a static array. Include a timer and a final results screen.

5. Countdown Timer

Let users set a timer with hours, minutes, and seconds. Display a countdown that updates every second. Play a sound or show an alert when time runs out.

JavaScript project examples

Walkthrough: To-Do List App

We will build a complete to-do list step by step. The final app will use localStorage for persistence and include add / delete / toggle-complete functionality.

HTML Structure

<div id="app">
  <h1>To-Do List</h1>
  <input id="taskInput" type="text" placeholder="Add a task...">
  <button id="addBtn">Add</button>
  <ul id="taskList"></ul>
  <div id="filters">
    <button data-filter="all" class="active">All</button>
    <button data-filter="active">Active</button>
    <button data-filter="completed">Completed</button>
  </div>
</div>

JavaScript Logic

const taskInput = document.getElementById('taskInput');
const addBtn = document.getElementById('addBtn');
const taskList = document.getElementById('taskList');

let tasks = JSON.parse(localStorage.getItem('tasks')) || [];
let filter = 'all';

function saveAndRender() {
  localStorage.setItem('tasks', JSON.stringify(tasks));
  render();
}

function render() {
  const filtered = tasks.filter(t => {
    if (filter === 'active') return !t.completed;
    if (filter === 'completed') return t.completed;
    return true;
  });

  taskList.innerHTML = filtered.map((t, i) => `
    <li class="${t.completed ? 'done' : ''}">
      <input type="checkbox" ${t.completed ? 'checked' : ''} data-index="${i}">
      <span>${t.text}</span>
      <button data-index="${i}" class="delete">&times;</button>
    </li>
  `).join('');
}

addBtn.addEventListener('click', () => {
  const text = taskInput.value.trim();
  if (text) {
    tasks.push({ text, completed: false });
    taskInput.value = '';
    saveAndRender();
  }
});

taskList.addEventListener('click', e => {
  if (e.target.classList.contains('delete')) {
    tasks.splice(+e.target.dataset.index, 1);
    saveAndRender();
  }
});

taskList.addEventListener('change', e => {
  if (e.target.type === 'checkbox') {
    tasks[+e.target.dataset.index].completed = e.target.checked;
    saveAndRender();
  }
});

document.getElementById('filters').addEventListener('click', e => {
  if (e.target.dataset.filter) {
    filter = e.target.dataset.filter;
    document.querySelectorAll('#filters button').forEach(b => b.classList.remove('active'));
    e.target.classList.add('active');
    render();
  }
});

render();
Tip: Use data-* attributes to store metadata directly in HTML elements. They are accessed via the dataset property and are valid HTML5.

Using Online Code Editors

Platforms like CodePen, JSFiddle, and CodeSandbox let you write HTML, CSS, and JavaScript in the browser and see results instantly. They are great for prototyping, sharing snippets, and experimenting.

Project Structure Tips

Exercise: Build the Quiz Game

Implement the quiz game project. Create an array of at least 5 question objects with question, options (array of 4 strings), and correctAnswer (index). Display one question at a time, highlight the correct/wrong answer after selection, move to the next question, and display the final score. Add a restart button.