Complete step-by-step guide + working code to build a Simple To-Do List App using Laravel (works with Laravel 11 / future Laravel 12 — nothing is version-breaking).

simple to-do-list

✅ Features

✔ Add Task
✔ Show Task List
✔ Mark Task as Completed
✔ Delete Task
✔ Uses Eloquent, Blade, Routes, Controllers
✔ Simple UI (Bootstrap or Tailwind)

🏗 1. Create Laravel Project

 bash

composer create-project laravel/laravel todo-app
cd todo-app

📌 2. Create Migration & Model

 bash

php artisan make:model Task -m

database/migrations/xxxx_create_tasks_table.php

 php

public function up()
{
    Schema::create('tasks', function (Blueprint $table) {
        $table->id();
        $table->string('title');
        $table->boolean('completed')->default(false);
        $table->timestamps();
    });
}


Run migration:

 bash

php artisan migrate

🧠 3. Task Model

app/Models/Task.php

 php

class Task extends Model
{
    protected $fillable = ['title', 'completed'];
}


🎯 4. Create Controller

 php

php artisan make:controller TaskController


app/Http/Controllers/TaskController.php

 php

namespace App\Http\Controllers;

use App\Models\Task;
use Illuminate\Http\Request;

class TaskController extends Controller
{
    public function index()
    {
        $tasks = Task::latest()->get();
        return view('tasks.index', compact('tasks'));
    }

    public function store(Request $request)
    {
        $request->validate([
            'title' => 'required|min:3'
        ]);

        Task::create([
            'title' => $request->title
        ]);

        return back();
    }

    public function update(Task $task)
    {
        $task->update([
            'completed' => !$task->completed
        ]);

        return back();
    }

    public function destroy(Task $task)
    {
        $task->delete();
        return back();
    }
}

🔗 5. Routes

routes/web.php

 php

use App\Http\Controllers\TaskController;

Route::get('/', [TaskController::class, 'index']);
Route::post('/tasks', [TaskController::class, 'store'])->name('tasks.store');
Route::patch('/tasks/{task}', [TaskController::class, 'update'])->name('tasks.update');
Route::delete('/tasks/{task}', [TaskController::class, 'destroy'])->name('tasks.delete');


🎨 6. Create Blade View

resources/views/tasks/index.blade.php

(Using Tailwind for simplicity — works with default Laravel install)

 blade

<!DOCTYPE html>
<html>
<head>
    <title>Laravel To-Do App</title>
    @vite('resources/css/app.css')
</head>
<body class="bg-gray-100 py-10">
    <div class="max-w-xl mx-auto bg-white p-6 shadow-lg rounded-lg">
        <h1 class="text-2xl font-bold mb-4 text-center">Simple To-Do List</h1>

        {{-- Add Task --}}
        <form action="{{ route('tasks.store') }}" method="POST">
            @csrf
            <input type="text" name="title" class="border w-full p-2 rounded" placeholder="New task..." required>
            <button class="bg-blue-500 text-white mt-3 px-4 py-2 rounded w-full">Add Task</button>
        </form>

        {{-- Task List --}}
        <ul class="mt-6">
            @foreach($tasks as $task)
                <li class="flex justify-between items-center mb-2 p-2 border rounded {{ $task->completed ? 'bg-green-50' : '' }}">
                    <form action="{{ route('tasks.update', $task) }}" method="POST">
                        @csrf @method('PATCH')
                        <button>{{ $task->completed ? '☑' : '⬜' }}</button>
                    </form>

                    <span class="{{ $task->completed ? 'line-through text-gray-500' : '' }}">
                        {{ $task->title }}
                    </span>

                    <form action="{{ route('tasks.delete', $task) }}" method="POST">
                        @csrf @method('DELETE')
                        <button class="text-red-500 font-bold">✖</button>
                    </form>
                </li>
            @endforeach
        </ul>
    </div>
</body>
</html>


Leave a Reply

Your email address will not be published. Required fields are marked *