GitHub - SH20RAJ/codevisualiser: CodeVisualizer is an open-source platform where you can see how algorithms work, not just read about them.
Understand algorithms by watching them run — step-by-step animated visualizations for every major LeetCode problem, with multiple approaches and code in your language of choice.
What is this?
CodeVisualizer is an open-source platform where you can see how algorithms work, not just read about them. Every problem comes with:
- Animated step-by-step visualization — play, pause, step through, and control speed
- Multiple approaches — Brute Force → Optimal, with clear tradeoffs
- Code in every major language — Python, TypeScript, Java, C++, Go
- Plain English explanation — intuition first, complexity second
Built with Next.js 15 App Router, deployed globally on Cloudflare Pages.
Problems Covered
| # | Problem | Difficulty | Tags |
|---|---|---|---|
| 1 | Two Sum | Easy | Array, Hash Map |
| 704 | Binary Search | Easy | Binary Search |
| 21 | Merge Two Sorted Lists | Easy | Linked List |
| 102 | Binary Tree Level Order | Medium | BFS, Tree |
| 15 | 3Sum | Medium | Two Pointers |
| ... | more added regularly |
Don't see your problem? Request it or contribute it yourself.
Tech Stack
| Layer | Choice | Why |
|---|---|---|
| Framework | Next.js 15 App Router | Static export, fast routing |
| Animations | Framer Motion | Smooth, controllable step animations |
| Code highlighting | Shiki | Build-time, zero client JS |
| Styling | Tailwind CSS | Contributor-friendly utility classes |
| Prose | MDX | Rich explanations with embedded components |
| Search | Fuse.js | Fuzzy client-side search, no backend |
| Package manager | Bun | Fast installs |
| Deployment | Cloudflare Pages (OpenNext) | Global edge, free tier |
Getting Started
Prerequisites
- Bun v1.0+
- Node.js 20+
Local Development
# Clone the repo git clone https://github.com/SH20RAJ/codevisualiser.git cd codevisualiser # Install dependencies bun install # Start dev server bun run dev
Open http://localhost:3000 to see it.
Preview on Cloudflare Runtime
To test exactly how it'll behave on Cloudflare Pages before deploying:
Deploy
This builds the app with OpenNext and deploys to your Cloudflare Pages project via Wrangler.
Project Structure
codevisualiser/
├── src/
│ └── app/
│ ├── page.tsx ← Homepage
│ ├── problems/
│ │ ├── page.tsx ← Problem list + filters
│ │ └── [slug]/page.tsx ← Problem detail (viz + code)
│ └── tags/[tag]/page.tsx ← Problems by topic
│
├── components/
│ ├── ui/ ← CodeBlock, Tabs, Badges, StepController
│ ├── visualizations/ ← One folder per problem
│ │ ├── _base/ ← Reusable primitives (ArrayViz, TreeViz…)
│ │ ├── two-sum/index.tsx
│ │ └── binary-search/index.tsx
│ └── layouts/
│
├── data/
│ ├── problems/ ← Typed TS file per problem
│ │ ├── two-sum.ts
│ │ └── binary-search.ts
│ ├── index.ts ← Problem registry
│ ├── schema.ts ← TypeScript interfaces
│ └── categories.ts
│
├── content/
│ └── problems/ ← MDX explanation per problem
│ ├── two-sum.mdx
│ └── binary-search.mdx
│
├── next.config.ts
├── open-next.config.ts
└── wrangler.jsonc
Contributing
Contributions are the heart of this project. Adding a new problem is intentionally straightforward — you only need to touch 3 files.
Adding a New Problem
Step 1 — Data file (data/problems/[slug].ts)
Define the problem metadata, all approaches, and code snippets for every language:
import type { Problem } from '../schema' const problem: Problem = { id: 1, slug: 'two-sum', title: 'Two Sum', difficulty: 'Easy', tags: ['Array', 'Hash Table'], leetcodeUrl: 'https://leetcode.com/problems/two-sum/', approaches: [ { name: 'Brute Force', timeComplexity: 'O(n²)', spaceComplexity: 'O(1)', intuition: 'Check every pair of numbers until you find ones that sum to target.', codes: [ { language: 'python', code: `def twoSum(nums, target): for i in range(len(nums)): for j in range(i + 1, len(nums)): if nums[i] + nums[j] == target: return [i, j]`, }, // add more languages... ], }, { name: 'Hash Map', timeComplexity: 'O(n)', spaceComplexity: 'O(n)', intuition: 'Store each number\'s index in a map; for each number check if its complement already exists.', codes: [ /* ... */ ], }, ], visualizationComponent: 'TwoSumViz', hasVisualization: true, } export default problem
Step 2 — Visualization component (components/visualizations/[slug]/index.tsx)
Use the base primitives and the useVizStepper hook — you only need to implement buildSteps():
import { ArrayViz, HashMapViz } from '../_base' import { useVizStepper } from '@/lib/useVizStepper' import StepController from '@/components/ui/StepController' export function TwoSumViz() { const steps = buildSteps([2, 7, 11, 15], 9) const { step, controls } = useVizStepper(steps) return ( <div className="space-y-4"> <ArrayViz array={step.array} highlights={step.highlights} /> <HashMapViz map={step.hashMap} /> <p className="text-sm text-muted">{step.description}</p> <StepController {...controls} total={steps.length} /> </div> ) } function buildSteps(nums: number[], target: number) { // Return an array of step snapshots that the stepper will play through // Each step: { array, highlights, hashMap, description } }
Step 3 — Explanation prose (content/problems/[slug].mdx)
Write the explanation in MDX. You can use standard markdown plus any component from components/ui/:
## Intuition The naive approach checks every pair — that's O(n²). But we only need to check each number once if we store what we've already seen. ## The Hash Map insight For each number `x`, we need `target - x`. If we store every number we've visited in a hash map... <Callout type="tip"> The key insight: instead of looking forward for the complement, look backward — it might already be in the map. </Callout>
Step 4 — Register it in data/index.ts:
import twoSum from './problems/two-sum' export const problems = [ twoSum, // your new problem here ]
That's it. Open a PR and it's live.
Contribution Guidelines
- Keep visualizations accessible — every animation must have a step-through mode (no auto-play-only)
- Code snippets should be idiomatic for each language, not just translated from Python
- Explanations should start with intuition, not with code
- If a problem has multiple valid approaches, include all of them
- Test locally with
bun run previewbefore submitting
See CONTRIBUTING.md for the full guide including PR checklist and code style.
Requesting a Problem
Open an issue using the Problem Request template. Include the LeetCode problem number, link, and why a visualization would be especially helpful for it.
License
MIT — see LICENSE for details.
Author
Built by @SH20RAJ. If this helped you crack an interview or finally understand binary search, consider starring the repo.