Welcome to my world!

Welcome to my world!

I'm a software engineer who cares deeply about clarity, usability, and getting the details right.

I'm a software engineer who cares deeply about clarity, usability, and getting the details right.

Brand Logo
Icon
1

<!--

Work info

-->

Company:

Independent Project

Role:

Full-Stack Software Engineer

Year:

2025

Work Image

Project Overview

This project focused on building an interactive sorting algorithm visualizer to make abstract algorithm behavior concrete and intuitive. Rather than treating sorting algorithms as purely theoretical or interview-style exercises, the goal was to surface what actually happens step by step—comparisons, swaps, and recursive structure—in a way that is visually and cognitively accessible.

The project emerged from my own experience struggling to build intuition around algorithms when learning them only through code or pseudocode. I wanted a tool that emphasized process over outcome, helping users understand why an algorithm behaves the way it does, not just that it eventually produces a sorted list.

Background & Motivation

Sorting algorithms are often taught as static code samples accompanied by time complexity charts. While useful, this approach hides the dynamic behavior that actually differentiates algorithms in practice.

I noticed that when learning or reviewing algorithms, my understanding improved significantly when I could:

  • see comparisons happening in real time

  • observe how data moves through the structure

  • connect algorithmic steps to performance characteristics

The visualizer was built to bridge that gap—turning invisible operations into something observable and explorable.

Problem Statement

The core problem was not implementing sorting algorithms themselves, but communicating their behavior clearly.

Specifically:

  • Algorithm steps are hard to reason about when hidden inside loops and recursion

  • Differences between algorithms are abstract without visual comparison

  • Many learning resources focus on correctness, not intuition

  • It’s easy to memorize algorithms without truly understanding them

The challenge was to design a system that made algorithm behavior understandable without oversimplifying it.

Approach & Constraints

Several constraints shaped the design:

  • Visualizations needed to be faithful to the actual algorithm logic

  • Animations had to reflect real operations (comparisons, swaps, merges)

  • The UI needed to stay simple and focused on learning

  • Performance optimizations should not obscure clarity

  • The system needed to support multiple algorithms without becoming brittle

Given these constraints, clarity and correctness were prioritized over visual flair.

Architecture & Technology Stack

The Sorting Algorithm Visualizer was built as a split frontend–backend system to keep visualization concerns separate from algorithm execution, while still allowing precise, step-by-step control.

Frontend Architecture

The frontend was implemented using React with TypeScript and Tailwind CSS. It was responsible for:

  • rendering the dataset as visual elements (e.g., bars or blocks)

  • animating comparisons, swaps, and structural changes

  • controlling playback (step, pause, reset)

  • synchronizing UI state with algorithm execution

State management was designed to reflect individual algorithm operations, not just array snapshots. This allowed the UI to highlight what operation was occurring (comparison, swap, merge) rather than only showing before/after states.

Tailwind CSS was used to keep styling minimal and consistent, ensuring the visual focus remained on algorithm behavior rather than UI chrome.

Backend Architecture

The backend was implemented using Java and Spring Boot, and was responsible for:

  • executing sorting algorithms deterministically

  • emitting step-by-step operation data (comparisons, swaps, partitions)

  • timing algorithm execution

  • returning structured responses suitable for animation

Algorithms were executed in memory, with each step exposed explicitly so the frontend could replay them faithfully. This separation ensured that visualization logic did not distort algorithm behavior.

The backend was containerized using Docker and deployed on Render, enabling consistent execution and realistic deployment conditions.

System Boundaries & Data Flow

At a high level:

  • the frontend requests a visualization run for a selected algorithm and dataset

  • the backend executes the algorithm and returns a sequence of operation steps

  • the frontend animates those steps in order, synchronizing visuals with algorithm intent

This architecture made it possible to:

  • validate correctness independently of visualization

  • support multiple algorithms without coupling UI logic to implementation details

  • reason about performance and timing separately from rendering

Key Decisions
Treat visualization as a first-class concern

Instead of writing algorithms first and “adding visuals later,” visualization was built into the algorithm execution itself.

Each algorithm step was surfaced explicitly so it could be:

  • animated

  • paused

  • reasoned about

This ensured the visual output reflected the true internal state of the algorithm at every step.

Emphasize operations, not just state

Rather than only showing the array before and after each step, the visualizer highlighted what operation was happening:

  • which elements were being compared

  • which elements were being swapped

  • how partitions or subarrays were formed

This helped users connect visual movement to algorithmic intent.

Support multiple algorithmic paradigms

The visualizer was designed to handle different classes of sorting algorithms, including:

  • comparison-based iterative algorithms

  • divide-and-conquer algorithms with recursion

This required different visualization strategies—especially for recursive algorithms—so users could see structure as well as movement.

Keep the UI intentionally minimal

The interface avoided unnecessary controls or configuration. The focus was on:

  • the data

  • the algorithm

  • the steps in between

This reduced cognitive load and kept attention on learning rather than interaction complexity.

Tradeoffs & Risks

Several tradeoffs were accepted:

  • Slower execution to allow step-by-step visualization

  • Additional state management to surface intermediate steps

  • Limited algorithm set to maintain clarity

These tradeoffs were intentional. The project optimized for understanding, not raw speed or breadth.

Results & Impact

The Sorting Algorithm Visualizer resulted in a functioning, deployed learning tool with measurable usage and performance characteristics.

Across live usage:

  • The visualizer supported 10+ sorting algorithms, including both iterative and divide-and-conquer approaches

  • Users triggered 500+ visualization runs, validating frontend–backend synchronization under repeated use

  • The Spring Boot backend consistently achieved sub-100 ms response times per algorithm step, ensuring smooth, responsive animations

  • Step-by-step execution and timing metrics made algorithm behavior and performance differences observable in practice

  • The system demonstrated reliable state synchronization between backend execution and frontend animation

Beyond usage metrics, the project achieved its primary goal: making algorithm behavior inspectable rather than abstract. By externalizing internal operations, the tool helped bridge the gap between code-level correctness and conceptual understanding.

For me personally, building the system materially improved my ability to reason about algorithms as processes rather than static solutions.

Reflections & Takeaways

This project reinforced several lessons:

  • Teaching tools require different design priorities than production systems

  • Visual feedback accelerates understanding

  • Correctness alone is insufficient for learning

  • Making internal state visible changes how problems are approached

It also highlighted how much of algorithmic difficulty comes from invisibility, not inherent complexity.

What I Intentionally Did Not Do

I avoided:

  • optimizing for large datasets at the cost of clarity

  • adding unnecessary controls or configuration

  • turning the project into a benchmarking tool

Keeping the scope focused allowed the visualizer to remain an effective learning aid rather than an overloaded demo.

Results

0

Sorting algorithms supported

0

Visualization runs triggered

0

Response time per algorithm step

Building and evolving production systems under real-world constraints

Social Icon
Social Icon

Building and evolving production systems under real-world constraints

Social Icon
Social Icon

Building and evolving production systems under real-world constraints

Social Icon
Social Icon