Crea una app de tareas sencilla paso a paso (lenguaje claro)
Guía clara y paso a paso para crear una pequeña app de tareas: planifica las funciones, crea las pantallas, añade la lógica, guarda los datos, prueba y publica.

Qué vamos a construir (y qué aprenderás)
Cuando digo “app” en esta guía, me refiero a una pequeña aplicación web: una sola página que abres en un navegador y que responde a lo que haces al hacer clic y escribir. Sin instalaciones, sin cuentas, sin configuraciones pesadas: solo un proyecto sencillo que puedes ejecutar localmente.
El objetivo (qué hará la app al final)
Al terminar, tendrás una app de tareas que puede:
- Añadir tareas desde un cuadro de entrada
- Marcar tareas como hechas (para ver lo completado)
- Borrar tareas que ya no necesitas
- Mantener las tareas después de refrescar usando
localStorage(para que cerrar la pestaña no borre todo)
No será perfecta ni “para empresas”, y esa es la idea. Es un proyecto para principiantes diseñado para enseñar lo básico sin lanzar muchas herramientas al mismo tiempo.
Qué aprenderás (en lenguaje claro)
Construirás la app paso a paso y aprenderás las piezas centrales de cómo funcionan las aplicaciones front-end:
- HTML para crear la estructura de la página (entrada, botón, lista)
- CSS para que sea legible y agradable de usar
- JavaScript para manejar clics, crear elementos de lista y actualizar la página
- localStorage para guardar y cargar tareas y que permanezcan
- Pruebas y depuración básicas (detectar errores pequeños y corregirlos)
Qué necesitas antes de empezar
Manténlo simple. Solo necesitas:
- Un ordenador (Windows, Mac o Linux)
- Un navegador moderno (Chrome, Firefox, Safari o Edge)
- Un editor de código (VS Code es popular, pero cualquier editor sirve)
Si puedes crear una carpeta y editar algunos archivos, estás listo.
Paso 1: Decide el objetivo y las funciones de la app
Antes de escribir código, decide cómo se verá el “éxito”. Este tutorial construye una app pequeña con una sola función clara: ayudarte a seguir tareas que quieres hacer.
Elige la única función de la app
Escribe una frase que puedas tener presente mientras construyes:
“Esta app me permite añadir tareas a una lista para no olvidarlas.”
Eso es todo. Si te sientes tentado a añadir calendarios, recordatorios, etiquetas o cuentas, deja esas ideas para más adelante.
Imprescindible vs. opcional
Haz dos listas rápidas:
Imprescindible (para este proyecto):
- Añadir una tarea (escribir texto, hacer clic en un botón)
- Ver tareas en una lista
- Marcar una tarea como hecha
- Borrar una tarea
- Mantener tareas después de refrescar (usaremos
localStoragemás adelante)
Opcional (no requerido hoy): fechas de vencimiento, prioridades, categorías, búsqueda, arrastrar y soltar, sincronización en la nube.
Mantener lo “imprescindible” pequeño te ayuda a terminar realmente.
Describe la pantalla en palabras sencillas
Esta app puede ser una sola página con:
- Un campo de texto (“Añadir una tarea…”) y un botón “Añadir”
- Una lista de tareas debajo
- Cada tarea tiene un control de “hecho” y un botón “borrar”
Define qué significa “hecho”
Sé específico para no atascarte:
- “Hecho” = la tarea aparece tachada (o desvanecida) y permanece en la lista hasta que la borres.
Con eso decidido, estás listo para configurar los archivos del proyecto.
Paso 2: Prepara los archivos del proyecto
Antes de escribir código, crea un pequeño “hogar” limpio para la app. Mantener los archivos organizados desde el inicio hace que los siguientes pasos sean más fluidos.
1) Crea una carpeta del proyecto
Haz una nueva carpeta en tu ordenador y nómbrala algo como todo-app. Esta carpeta contendrá todo el proyecto.
Dentro de esa carpeta, crea tres archivos:
index.html(la estructura de la página)styles.css(el aspecto y diseño)app.js(el comportamiento y la interactividad)
Si tu ordenador oculta las extensiones de archivo (p. ej. “.html”), asegúrate de crear realmente los archivos. Un error común es acabar con index.html.txt.
2) Abre la carpeta en tu editor y navegador
Abre la carpeta todo-app en tu editor de código (VS Code, Sublime Text, etc.). Luego abre index.html en tu navegador.
En este punto, la página puede estar en blanco—y está bien. Añadiremos contenido en el siguiente paso.
3) Cómo verás los cambios
Cuando edites tus archivos, el navegador no se actualizará automáticamente (a menos que uses una herramienta que lo haga).
Así que el ciclo básico es:
- Guardar tu archivo en el editor
- Ir a la pestaña del navegador
- Refrescar la página para ver la actualización
Si algo “no funciona”, refrescar es lo primero que debes intentar.
Opcional: usar un servidor local simple (recomendado, no obligatorio)
Puedes construir esta app haciendo doble clic en index.html, pero un servidor local puede evitar problemas raros más adelante (especialmente cuando empieces a guardar datos o cargar archivos).
Opciones fáciles para principiantes:
- En VS Code, instala Live Server y haz clic en “Go Live”
- Si ya tienes Python instalado, ejecuta esto dentro de la carpeta:
python -m http.server
Luego abre la dirección que te muestre (a menudo http://localhost:8000) en tu navegador.
Paso 3: Construye la estructura de la página (HTML)
Ahora crearemos un esqueleto limpio para la app. Este HTML no hará nada interactivo aún (eso viene después), pero le da a tu JavaScript lugares claros para leer y escribir.
El diseño mínimo que necesitamos
Incluiremos:
- Un título para que la página sea reconocible de un vistazo
- Un cuadro de entrada para el texto de la tarea
- Un botón Añadir para enviar una tarea
- Un área de lista donde aparecerán las tareas nuevas
Usa nombres simples y legibles. IDs y clases claros facilitan los siguientes pasos porque tu JavaScript puede seleccionar elementos por nombre sin confusiones.
Pega esto en tu index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>To‑Do App</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<main class="app" id="app">
<h1 class="app__title" id="appTitle">My To‑Do List</h1>
<form class="task-form" id="taskForm">
<label class="task-form__label" for="taskInput">New task</label>
<div class="task-form__row">
<input
id="taskInput"
class="task-form__input"
type="text"
placeholder="e.g., Buy milk"
autocomplete="off"
/>
<button id="addButton" class="task-form__button" type="submit">
Add
</button>
</div>
</form>
<ul class="task-list" id="taskList" aria-label="Task list"></ul>
</main>
<script src="app.js"></script>
</body>
</html>
Eso es todo por la estructura. Observa que usamos id="taskInput" e id="taskList": esos serán los dos elementos con los que hablará más tu JavaScript.
Paso 4: Haz que se vea limpio (CSS)
Ahora mismo la página existe, pero probablemente se vea como un documento simple. Un poco de CSS la hace más fácil de usar: espaciado claro, texto legible y botones que parecen clicables.
Empieza con un contenedor centrado
Una caja centrada mantiene la app enfocada y evita que el contenido se estire en pantallas anchas.
/* Basic page setup */
body {
font-family: Arial, sans-serif;
background: #f6f7fb;
margin: 0;
padding: 24px;
}
/* Centered app container */
.container {
max-width: 520px;
margin: 0 auto;
background: #ffffff;
padding: 16px;
border-radius: 10px;
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.08);
}
Haz que las tareas sean fáciles de escanear
Cada tarea debería parecer una fila separada, con espaciado cómodo.
ul { list-style: none; padding: 0; margin: 16px 0 0; }
li {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
padding: 10px 12px;
border: 1px solid #e7e7ee;
border-radius: 8px;
margin-bottom: 10px;
}
.task-text { flex: 1; }
Añade una apariencia clara para “hecho”
Cuando una tarea esté completada, debería cambiar visualmente para que se note de un vistazo.
.done .task-text {
text-decoration: line-through;
color: #777;
opacity: 0.85;
}
Mantén los botones consistentes
Que los botones tengan el mismo tamaño y estilo para que parezcan parte de una misma app.
button {
border: none;
border-radius: 8px;
padding: 8px 10px;
cursor: pointer;
}
button:hover { filter: brightness(0.95); }
Eso es suficiente estilo para una interfaz limpia y agradable—sin trucos avanzados. A continuación conectaremos el comportamiento con JavaScript.
Paso 5: Añadir tareas (conceptos básicos de JavaScript)
Ahora que tienes el campo de entrada, el botón y la lista en la página, harás que hagan algo. El objetivo es simple: cuando alguien escribe una tarea y pulsa Añadir (o presiona Enter), debe aparecer un elemento nuevo en la lista.
Conecta el botón y la tecla Enter
En tu archivo JavaScript, primero toma los elementos que necesitas, luego escucha dos acciones: un clic del botón y la tecla Enter dentro del input.
const taskInput = document.querySelector('#taskInput');
const addBtn = document.querySelector('#addBtn');
const taskList = document.querySelector('#taskList');
function addTask() {
const text = taskInput.value.trim();
// Block empty tasks (including ones that are just spaces)
if (text === '') return;
const li = document.createElement('li');
li.textContent = text;
taskList.appendChild(li);
// Clear the input and put the cursor back
taskInput.value = '';
taskInput.focus();
}
addBtn.addEventListener('click', addTask);
taskInput.addEventListener('keydown', (event) => {
if (event.key === 'Enter') {
addTask();
}
});
Qué hace esto (en lenguaje sencillo)
- Lee el texto del input y usa
trim()para quitar espacios extra al inicio/final. - Detiene la acción si la tarea está vacía, para no añadir items en blanco.
- Crea un nuevo
li, le asigna el texto y lo añade a la lista. - Limpia el input y devuelve el foco a él para que escribir la siguiente tarea sea rápido.
Si no pasa nada, revisa que los IDs en el HTML coincidan exactamente con los selectores en JavaScript (es uno de los fallos más comunes para principiantes).
Paso 6: Marcar como hecho y borrar tareas
Ahora que puedes añadir tareas, hagámoslas accionables: deberías poder marcar una tarea como hecha y eliminarla.
Almacena tareas como datos simples
En lugar de guardar las tareas como cadenas, guárdalas como objetos. Eso les da una identidad estable y un lugar para rastrear el estado “hecho”:
text: lo que dice la tareadone:trueofalseid: un número único para poder encontrar/borrar la tarea correcta
Aquí hay un ejemplo simple:
let tasks = [
{ id: 1, text: "Buy milk", done: false },
{ id: 2, text: "Email Sam", done: true }
];
Añade un control de Hecho y un botón Eliminar
Cuando renders cada tarea en la página, incluye un checkbox o un botón “Hecho”, además de un botón “Borrar”.
Un patrón amigable para principiantes es delegación de eventos: pon un listener de clic en el contenedor de la lista y luego comprueba qué se ha pulsado.
function toggleDone(id) {
tasks = tasks.map(t => t.id === id ? { ...t, done: !t.done } : t);
renderTasks();
}
function deleteTask(id) {
tasks = tasks.filter(t => t.id !== id);
renderTasks();
}
document.querySelector("#taskList").addEventListener("click", (e) => {
const id = Number(e.target.dataset.id);
if (e.target.matches(".toggle")) toggleDone(id);
if (e.target.matches(".delete")) deleteTask(id);
});
En tu función renderTasks():
- Añade
data-id="${task.id}"a cada botón. - Muestra visualmente las tareas hechas (por ejemplo, añadiendo la clase
.done).
Paso 7: Guardar tareas para que se mantengan (localStorage)
Ahora mismo tu lista tiene un problema molesto: si refrescas la página (o cierras la pestaña), todo desaparece.
Esto pasa porque tus tareas solo existen en la memoria de JavaScript. Cuando la página se recarga, esa memoria se reinicia.
localStorage = una pequeña “caja de guardado” dentro del navegador
localStorage viene integrado en el navegador. Piénsalo como una caja pequeña donde puedes guardar texto bajo un nombre (una “clave”). Es perfecto para proyectos de principiantes porque no necesita servidor ni cuentas.
Guardaremos toda la lista de tareas como texto JSON y la cargaremos cuando se abra la página.
1) Guardar después de cada cambio
Cada vez que añadas, marques o borres una tarea, llama a saveTasks().
const STORAGE_KEY = "todo.tasks";
function saveTasks(tasks) {
localStorage.setItem(STORAGE_KEY, JSON.stringify(tasks));
}
Donde sea que actualices el array tasks, haz esto justo después:
saveTasks(tasks);
renderTasks(tasks);
2) Cargar al iniciar la página (y renderizar)
Cuando la página carga, lee el valor guardado. Si no hay nada guardado aún, usa una lista vacía.
function loadTasks() {
const saved = localStorage.getItem(STORAGE_KEY);
return saved ? JSON.parse(saved) : [];
}
let tasks = loadTasks();
renderTasks(tasks);
Eso es todo: ahora la app recuerda las tareas aunque refresques.
Consejo: localStorage solo guarda cadenas, así que JSON.stringify() convierte tu array en texto y JSON.parse() lo vuelve a transformar en un array cuando lo cargas.
Paso 8: Prueba y arregla errores comunes
Probar suena aburrido, pero es la forma más rápida de convertir tu app de “funciona en mi máquina” a “funciona siempre”. Haz una pasada rápida tras cada cambio pequeño.
Una pasada rápida de prueba (60 segundos)
Recorre el flujo principal en este orden:
- Añadir una tarea
- Marcarla como hecha
- Borrarla
- Refrescar la página (para confirmar que la UI sigue comportándose como se espera)
Si algún paso falla, arréglalo antes de añadir nuevas funciones. Las apps pequeñas se vuelven caóticas si apilas problemas.
Prueba casos límite que rompen apps de principiantes
Los casos límite son entradas para las que no diseñaste, pero los usuarios reales las harán:
- Texto muy largo (¿desborda o empuja botones fuera de la pantalla?)
- Tareas repetidas (¿borras la correcta?)
- Entrada en blanco (¿añade una tarea vacía?)
Un arreglo común es bloquear tareas vacías:
const text = input.value.trim();
addButton.disabled = text === "";
(Puedes ejecutar eso en cada evento input, y otra vez justo antes de añadir.)
Rápida lista de comprobación cuando “no pasa nada”
Cuando los clics no hacen nada, suele ser una de estas:
- Un selector no coincide (un
ido nombre de clase difiere entre HTML y JS). - Tu script no se carga (nombre/ruta incorrecta, o
app.jsno se encontró). - Hay un error de JavaScript que detiene el resto del archivo.
Usa la consola para ver qué pasa realmente
Cuando algo parece aleatorio, regístralo:
console.log("Adding:", text);
console.log("Current tasks:", tasks);
Revisa la Consola del navegador para errores (texto rojo). Cuando soluciones, elimina los logs para que no ensucien el proyecto.
Paso 9: Hazla cómoda de usar (accesibilidad + móvil)
Una app de tareas está “lista” cuando es cómoda para personas reales—en teléfonos, con teclado y con herramientas de ayuda como lectores de pantalla.
Facilita el uso en móvil
En pantallas pequeñas, botones diminutos frustran. Da espacio a los elementos clicables:
- Usa padding más grande en botones (apunta a unos 44px de alto).
- Añade espacio entre los botones Hecho y Borrar para no fallar al pulsar.
- Mantén el campo de entrada a ancho completo en móvil para que escribir sea cómodo.
En CSS, aumentar padding, font-size y gap suele marcar la mayor diferencia.
Añade labels y ARIA (qué y por qué)
Los lectores de pantalla necesitan nombres claros para los controles.
- Tu input de texto debe tener un
labelreal (la mejor opción). Si no quieres mostrarlo, puedes ocultarlo visualmente con CSS, pero mantenlo en el HTML. - Botones con solo iconos (por ejemplo, una papelera) deberían incluir
aria-label="Borrar tarea"para que el lector de pantalla no anuncie un botón sin contexto.
Esto ayuda a que las personas entiendan qué hace cada control sin adivinar.
Soporte de teclado: Tab + Enter
Asegúrate de que se pueda usar toda la app sin ratón:
- Debes poder Tab al input y a los botones.
- Pulsar Enter en el input debería añadir la tarea (usar un
formayuda a que Enter funcione naturalmente). - Cuando añades una tarea, considera devolver el foco al input para añadir varias tareas rápidamente.
Legibilidad: contraste y tamaño de fuente
Usa un tamaño de fuente legible (16px es una buena base) y contraste fuerte (texto oscuro sobre fondo claro o viceversa). Evita usar solo color para indicar “hecho”: añade un estilo claro como tachado además del color.
Paso 10: Limpia y organiza tu código
Ahora que todo funciona, dedica 10–15 minutos a ordenar. Esto hace que arreglos futuros sean más fáciles y te ayuda a entender tu propio proyecto cuando vuelvas más tarde.
Una estructura sencilla de carpetas
Manténlo pequeño y predecible:
/index.html— la estructura de la página (input, botón, lista)/styles.css— el aspecto (espaciado, fuentes, estilo “hecho”)/app.js— el comportamiento (añadir, alternar hecho, borrar, guardar/cargar)/README.md— notas rápidas para el “tú del futuro”
Si prefieres subcarpetas, también puedes:
/css/styles.css/js/app.js
Solo asegúrate de que tus rutas en link y script coincidan.
Haz que el JavaScript sea más legible
Algunos trucos rápidos:
- Usa nombres claros:
taskInput,taskList,saveTasks() - Mantén funciones pequeñas: una función debe hacer una sola cosa
- Usa comentarios cortos solo donde el código no sea obvio (evita comentar cada línea)
Por ejemplo, es más fácil leer:
renderTasks(tasks)addTask(text)toggleTask(id)deleteTask(id)
Añade un README pequeño
Tu README.md puede ser simple:
- Qué hace (una lista de tareas que guarda las tareas)
- Cómo ejecutarla (abre
index.htmlen un navegador) - Opcional: limitaciones conocidas
Haz una copia de seguridad del proyecto
Como mínimo, comprime la carpeta cuando termines un hito (por ejemplo, “localStorage funciona”). Si quieres historial, Git es genial—pero opcional. Incluso una copia de seguridad simple puede salvarte de borrados accidentales.
Paso 11: Publica tu app y compártela
Publicar solo significa poner los archivos (HTML, CSS, JavaScript) en algún sitio público para que otras personas puedan abrir un enlace y usarla. Como esta app es un “sitio estático” (se ejecuta en el navegador y no necesita servidor), puedes alojarla gratis en varios servicios.
Opción 1: GitHub Pages (bueno para sitios estáticos)
Pasos generales:
- Crea una cuenta en GitHub (si no tienes una).
- Crea un nuevo repositorio y sube tus archivos (o haz push con Git).
- En el repo, ve a Settings → Pages.
- Elige la rama a publicar (a menudo main) y la carpeta (normalmente / root).
- Guarda: GitHub te dará una URL pública.
Si tu app usa archivos separados, revisa que los nombres coincidan exactamente con tus enlaces (por ejemplo styles.css vs style.css).
Opción 2: Netlify o Vercel (arrastrar y soltar)
Si quieres la manera más sencilla “subir y listo”:
- Crea una cuenta en Netlify o Vercel.
- Busca Deploy / Add New Project.
- Arrastra y suelta la carpeta del proyecto (o conecta un repo de GitHub).
- Espera a que termine la subida.
- Abre la URL generada y pruébala.
Lista rápida antes de compartir el enlace
- Refresca la página: las tareas deberían seguir ahí (
localStoragefuncionando). - Prueba añadir, completar y borrar tareas: que no haya botones rotos.
- Ábrela en móvil (o estrecha la ventana): nada debería salirse de la pantalla.
Cuando pase esto, envía el enlace a un amigo y pídele que la pruebe—ojos frescos detectan problemas rápido.
Próximos pasos: mejoras fáciles que puedes intentar
Has construido una app de tareas que funciona. Si quieres seguir aprendiendo sin saltar a un proyecto grande, estas mejoras añaden valor real y enseñan patrones útiles.
1) Editar texto de una tarea
Añade un botón “Editar” al lado de cada tarea. Al hacer clic, cambia la etiqueta por un pequeño input (prefill) y muestra “Guardar” y “Cancelar”.
Consejo: mantén los datos como un array de objetos (con id y text). Editar entonces es: encontrar la tarea por id, actualizar text, volver a renderizar y guardar.
2) Filtros: Todas / Activas / Hechas
Añade tres botones arriba: Todas, Activas, Hechas.
Guarda el filtro actual en una variable como currentFilter = 'all'. Al renderizar, muestra:
- All: todas las tareas
- Active: tareas no completadas
- Done: tareas completadas
3) Fechas de vencimiento o categorías simples
Mantenlo ligero:
- Añade una fecha opcional (
YYYY-MM-DD) y muéstrala junto a la tarea - O añade una categoría como “Trabajo / Casa / Estudio” con un pequeño desplegable
Incluso un campo extra te enseña a actualizar el modelo de datos y la UI juntos.
4) Más adelante: pasar de localStorage a un backend simple
Cuando estés listo, la idea grande es: en vez de guardar en localStorage, envías las tareas a una API (un servidor) usando fetch(). El servidor las guarda en una base de datos, así las tareas se sincronizan entre dispositivos.
Si quieres probar ese salto sin rehacer todo, plataformas de prototipado y generación de código pueden ayudarte a crear la versión siguiente con endpoints API y persistencia.
5) Un buen siguiente proyecto para principiantes
Prueba a construir una app de notas (con búsqueda) o un rastreador de hábitos (check-ins diarios). Reutilizan las mismas habilidades: renderizado de listas, edición, guardado y diseño de UI simple.
Preguntas frecuentes
¿Qué necesito para crear esta aplicación de lista de tareas?
Solo necesitas una computadora, un navegador moderno y un editor de código. Crea una carpeta con index.html, styles.css y app.js, y luego abre el archivo HTML en tu navegador.
¿Qué funciones debería incluir una aplicación de lista de tareas para principiantes?
Empieza con cuatro acciones: añadir una tarea, verla en una lista, marcarla como completada y eliminarla. Deja para más adelante los extras, como fechas límite, categorías y cuentas.
¿Qué hace cada archivo del proyecto?
HTML crea el campo de entrada, el botón y la lista de tareas. CSS controla el espaciado y la apariencia. JavaScript lee las acciones del usuario, actualiza la lista y guarda los datos de las tareas.
¿Cómo evito que se añadan tareas vacías?
Usa un formulario con un campo de texto y un botón de envío. JavaScript debe eliminar los espacios sobrantes del valor introducido, rechazar un resultado vacío, crear un elemento de lista y luego limpiar y enfocar el campo.
¿Por qué las tareas deberían usar objetos en lugar de texto sin formato?
Usa objetos de tarea con valores id, text y done. El ID permite que tu código actualice o elimine la tarea exacta, incluso cuando dos tareas tienen el mismo texto.
¿Cómo marco una tarea como completada?
Añade una casilla de verificación o un botón de completada para cada tarea. Cuando alguien haga clic, cambia el valor done de esa tarea y añade una clase CSS que aplique un tachado o un estilo atenuado.
¿Cómo puede la aplicación recordar las tareas después de actualizar la página?
Guarda el array de tareas con JSON.stringify() bajo un nombre en localStorage y luego léelo con JSON.parse() al iniciar la página. Vuelve a guardar después de añadir, completar, editar o eliminar una tarea.
¿Por qué mi botón Añadir no hace nada?
Primero actualiza la página y abre la consola del navegador para ver mensajes de error en rojo. Luego comprueba que los ID de tu HTML coincidan con los selectores de JavaScript y que el nombre del archivo de script coincida con la ruta en index.html.
¿Cómo puedo facilitar el uso de la aplicación en teléfonos y con un teclado?
Usa una etiqueta real para el campo de entrada de tareas, haz que los controles sean lo bastante grandes para tocarlos y prueba la aplicación con Tab y Enter. Las tareas completadas deben usar algo más que el color, como un tachado y texto claro.
¿Qué debería probar antes de publicar mi aplicación de lista de tareas?
Prueba a añadir una tarea, marcarla como completada, eliminarla y actualizar la página. Antes de compartir la aplicación, prueba también campos vacíos, nombres de tareas largos y texto de tareas duplicado.