Two interactive visualizations to run in your browser. No install needed.
App.js in the left sidebarCtrl+A) → delete → paste the codeWhat it shows:
Code file: kafka-flow-codesandbox.js
import { useState } from "react";
const styles = {
page: {
minHeight: "100vh",
backgroundColor: "#0a0a0f",
color: "white",
padding: "24px",
fontFamily: "sans-serif",
},
title: {
fontSize: "26px",
fontWeight: "bold",
textAlign: "center",
marginBottom: "6px",
},
subtitle: {
textAlign: "center",
color: "#9ca3af",
fontSize: "13px",
marginBottom: "32px",
},
row: {
display: "flex",
alignItems: "center",
justifyContent: "center",
gap: "12px",
flexWrap: "wrap",
marginBottom: "8px",
},
card: (bg, border) => ({
borderRadius: "14px",
border: `2px solid ${border}`,
backgroundColor: bg,
width: "170px",
overflow: "hidden",
cursor: "pointer",
transition: "transform 0.2s",
}),
cardHeader: (bg) => ({
backgroundColor: bg,
color: "black",
fontWeight: "bold",
textAlign: "center",
padding: "8px",
fontSize: "13px",
}),
cardBody: {
padding: "10px",
fontSize: "12px",
},
arrow: {
display: "flex",
flexDirection: "column",
alignItems: "center",
color: "#6b7280",
fontSize: "12px",
},
brokerCard: {
borderRadius: "14px",
border: "2px solid #facc15",
backgroundColor: "#1a1500",
width: "200px",
overflow: "hidden",
cursor: "pointer",
},
topicPill: {
backgroundColor: "#581c87",
border: "1px solid #a855f7",
borderRadius: "8px",
padding: "4px 10px",
fontSize: "11px",
color: "#e9d5ff",
textAlign: "center",
marginBottom: "4px",
},
zookeeperBox: {
border: "2px solid #4b5563",
backgroundColor: "#1f2937",
borderRadius: "14px",
padding: "10px 24px",
textAlign: "center",
fontSize: "13px",
color: "#d1d5db",
display: "inline-block",
},
stepBox: (active) => ({
display: "flex",
alignItems: "flex-start",
gap: "12px",
padding: "12px",
borderRadius: "14px",
border: active ? "2px solid #f97316" : "2px solid #374151",
backgroundColor: active ? "#431407" : "#1f2937",
cursor: "pointer",
transition: "all 0.2s",
transform: active ? "scale(1.02)" : "scale(1)",
}),
insightBox: {
marginTop: "16px",
backgroundColor: "#1c0a00",
border: "2px solid #f97316",
borderRadius: "14px",
padding: "16px",
fontSize: "13px",
color: "#fed7aa",
lineHeight: "1.6",
},
};
const zomatoSteps = [
{ icon: "🛵", text: "Customer places an order on Zomato app" },
{ icon: "📤", text: "App (Producer) sends 'Order Placed' event to Kafka" },
{ icon: "🖥️", text: "Broker receives and stores it in the orders-topic" },
{ icon: "📁", text: "orders-topic holds the message safely — even if DB is slow or down" },
{ icon: "💳", text: "Payment Service (Consumer) reads it → charges the customer" },
{ icon: "🍕", text: "Restaurant Service reads it → notifies the restaurant to start cooking" },
{ icon: "🔔", text: "Notification Service reads it → sends you a confirmation SMS" },
];
export default function KafkaFlow() {
const [activeStep, setActiveStep] = useState(null);
return (
<div style={styles.page}>
<h1 style={styles.title}>Kafka — How It All Fits Together</h1>
<p style={styles.subtitle}>Click each step in the Zomato flow to walk through it</p>
{/* Main Flow */}
<div style={styles.row}>
{/* Producer */}
<div style={styles.card("#0c1a2e", "#60a5fa")}>
<div style={styles.cardHeader("#60a5fa")}>📤 Producer</div>
<div style={{ ...styles.cardBody, color: "#bfdbfe" }}>
<p style={{ fontWeight: "bold", color: "white", marginBottom: "6px" }}>Sends data into Kafka</p>
<p>• Zomato App</p>
<p>• Driver App</p>
<p>• REST API</p>
<p>• IoT Sensor</p>
</div>
</div>
{/* Arrow */}
<div style={styles.arrow}>
<span style={{ fontSize: "22px" }}>→</span>
<span>writes to</span>
</div>
{/* Broker */}
<div style={styles.brokerCard}>
<div style={styles.cardHeader("#facc15")}>🖥️ Broker (Kafka Server)</div>
<div style={{ ...styles.cardBody, color: "#fef08a" }}>
<p style={{ fontWeight: "bold", color: "white", marginBottom: "6px" }}>Stores & manages messages</p>
<p style={{ color: "#9ca3af", fontSize: "11px", marginBottom: "6px" }}>Contains Topics:</p>
<div style={{ backgroundColor: "#1e0a3c", border: "1px solid #7c3aed", borderRadius: "10px", padding: "8px" }}>
<div style={styles.topicPill}>📁 orders-topic</div>
<div style={styles.topicPill}>📁 payments-topic</div>
<div style={styles.topicPill}>📁 location-topic</div>
</div>
</div>
</div>
{/* Arrow */}
<div style={styles.arrow}>
<span style={{ fontSize: "22px" }}>→</span>
<span>consumed by</span>
</div>
{/* Consumer */}
<div style={styles.card("#0a1f0f", "#4ade80")}>
<div style={styles.cardHeader("#4ade80")}>📥 Consumer</div>
<div style={{ ...styles.cardBody, color: "#bbf7d0" }}>
<p style={{ fontWeight: "bold", color: "white", marginBottom: "6px" }}>Reads data from topics</p>
<p>• Payment Service</p>
<p>• Restaurant Service</p>
<p>• Notification Service</p>
<p>• Analytics Dashboard</p>
</div>
</div>
</div>
{/* Zookeeper */}
<div style={{ display: "flex", justifyContent: "center", margin: "20px 0 32px" }}>
<div style={styles.zookeeperBox}>
⚙️ <strong>Zookeeper / KRaft</strong> — manages the cluster in the background (tracks brokers, handles failures)
</div>
</div>
{/* Zomato Steps */}
<div style={{ maxWidth: "620px", margin: "0 auto" }}>
<h2 style={{ fontSize: "18px", fontWeight: "bold", textAlign: "center", marginBottom: "6px" }}>🍕 Zomato Order — Step by Step</h2>
<p style={{ textAlign: "center", color: "#9ca3af", fontSize: "12px", marginBottom: "14px" }}>Click each step to highlight it</p>
<div style={{ display: "flex", flexDirection: "column", gap: "8px" }}>
{zomatoSteps.map((step, i) => (
<div
key={i}
style={styles.stepBox(activeStep === i)}
onClick={() => setActiveStep(activeStep === i ? null : i)}
>
<span style={{ fontSize: "20px" }}>{step.icon}</span>
<div>
<span style={{ color: "#6b7280", fontSize: "11px", marginRight: "6px" }}>Step {i + 1}</span>
<span style={{ fontSize: "13px", color: "white" }}>{step.text}</span>
</div>
</div>
))}
</div>
<div style={styles.insightBox}>
<p style={{ fontWeight: "bold", color: "#fb923c", marginBottom: "6px" }}>💡 Key Insight</p>
<p>
All 3 consumers (Payment, Restaurant, Notification) read from the <strong>same topic independently</strong>.
If one service goes down, Kafka holds the messages. It picks up right where it left off when it comes back.
<span style={{ color: "#86efac" }}> Nothing is ever lost.</span>
</p>
</div>
</div>
</div>
);
}
What it shows: