Whether you need a high-performance web application, full-stack architecture advisory, or an engineer who ships with urgency and care.
Jump directly on my calendar to talk about goals, timeline, and fit.
Insertion Sort is one of the most intuitive sorting algorithms out there.
Imagine you’re sitting at a table playing a card game. The dealer hands you a pile of unsorted cards face down. You pick up the cards one by one to arrange them in your hand from smallest to largest.
Here is how your brain naturally handles it:
You pick up the first card. It’s a 7. Since it's the only card in your hand, it's already "sorted."
You pick up the second card. It’s a 3. You look at the 7, realize 3 is smaller, and insert it to the left of the 7.
You pick up a third card. It’s a 5. You compare it to the 7 (bigger, so you move past it) and then the 3 (smaller). You insert the 5 right between the 3 and the 7.
That is literally all Insertion Sort is! It builds a sorted list one item at a time by constantly "inserting" the current item into its correct position among the items already sorted.
Assume the very first element in the array is already sorted.
Move to the next element (let's call this the Key).
Compare the Key with the elements before it (to its left).
Shift all elements that are greater than the Key to the right to make room.
Insert the Key into its correct, empty slot.
Repeat for all remaining elements until the whole array is sorted.
Let's watch this happen with a real array of numbers: [5, 2, 4, 6, 1, 3].
Start: [5, 2, 4, 6, 1, 3] The first element (5) is our sorted zone.
Iteration 1: Key is 2. Compare 2 with 5. Since 5 is bigger, shift 5 to the right and insert 2.
Array becomes: [2, 5, 4, 6, 1, 3]
Iteration 2: Key is 4. Compare 4 with 5 (shift 5 right), then compare 4 with 2 (2 is smaller, so stop). Insert 4.
Array becomes: [2, 4, 5, 6, 1, 3]
Iteration 3: Key is 6. Compare 6 with 5. Since 6 is already bigger than 5, it's in the right spot! No shifting needed.
Array becomes: [2, 4, 5, 6, 1, 3]
Iteration 4: Key is 1. This is a tiny number, so it compares against 6, 5, 4, and 2, shifting all of them to the right, and drops into the very front.
Array becomes: [1, 2, 4, 5, 6, 3]
Iteration 5: Key is 3. Compare and shift 6, 5, and 4 to the right. Stop at 2. Insert 3.
Array becomes: [1, 2, 3, 4, 5, 6]
Here is how we write this in clean, readable JavaScript. Paste this into your browser console or code editor to play around with it!
Imagine you give this algorithm an array that is already sorted, like [1, 2, 3, 4, 5]. The algorithm will check each number once, realize it doesn't need to shift anything, and smoothly finish. It runs in linear time, which is incredibly fast!
Imagine the array is completely backward, like [5, 4, 3, 2, 1]. For every single number, the algorithm has to compare and shift every single other number before it. This results in quadratic time. If your array grows 10x larger, the time it takes grows 100x larger!
Because Insertion Sort rearranges elements directly inside the original array without creating a copy or a new array, it uses virtually no extra memory. This is called sorting in-place.
If Insertion Sort can get terribly slow with large datasets (O(n^2)), why do we care about it?
Because it shines in specific real-world situations:
Small datasets: For lists with just a few items, Insertion Sort is actually faster than algorithms like Quick Sort because it has almost zero administrative overhead.
Nearly sorted data: If you are constantly adding a few new entries to a database that is already mostly sorted, Insertion Sort will clean it up in record time.
Explore more articles on software architecture, frontend craftsmanship, and backend engineering.

Selection Sort is one of the most intuitive sorting algorithms in computer science. It repeatedly selects the smallest item from an unsorted list and moves it to its correct position.
Selection Sort takes a single list of data and conceptually divides it into two sides:
The Sorted Side (on the left)
The Unsorted Side (on the right)
When you start, the sorted side is completely empty, and the unsorted side contains all your data.
Here is the exact step-by-step logic the computer follows:
Step 1: Start at the very beginning of the unsorted list.
Step 2: Scan through the rest of the unsorted items to find the absolute smallest value.
Step 3: Swap that smallest value with the item currently at the starting position.
Step 4: Move your starting point one spot to the right (since the previous spot is now officially "sorted").
Step 5: Repeat the process until you reach the end of the list.
Selection Sort in action with a small array of numbers: [29, 10, 14, 37, 13]. Our goal is to sort them from smallest to largest.
Starting State
Unsorted: [29, 10, 14, 37, 13]
Sorted: []
Pass 1
We scan the whole list looking for the smallest number. It’s 10.
We swap 10 with the number in the first position (29).
Array becomes: [10, 29, 14, 37, 13]
Sorted so far: [10]
Pass 2
We look at the remaining unsorted numbers: [29, 14, 37, 13].
The smallest number here is 13.
We swap 13 with the number in the second position (29).
Array becomes: [10, 13, 14, 37, 29]
Sorted so far: [10, 13]
Pass 3
We look at the remaining unsorted numbers: [14, 37, 29].
The smallest number is 14. Since it's already in the correct spot, no swap is needed!
Array stays: [10, 13, 14, 37, 29]
Sorted so far: [10, 13, 14]
Pass 4
We look at the remaining unsorted numbers: [37, 29].
The smallest number is 29.
We swap 29 with the number in the fourth position (37).
Array becomes: [10, 13, 14, 29, 37]
Final State
Because there is only one number left (37), it must automatically be in the correct spot.
Final Sorted Array: [10, 13, 14, 29, 37]
def selection_sort(arr):
# Get the total number of items in the list
n = len(arr)
# Loop through the entire array
for i in range(n):
# Assume the current item is the smallest for now
min_index = i
# Scan the rest of the array to find the actual smallest item
for j in range(i + 1, n):
if arr[j] < arr[min_index]:
# We found a new smallest item! Remember its position
min_index = j
# Swap the smallest item we found with the item at our current position
arr[i], arr[min_index] = arr[min_index], arr[i]
return arr
# Test the algorithm
example_list = [29, 10, 14, 37, 13]
print("Sorted list:", selection_sort(example_list))Easy to Understand: It’s incredibly simple to write and debug.
Low Memory Usage: It sorts the list "in-place," meaning it doesn't need to create copies of your list or use extra computer memory to do its job.
Minimal Swapping: It only performs one swap per pass. If writing data to a disk is expensive/slow, Selection Sort is highly efficient with its moves.
It’s Slow: Selection Sort has to look through the unsorted list over and over again. If you double the size of your list, the sorting time doesn't just double; it quadruples!
It Ignores Existing Order: Selection Sort is "blind" to whether a list is already partially sorted. Even if you give it a list that is perfectly sorted from the start, it will still stubbornly scan every single item to double check.
Use Selection Sort if you are dealing with a very small amount of data, or if you need a quick and dirty algorithm that uses almost zero extra memory. If you are dealing with thousands or millions of items, you'll want to upgrade to faster algorithms like Merge Sort or Quick Sort!

Bubble Sort is a sorting algorithm. It works by comparing two neighbouring elements and swapping them until the list is sorted.
Compare: Look at the first two elements
Swap: If the first element is greater than the second element, swap them.
Move: Move to the next pair and repeat until you reach the end of the list.
Repeat: Go back to the start and repeat the process until the list is sorted.
Example
Consider the following list [4, 6, 1, 3, 5, 2]
Compare the first two elements. 4 and 6.
6 is greater than 4. Move to the next index.
Move to the next pair, 6 and 1.
6 > 1, swap them.
The new list becomes [4, 1, 6, 3, 5, 2]
Move to the next pair. 6 and 3. 6 > 3 , swap them -> [4, 1, 3, 6, 5, 2]
Move to the next pair. 6 and 5. 6 > 5, swap them -> [4, 1, 3, 5, 6, 2]
Move to the next pair. 6 and 2. Again 6 > 2, swap them -> [4, 1, 3, 5, 2, 6]
The first iteration is completed.
Now move to the start and follow the same steps until the list is sorted.
Example Code
def bubble_sort(arr):
n = len(arr)
# Traverse through all array elements
for i in range(n):
swapped=False
# Last i elements are already in place, so we ignore them
# Traverse the array from 0 to n-i-1
for j in range (0, n-i-1):
# Swap if the element found is greater than the next element
if arr[j] > arr[j+1]:
arr[j], arr[j+1] = arr[j+1], arr[j]
swapped = True
# If no two elements were swapped by inner loop, then break
if not swapped:
break
return arr
Creating a todo app in JS is easy as we write the code. Before starting without a project we must have a basic understanding of HTML, CSS, and JavaScript.
Basic knowledge of HTML
Basic knowledge of CSS
Basic knowledge of JS
Let's understand the app we are going to build. It will be a simple to-do app where users can add, edit, and delete items.
First, create a directory for the todo app. Create a file inside for HTML, CSS, and JavaScript.
mkdir todo && cd todotouch app.js && touch styles.css && touch index.htmlAdd the following code to index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/meistericons@latest/fonts/mni.css"
/>
<link rel="stylesheet" href="./styles.css" />
<title>Todo App - HTML, CSS and JS</title>
</head>
<body>
<main class="container">
<h1>Todos</h1>
<form class="">
<input
type="text"
name="todo"
id="todo"
placeholder="+ Add New Todo"
name="Take a walk"
/>
<button type="submit">Add</button>
</form>
<div class="tab_container">
<span class="active_tab tab">Remaning Todos</span>
<span class="tab">Completed Todos</span>
</div>
<strong class="active__todo">Remaning Todos</strong>
<ul class="todo__container"></ul>
</main>
<script src="./app.js"></script>
</body>
</html>Add the following code to styles.css
body,
html,
:root,
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
width: 20rem;
height: 30rem;
border-radius: 2rem;
border: 1px solid rgb(34, 36, 192);
padding: 2rem;
position: fixed;
top: 10rem;
left: 38%;
}
h1 {
font-size: 3rem;
font-weight: 700;
margin-bottom: 1rem;
}
div {
display: flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
margin: 1rem 0;
}
.todo__active {
border-bottom: 4px solid rgb(34, 36, 192);
}
.active__todo {
font-size: 1.25rem;
font-weight: 600;
}
ul {
margin-top: 1rem;
display: flex;
flex-direction: column;
gap: 0.5rem;
}
li {
list-style-type: none;
display: flex;
gap: 0.25rem;
}
label {
font-size: 1rem;
font-weight: 500;
}
.tab_container {
display: flex;
gap: 1rem;
}
.tab {
font-weight: 600;
font-size: 0.85rem;
}
.tab:hover {
cursor: pointer;
}
.active_tab {
border-bottom: 4px solid rgb(34, 36, 192);
font-weight: 700;
font-size: 1rem;
}
.todo__container {
height: 15rem;
overflow-y: scroll;
}
.todo {
display: flex;
align-items: center;
justify-content: space-between;
}
.todo__item__span {
display: flex;
align-items: center;
gap: 0.5rem;
}Add the following code to the app.js file.
// List of Tasks
let todos = [
{ title: "Example 1", completed: false },
{ title: "Example 2", completed: false },
{ title: "Example 3", completed: false },
];
const todoContainer = document.querySelector(".todo__container");
const remainingTodoTab = document.querySelectorAll(".tab")[0];
const completedTodoTab = document.querySelectorAll(".tab")[1];
const todoHeader = document.querySelector(".active__todo");
// RemainingTasks event listerner.
remainingTodoTab.addEventListener("click", () => {
completedTodoTab.classList.remove("active_tab");
remainingTodoTab.classList.add("active_tab");
todoHeader.innerHTML = "Remaining Todos";
clearTodoList();
todos
.filter(({ completed }) => !completed)
.forEach((remainingTodo) => {
createTodoItem(remainingTodo.title);
});
});
// CompletedTasks event listener.
completedTodoTab.addEventListener("click", () => {
remainingTodoTab.classList.remove("active_tab");
completedTodoTab.classList.add("active_tab");
todoHeader.innerHTML = "Completed Todos";
clearTodoList();
todos
.filter(({ completed }) => completed === true)
.forEach((completedTodo) => {
createTodoItem(completedTodo.title, true);
});
});
// Clear Task List
const clearTodoList = () => {
todoContainer.innerHTML = "";
};
/**
* Remove task from tasks list.
* @param {*} removeTodo - String to remove from tasks list.
*/
const removeTodo = (removeTodo) => {
todos = todos.filter((todo) => todo.title !== removeTodo);
};
/**
*
* @param {*} task - String to add to tasks list.
* @param {*} isCompleted - Status of the task.
*/
const createTodoItem = (task, isCompleted = false) => {
const newListItem = document.createElement("li");
newListItem.classList.add("todo");
const newTodoSpan = document.createElement("span");
newTodoSpan.classList.add("todo__item__span");
const newTodo = document.createElement("label");
const input = document.createElement("input");
const deleteIcon = document.createElement("i");
deleteIcon.classList.add("mni-delete-aB");
// Delete Task Click Event Listner.
deleteIcon.addEventListener("click", () => {
removeTodo(task);
newListItem.remove();
});
if (isCompleted) {
input.checked = true;
newListItem.style.textDecoration = "line-through";
} else {
input.checked = false;
}
input.type = "checkbox";
/**
* Update checkbox status.
* @param {*} e - Events in input element.
*/
input.onchange = (e) => {
const currentTodo = todos.find((todo) => todo.title === e.target.name);
if (e.target.checked) {
e.target.parentElement.style.textDecoration = "line-through";
currentTodo.completed = true;
} else {
currentTodo.completed = false;
e.target.parentElement.style.textDecoration = "none";
}
newListItem.remove();
};
input.name = task;
newListItem.appendChild(newTodoSpan);
newTodoSpan.appendChild(input);
newTodoSpan.appendChild(newTodo);
newListItem.appendChild(deleteIcon);
newTodo.innerHTML = task;
todoContainer.appendChild(newListItem);
if (!todos.length) {
todos.push({ title: task, completed: false });
}
};
// Create a list of tasks
todos.forEach((todo) => {
createTodoItem(todo.title);
});
// Add task to the list.
const addTodo = (e) => {
e.preventDefault();
const todo = document.getElementById("todo").value;
if (todo.length > 0 && remainingTodoTab.classList.contains("active_tab")) {
todos.push({ title: todo, completed: false });
createTodoItem(todo);
}
document.getElementById("todo").value = "";
};
document.querySelector("form").addEventListener("submit", addTodo);
Let's understand each of the lines of code.
Initially, a list of example tasks is added.
let todos = [
{ title: "Example 1", completed: false },
{ title: "Example 2", completed: false },
{ title: "Example 3", completed: false },
];We will add an event listener for the form submission and add a function for it.
const addTodo = (e) => {
e.preventDefault();
const todo = document.getElementById("todo").value;
if (todo.length > 0 && remainingTodoTab.classList.contains("active_tab")) {
todos.push({ title: todo, completed: false });
createTodoItem(todo);
}
document.getElementById("todo").value = "";
};
document.querySelector("form").addEventListener("submit", addTodo);We also need to create a function to append a new task list item after the user submits the form.
const createTodoItem = (task, isCompleted = false) => {};First, we create the tags necessary for the list item to check if the selected task is completed.
if (isCompleted) {
input.checked = true;
newListItem.style.textDecoration = "line-through";
} else {
input.checked = false;
}
input.type = "checkbox";Add an event handler for the input to update the completed and remaining tasks.
/**
* Update checkbox status.
* @param {*} e - Events in input element.
*/
input.onchange = (e) => {
const currentTodo = todos.find((todo) => todo.title === e.target.name);
if (e.target.checked) {
e.target.parentElement.style.textDecoration = "line-through";
currentTodo.completed = true;
} else {
currentTodo.completed = false;
e.target.parentElement.style.textDecoration = "none";
}
newListItem.remove();
};
input.name = task;Finally, append all the created tags to the html body
newListItem.appendChild(newTodoSpan);
newTodoSpan.appendChild(input);
newTodoSpan.appendChild(newTodo);
newListItem.appendChild(deleteIcon);
newTodo.innerHTML = task;
todoContainer.appendChild(newListItem);
if (!todos.length) {
todos.push({ title: task, completed: false });
}Now, let us add an event listener to our delete icon.
// Delete Task Click Event Listner.
deleteIcon.addEventListener("click", () => {
removeTodo(task);
newListItem.remove();
});
and the function to remove the task.
// Clear Task List
const clearTodoList = () => {
todoContainer.innerHTML = "";
};
/**
* Remove task from tasks list.
* @param {*} removeTodo - String to remove from tasks list.
*/
const removeTodo = (removeTodo) => {
todos = todos.filter((todo) => todo.title !== removeTodo);
};We have built a complete to-do app where users can add tasks. View Remaining and completed tasks. Update tasks to be completed and/or uncompleted. We have done it all using our knowledge of HTML, CSS, and javascript. You can now easily update the UI to your liking and extra features to the app to make it even better.

Todo app is a simple web app that can get you started with React. React makes it easy to accomplish our task.
Basic knowledge of React.
Basic knowledge of React Hooks.
Basic knowledge of HTML, CSS, and JavaScript.
Let's start by Creating a React app with the following command. For this example, we will be using the Vite to create the Todo React app
npm create vite@latest todo --tempalate react-swc-tsNavigate into the directory and install the dependencies.
cd todo && npm i && npm run devNow we can see the starter for a Vite React project. Edit the src/App.tsx page to get started.
Initially, create a component for the Input so that we can reuse it across the App.
//components/Input/Input.tsx
import { ComponentPropsWithoutRef } from "react";
import "./styles.css";
interface IInput extends ComponentPropsWithoutRef<"fieldset"> {
inputProps: ComponentPropsWithoutRef<"input">;
}
export default function Input({ inputProps }: IInput) {
return (
<fieldset className="input__container">
<label htmlFor="todo" className="input__label">
Add Todo
</label>
<input
{...inputProps}
type="text"
name="todo"
id="todo"
className="input__input"
/>
</fieldset>
);
}
Add the styles for it.
//components/Input/styles.css
.input__container {
display: flex;
flex-direction: column;
gap: 0.25rem;
border: none;
}
.input__label {
font-size: 1rem;
font-weight: 700;
}
.input__input {
padding: 0.5rem 1rem;
border-radius: 1rem;
border: 1px solid rgba(0, 0, 0, 0.4);
outline: none;
}Clear everything in the App.tsx and get started with the code below.
//src/App.tsx
<main className="container">
<h1 className="title">Todos</h1>
</main>We can now add a form to our UI to begin adding todos to our application.
<form onSubmit={handleAddTodo} className="add__todo__form">
<Input inputProps={{ name: "todo", value: todo, onChange: handleOnChange }} />
<button type="submit" className="add__todo__button">
Add
</button>
</form>To update the todos we need to listen for changes in our input. We can save our values from the input in a useState React hook.
const [todo, setTodo] = useState("");Similarly, add the onChange function to add our todo.
const handleOnChange = (e: ChangeEvent<HTMLInputElement>) => {
const { value } = e.target;
setTodo(value);
};In this function, we listen for changes in the input and append the resulting value to our todo state using setTodo.
Similarly, the form will be submitted to the handleAddTodo function. Here, we prevent the default behavior of the browser and add todos to our setTodos useState hook.
const [todos, setTodos] = useState<{ title: string; completed: boolean }[]>([]);
const handleAddTodo = (e: SyntheticEvent) => {
e.preventDefault();
setTodos((prev) => [...prev, { title: todo, completed: false }]);
setTodo("");
};Continue by building tabs to view the remaining and completed todos. We can handle the state of our active tab by again using the useState React hook.
const [activeTab, setActiveTab] = useState("Remaining Todos");We can update the active tab value by listening to a click event in the tabs.
<div className="tabs__container">
{["Remaining Todos", "Completed Todos"].map((tab) => (
<button
key={tab}
className={`tabs__tab ${
activeTab === tab ? "tabs__tab__active" : ""
}`}
onClick={() => setActiveTab(tab)}
>
{tab}{" "}
{tab === "Remaining Todos"
? remainingTodos.length > 0 && `(${remainingTodos.length})`
: completedTodos.length > 0 && `(${completedTodos.length})`}
</button>
))}
</div>In the above onClick function we make use of the setActiveTab hook to update our activeTab value.
Now we can memoize our remaining and completed todos.
const remainingTodos = useMemo(() => {
return todos.filter((todo) => !todo.completed);
}, [todos]);
const completedTodos = useMemo(() => {
return todos.filter((todo) => todo.completed);
}, [todos]);Finally, render the list of our todos to the UI. Before, rendering the UI we must also check for the active tab state to get the active tab todos.
<ul className="todos__container">
{(activeTab === "Remaining Todos"
? remainingTodos
: completedTodos
).map((todo) => (
<li key={todo.title} className="todo__list__item">
<span className="todo__list__item__input__container">
<input
type="checkbox"
checked={todo.completed}
name={todo.title}
onChange={(e) => {
setTodos((prev) =>
prev.map((t) =>
t.title === todo.title
? { ...t, completed: e.target.checked }
: t
)
);
}}
/>
{todo.title}
</span>
<DeleteB
onClick={() => {
setTodos((prev) => prev.filter((t) => t.title !== todo.title));
}}
/>
</li>
))}
</ul>Add styles to the page.
//src/index.css
html,
body,
:root,
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.title {
font-size: 2.5rem;
font-weight: 900;
}
.add__todo__form {
display: flex;
align-items: flex-end;
gap: 1rem;
}
.add__todo__button {
padding: 0.5rem 1rem;
border-radius: 1.5rem;
border: none;
outline: none;
}
.container {
width: 25rem;
position: absolute;
top: 25%;
left: calc(50% - 10rem);
display: flex;
flex-direction: column;
gap: 1.25rem;
padding: 2rem 2.5rem;
border-radius: 2rem;
border: 1px solid rgb(58, 40, 216);
}
.todo__list__item {
list-style-type: none;
display: flex;
gap: 0.25rem;
align-items: center;
justify-content: space-between;
padding: 0.25rem 1rem;
}
.tabs__container {
display: flex;
align-items: center;
gap: 1rem;
}
.tabs__tab {
white-space: nowrap;
font-size: 1rem;
font-weight: 500;
outline: none;
border: none;
background: transparent;
}
.tabs__tab__active {
border-bottom: 1px solid blue;
}
.todos__container {
height: 20rem;
overflow-y: scroll;
}
.todo__list__item__input__container {
display: flex;
gap: 0.25rem;
align-items: center;
}Here, we created a to-do app in React using Vite and React hooks. You can now further update the UI and add additional functionalities to your to-do app to make it even better.