<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: mitali</title>
    <description>The latest articles on DEV Community by mitali (@kayleecodez).</description>
    <link>https://dev.to/kayleecodez</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3560694%2F9e65445b-a907-4616-a571-dfe26c862665.jpg</url>
      <title>DEV Community: mitali</title>
      <link>https://dev.to/kayleecodez</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kayleecodez"/>
    <language>en</language>
    <item>
      <title>I Thought Compilers Were Scary. So I Built Sauce.</title>
      <dc:creator>mitali</dc:creator>
      <pubDate>Sun, 28 Dec 2025 06:31:50 +0000</pubDate>
      <link>https://dev.to/kayleecodez/i-thought-compilers-were-scary-so-i-built-sauce-5j</link>
      <guid>https://dev.to/kayleecodez/i-thought-compilers-were-scary-so-i-built-sauce-5j</guid>
      <description>&lt;p&gt;I’ve been writing code for years. I type &lt;code&gt;cargo run&lt;/code&gt; or &lt;code&gt;npm start&lt;/code&gt;, hit enter, and meaningful things happen. But if you asked me what &lt;em&gt;actually&lt;/em&gt; happens between hitting enter and seeing "Hello World," I’d have mumbled something about "machine code" and changed the subject.&lt;/p&gt;

&lt;p&gt;That bothered me. I rely on these tools every day, but I didn't understand them.&lt;/p&gt;

&lt;p&gt;So I started building &lt;strong&gt;Sauce&lt;/strong&gt;, my own programming language in Rust. Not because the world needs another language, but because I needed to stop treating my compiler like a black box.&lt;/p&gt;

&lt;p&gt;Turns out, a language isn't magic. It's just a pipeline.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why We Think It's Hard
&lt;/h3&gt;

&lt;p&gt;We usually see a compiler as this big, scary brain that judges our code. You feed it text, and it either gives you a working program or yells at you with an error.&lt;/p&gt;

&lt;p&gt;I spent years thinking you needed to be a math genius to build one. I was wrong. You just need to break it down into small steps.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Sauce Actually Is
&lt;/h3&gt;

&lt;p&gt;Strip away the hype, and a programming language is just a way to move data around.&lt;/p&gt;

&lt;p&gt;Sauce is a statically typed language that feels like a simple script. I wanted something that was clear and honest. The core ideas are simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pipelines (&lt;code&gt;|&amp;gt;&lt;/code&gt;) are default:&lt;/strong&gt; Data flows explicitly from one step to the next, like a factory line.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Effects are explicit (&lt;code&gt;toss&lt;/code&gt;):&lt;/strong&gt; No hidden surprises or secret jumps in your code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But to get there, I had to build the engine. And thanks to Rust, I learned that the engine is actually pretty cool.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Architecture: It’s Just an Assembly Line
&lt;/h3&gt;

&lt;p&gt;I used to think compilation was one giant, messy function. In reality, it’s a disciplined process. I’m following a strict architecture for Sauce that separates "understanding the code" (Frontend) from "running the code" (Backend).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F438ke1lt2qvd98mcwn23.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F438ke1lt2qvd98mcwn23.png" alt="saucr architecture" width="800" height="359"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is exactly how Sauce works under the hood:&lt;/p&gt;

&lt;p&gt;The diagram above isn't just a sketch; it's the map I'm building against. It breaks down into two main phases.&lt;/p&gt;

&lt;h4&gt;
  
  
  Phase 1: Frontend (The Brain)
&lt;/h4&gt;

&lt;p&gt;This phase is all about understanding what you wrote. It doesn't run anything yet; it just reads and checks.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Lexer (Logos): The Chopping Block&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Job:&lt;/strong&gt; Computers don't read words; they read characters. The Lexer's job is to group those characters into meaningful chunks called "Tokens."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;In Plain English:&lt;/strong&gt; Imagine reading a sentence without spaces: &lt;code&gt;thequickbrownfox&lt;/code&gt;. It's hard. The Lexer adds the spaces and labels every word. It turns &lt;code&gt;grab x = 10&lt;/code&gt; into a list: &lt;code&gt;[Keyword(grab), Ident(x), Symbol(=), Int(10)]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Tool:&lt;/strong&gt; I used a Rust tool called &lt;strong&gt;Logos&lt;/strong&gt;. It’s incredibly fast, but I learned a hard lesson: computers are dumb. If you don't explicitly tell them that "grab" is a special keyword, they might think it's just a variable name like "green." You have to set strict rules.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Parser (Chumsky): The Grammar Police&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Job:&lt;/strong&gt; Now that we have a list of words (tokens), we need to check if they make a valid sentence. The Parser organizes these flat lists into a structured tree called the &lt;strong&gt;AST (Abstract Syntax Tree)&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;In Plain English:&lt;/strong&gt; A list of words like &lt;code&gt;[10, =, x, grab]&lt;/code&gt; contains valid words but makes no sense. The Parser ensures the order is correct (&lt;code&gt;grab x = 10&lt;/code&gt;) and builds a hierarchy: "This is a Variable Assignment. The name is 'x'. The value is '10'."&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Tool:&lt;/strong&gt; I used &lt;strong&gt;Chumsky&lt;/strong&gt;, which lets you build logic like LEGOs. You write a tiny function to read a number, another for a variable, and glue them together.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The "Aha!" Moment:&lt;/strong&gt; I learned how much structure matters. Instead of trying to parse everything in one giant loop, breaking the grammar into small, composable pieces made the language way easier to extend and reason about. It’s not magic; it’s just organizing data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Type Checking: The Logic Check&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Job:&lt;/strong&gt; Just because a sentence is grammatically correct doesn't mean it makes sense. "The sandwich ate the Tuesday" is a valid sentence, but it's nonsense. The Type Checker catches these logical errors.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;In Plain English:&lt;/strong&gt; If you write &lt;code&gt;grab x = "hello" + 5&lt;/code&gt;, the Parser says "Looks like a valid math operation!" But the Type Checker steps in and says, "Wait. You can't add a Word to a Number. That's illegal." Sauce currently has a small, explicit system that catches these basic mistakes before you ever try to run the code.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Phase 2: Backend (The Muscle)
&lt;/h4&gt;

&lt;p&gt;Once the Frontend gives the "thumbs up," we move to the Backend. This phase is about making the code actually run.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Codegen (Inkwell/LLVM): The Translator&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Job:&lt;/strong&gt; This is where we leave the high-level world of "Variables" and "Pipelines" and enter the low-level world of CPU instructions. We translate our AST into &lt;strong&gt;LLVM IR&lt;/strong&gt; (Intermediate Representation).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;In Plain English:&lt;/strong&gt; Sauce is like a high-level manager giving orders ("Calculate this pipeline"). The CPU is the worker who only understands basic tasks ("Move number to register A," "Add register A and B"). &lt;strong&gt;LLVM&lt;/strong&gt; is the translator that turns the manager's orders into the worker's checklist.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Why LLVM?&lt;/strong&gt; It's the same industrial-grade machinery that powers Rust, Swift, and C++. By using it, Sauce gets decades of optimization work for free. Once you figure out how to tell LLVM to "print a number," the rest stops feeling so scary.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Native Binary: The Final Product&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Job:&lt;/strong&gt; The final step is bundling all those CPU instructions into a standalone file (like an &lt;code&gt;.exe&lt;/code&gt; on Windows or a binary on Linux).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;In Plain English:&lt;/strong&gt; This is what lets you send your program to a friend. They don't need to install Sauce, Rust, or anything else. They just double-click the file, and it runs. (Currently, this works for simple, effect-free programs).&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  What Works Right Now (v0.1.0)
&lt;/h3&gt;

&lt;p&gt;Sauce isn't just an idea anymore. The core compiler pipeline is alive.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pipelines:&lt;/strong&gt; You can write &lt;code&gt;grab x = 10 |&amp;gt; _&lt;/code&gt; and it understands it perfectly. The data flows left-to-right, just like reading a sentence.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real Output:&lt;/strong&gt; I can feed it real &lt;code&gt;.sauce&lt;/code&gt; source code, and it parses it into a type-safe syntax tree.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Explicit Effects:&lt;/strong&gt; You can use &lt;code&gt;toss&lt;/code&gt; to signal a side effect. This currently works in the interpreter, while the LLVM backend intentionally rejects effects for now.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Road Ahead
&lt;/h3&gt;

&lt;p&gt;I have a clear plan for where this is going. Since the core architecture is stable, the next updates are about making it usable.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;v0.1.x (UX):&lt;/strong&gt; Right now, if you make a mistake, the error messages are a bit cryptic. I'm adding a tool called &lt;strong&gt;Ariadne&lt;/strong&gt; to give pretty, helpful error reports (like Rust does).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;v0.2.0 (Effects):&lt;/strong&gt; This is the big one. I'll be finalizing how "Effects" work—defining rules for when you can resume a program after an error and when you have to abort.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;v0.3.0 (Runtime):&lt;/strong&gt; Merging the Interpreter and LLVM worlds so they behave exactly the same, plus adding a standard library so you can do more than just print numbers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why You Should Try This
&lt;/h3&gt;

&lt;p&gt;I avoided building a language for years because I thought I wasn't smart enough.&lt;/p&gt;

&lt;p&gt;But building Sauce taught me that there's no magic. It's just data structures. A Lexer is just regex. A Parser is just a tree builder. An Interpreter is just a function that walks through that tree.&lt;/p&gt;

&lt;p&gt;If you want to actually understand how your code runs, don't just read a book. Build a tiny, broken compiler. Create a Lexer. Define a simple tree. Parse &lt;code&gt;1 + 1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You'll learn more in a weekend of fighting syntax errors than you will in a year of just using &lt;code&gt;cargo run&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Check out &lt;a href="https://github.com/Kayleexx/sauce" rel="noopener noreferrer"&gt;Sauce on GitHub&lt;/a&gt;. It's small, it's honest, and we are officially cooking. &lt;/p&gt;

</description>
      <category>rust</category>
      <category>programming</category>
      <category>showdev</category>
      <category>compiling</category>
    </item>
    <item>
      <title>Building Conflux - My Own Real-time Collaboration Engine in Rust</title>
      <dc:creator>mitali</dc:creator>
      <pubDate>Thu, 13 Nov 2025 07:09:28 +0000</pubDate>
      <link>https://dev.to/kayleecodez/building-conflux-my-own-real-time-collaboration-engine-in-rust-41lm</link>
      <guid>https://dev.to/kayleecodez/building-conflux-my-own-real-time-collaboration-engine-in-rust-41lm</guid>
      <description>&lt;p&gt;I’ve always used real-time tools without thinking too much about how they actually work. Google Docs, Figma, Replit multiplayer, VSCode Live Share… you type something, the other person sees it instantly, nothing breaks, nobody overwrites anybody else. It... just works.&lt;/p&gt;

&lt;p&gt;And for some reason, I kept wondering what’s happening under the hood. How does one person’s change mysteriously appear everywhere? How are conflicts handled? What happens if two people change the same thing at the same time?&lt;/p&gt;

&lt;p&gt;I didn’t want the “high-level” answer. I wanted to &lt;em&gt;feel&lt;/em&gt; the system. The same way building &lt;a href="https://github.com/Kayleexx/veridian" rel="noopener noreferrer"&gt;&lt;strong&gt;Veridian&lt;/strong&gt;&lt;/a&gt; helped me understand Git, I wanted to understand these real-time sync systems by building one myself.&lt;/p&gt;

&lt;p&gt;So I built &lt;strong&gt;Conflux&lt;/strong&gt;, a small real-time collaboration engine written in Rust. Not because the world needs another backend, but because &lt;em&gt;I&lt;/em&gt; needed to understand how these real-time systems actually sync state between multiple users without blowing up.&lt;/p&gt;

&lt;p&gt;Turns out, it’s not some mysterious technology. It’s a bunch of simple ideas stacked cleanly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why I Wanted to Build This
&lt;/h3&gt;

&lt;p&gt;Whenever I saw people editing the same thing at once, my brain just assumed, “Okay, some mysterious library is doing something complicated.” But then I learned about &lt;strong&gt;CRDTs&lt;/strong&gt;, and the whole idea clicked.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;CRDT (Conflict-free Replicated Data Type)&lt;/strong&gt; is basically a data structure that &lt;em&gt;never conflicts&lt;/em&gt;. Every update is mergeable. Everyone can edit freely without locking. And eventually, everything converges to the same state.&lt;/p&gt;

&lt;p&gt;When I realized that, I wanted to see it for myself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What does a CRDT-based collaboration system &lt;em&gt;actually&lt;/em&gt; look like when you implement it?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The "Real Stuff" Behind It: What is a CRDT?
&lt;/h3&gt;

&lt;p&gt;Okay, let's break this down. The "Conflict-free" part is what matters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The "Normal" Way (The Problem):&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Imagine you and I are editing a text file.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; We both download the file. It says: &lt;code&gt;"Hello"&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; I change my copy to: &lt;code&gt;"Hello world"&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; You, at the &lt;em&gt;exact same time&lt;/em&gt;, change your copy to: &lt;code&gt;"Hello there"&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; I upload my version. The server now has &lt;code&gt;"Hello world"&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; You upload your version. The server now has &lt;code&gt;"Hello there"&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;My change is &lt;strong&gt;gone&lt;/strong&gt;. Forever. You overwrote me. This is a &lt;strong&gt;conflict&lt;/strong&gt;. This is what version control systems like Git spend all their time trying to manage with "merge conflicts."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The "CRDT" Way (The Solution):&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;CRDTs don't work like that. They don't send the &lt;em&gt;whole file&lt;/em&gt; back and forth. They send &lt;em&gt;instructions&lt;/em&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; We both have the state: &lt;code&gt;"Hello"&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; I make a change. My local CRDT doesn't say "the new file is 'Hello world'". It generates an &lt;em&gt;instruction&lt;/em&gt;: &lt;code&gt;(At position 5, add: " world")&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; You, at the same time, make a change. Your CRDT generates an &lt;em&gt;instruction&lt;/em&gt;: &lt;code&gt;(At position 5, add: " there")&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; I send my instruction to the server.&lt;/li&gt;
&lt;li&gt; You send your instruction to the server.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The server, and eventually all clients, get &lt;em&gt;both&lt;/em&gt; instructions. The "aura" of the CRDT is that it has a mathematical rule for merging these instructions so that &lt;strong&gt;everyone ends up with the exact same final state&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The final text might be &lt;code&gt;"Hello world there"&lt;/code&gt; or &lt;code&gt;"Hello there world"&lt;/code&gt;. What's important is that &lt;strong&gt;no data was lost&lt;/strong&gt;, and &lt;strong&gt;we both end up seeing the same thing&lt;/strong&gt; without ever getting a "MERGE CONFLICT" error.&lt;/p&gt;

&lt;p&gt;That's it. A CRDT is just a data structure with a "merge" algorithm so good that it &lt;em&gt;never&lt;/em&gt; conflicts.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Conflux Actually Does
&lt;/h3&gt;

&lt;p&gt;Now that we know what a CRDT is, the whole system makes more sense.&lt;/p&gt;

&lt;p&gt;Strip away the extra details, and Conflux does three simple things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; It maintains &lt;strong&gt;rooms&lt;/strong&gt; – like “documents” or “sessions.”&lt;/li&gt;
&lt;li&gt; Each room contains a &lt;strong&gt;CRDT document&lt;/strong&gt; – this stores the shared state.&lt;/li&gt;
&lt;li&gt; Clients send &lt;em&gt;instructions&lt;/em&gt; (updates), the server merges them, and it broadcasts them to everyone else.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here’s that same loop, but now it makes sense:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You type something → your local CRDT generates an &lt;em&gt;instruction&lt;/em&gt; → you send that &lt;em&gt;instruction&lt;/em&gt; (the "update") to the server → the server merges it into its own CRDT → the server broadcasts that &lt;em&gt;instruction&lt;/em&gt; to all other clients → their local CRDTs merge it → everyone's UI updates.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That’s it. That’s the entire loop. No fancy algorithm, no weird transformations, no branching timelines.&lt;/p&gt;

&lt;p&gt;Just: &lt;strong&gt;update → merge → broadcast.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And because CRDTs are designed to merge cleanly, nothing conflicts.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Architecture (Simple Version)
&lt;/h3&gt;

&lt;p&gt;To make it easier to understand, I drew it out:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fllkpax60vkkun9fhd3zc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fllkpax60vkkun9fhd3zc.png" alt="Conflux Architecture" width="800" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Every box in this diagram has one job. No box is doing five things at once. And that simplicity is what made the whole system feel approachable.&lt;/p&gt;

&lt;h3&gt;
  
  
  How the Server is Designed
&lt;/h3&gt;

&lt;p&gt;The Conflux server has four main pieces, and each one does exactly one job.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Room Manager
&lt;/h4&gt;

&lt;p&gt;This is the part that keeps track of all active rooms.&lt;/p&gt;

&lt;p&gt;If a room doesn’t exist, it creates it. If a room is idle for too long, it cleans it up.&lt;/p&gt;

&lt;p&gt;Nothing fancy - just lifecycle management.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Room (Actor Loop)
&lt;/h4&gt;

&lt;p&gt;A room is basically its own mini-server.&lt;/p&gt;

&lt;p&gt;It runs a loop that just listens for commands like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ApplyUpdate&lt;/code&gt; (This is our CRDT &lt;em&gt;instruction&lt;/em&gt;!)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SetAwareness&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Chat&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Join&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Leave&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;...and it applies those updates to its own YDoc.&lt;/p&gt;

&lt;p&gt;This “actor” design means each room is isolated, which avoids the usual shared-state chaos.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. WebSocket Server
&lt;/h4&gt;

&lt;p&gt;This is the entry point.&lt;/p&gt;

&lt;p&gt;It:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authenticates users using JWT.&lt;/li&gt;
&lt;li&gt;Extracts the room ID from the URL.&lt;/li&gt;
&lt;li&gt;Upgrades the connection to a WebSocket.&lt;/li&gt;
&lt;li&gt;Forwards incoming messages to the correct room.&lt;/li&gt;
&lt;li&gt;Forwards outgoing messages from the room back to the client.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It accepts two types of messages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Plain text:&lt;/strong&gt; This becomes a chat message.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JSON:&lt;/strong&gt; This becomes a structured CRDT or awareness update.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes debugging easy because you can literally type chat messages from a terminal.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. JWT Authentication
&lt;/h4&gt;

&lt;p&gt;Every login creates a new session ID (&lt;code&gt;sid&lt;/code&gt;) inside the token.&lt;/p&gt;

&lt;p&gt;This fixes the “everyone logs in with the same token” problem.&lt;br&gt;
When a client connects, the server knows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which user&lt;/li&gt;
&lt;li&gt;Which session&lt;/li&gt;
&lt;li&gt;Which room&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s simple, but it gives a clean identity model.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Sync Flow (Easy Explanation)
&lt;/h3&gt;

&lt;p&gt;Let’s say two people are editing a shared document.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Person A edits something.&lt;/strong&gt;
Their local CRDT applies the change instantly and generates an &lt;em&gt;instruction&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;A sends the instruction (the update) to the server.&lt;/strong&gt;
This is just a small binary chunk.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Server applies the instruction to its own CRDT.&lt;/strong&gt;
This keeps the server's copy of the document authoritative.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Server broadcasts the instruction.&lt;/strong&gt;
All &lt;em&gt;other&lt;/em&gt; clients in that room receive the same update.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Each client applies it.&lt;/strong&gt;
Their local CRDT merges the instruction into whatever they already have.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Everyone stays in sync.&lt;/strong&gt;
Even if many people change the same thing at the same time, the CRDT handles the merges smoothly.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It sounds complicated, but seeing it work makes it feel simple.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Awareness and Chat Matter
&lt;/h3&gt;

&lt;p&gt;Real-time systems aren’t just about document content.&lt;/p&gt;

&lt;p&gt;Users need to know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Who else is online&lt;/li&gt;
&lt;li&gt;Where their cursor is&lt;/li&gt;
&lt;li&gt;Who is typing&lt;/li&gt;
&lt;li&gt;Who joined or left&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So I added “awareness events.” These are just tiny JSON messages that propagate instantly to show who's who and who's where.&lt;/p&gt;

&lt;p&gt;Chat was simple - if the client sends normal text instead of JSON, the server treats it as a chat message and broadcasts it.&lt;/p&gt;

&lt;p&gt;It's a small feature, but it makes the system feel alive.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Dashboard
&lt;/h3&gt;

&lt;p&gt;I also built a small dashboard endpoint:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;GET /dashboard&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This returns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Room ID&lt;/li&gt;
&lt;li&gt;Number of connected clients&lt;/li&gt;
&lt;li&gt;Number of document updates&lt;/li&gt;
&lt;li&gt;Number of awareness events&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s nothing fancy, but it’s incredibly useful to &lt;em&gt;see&lt;/em&gt; the system working.&lt;/p&gt;

&lt;h3&gt;
  
  
  What I Learned From Building This
&lt;/h3&gt;

&lt;p&gt;Just like Veridian made Git click for me, Conflux made real-time collaboration click.&lt;/p&gt;

&lt;p&gt;Here are the things that stood out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Real-time sync is mostly about &lt;strong&gt;message ordering and broadcasting.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;CRDTs remove &lt;strong&gt;like 90%&lt;/strong&gt; of the “conflict” problems.&lt;/li&gt;
&lt;li&gt;Actor-style rooms make concurrency &lt;strong&gt;surprisingly clean.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;WebSockets are &lt;strong&gt;way easier&lt;/strong&gt; to work with than I expected.&lt;/li&gt;
&lt;li&gt;Having a proper &lt;strong&gt;identity system&lt;/strong&gt; early saves headaches later.&lt;/li&gt;
&lt;li&gt;Most “complex systems” are just a &lt;strong&gt;chain of simple steps.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Before building Conflux, these systems felt like black boxes.&lt;/p&gt;

&lt;p&gt;After building it, they feel like something I can understand - and even improve.&lt;/p&gt;

&lt;h3&gt;
  
  
  Closing Thoughts
&lt;/h3&gt;

&lt;p&gt;Conflux isn’t perfect. It’s probably missing features. It's &lt;em&gt;definitely&lt;/em&gt; not production-ready. But it does exactly what I built it for and it helped me understand how real-time collaboration works under the hood.&lt;/p&gt;

&lt;p&gt;If you’re curious about this stuff, try building a small version yourself.&lt;/p&gt;

&lt;p&gt;You don’t need to recreate Google Docs. Even a tiny CRDT-based shared counter will teach you a lot.&lt;/p&gt;

&lt;p&gt;You can check out Conflux here:&lt;br&gt;
&lt;a href="https://github.com/Kayleexx/conflux" rel="noopener noreferrer"&gt;https://github.com/Kayleexx/conflux&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’ll keep improving it, and I’ll probably write more about the deeper parts later.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>showdev</category>
      <category>websocket</category>
      <category>backend</category>
    </item>
    <item>
      <title>I Built My Own Git in Rust to Understand Version Control</title>
      <dc:creator>mitali</dc:creator>
      <pubDate>Sun, 12 Oct 2025 15:33:06 +0000</pubDate>
      <link>https://dev.to/kayleecodez/i-built-git-from-scratch-to-finally-understand-what-ive-been-using-for-years-37a9</link>
      <guid>https://dev.to/kayleecodez/i-built-git-from-scratch-to-finally-understand-what-ive-been-using-for-years-37a9</guid>
      <description>&lt;p&gt;I've been using Git for years. Committing, pushing, pulling, occasionally panicking when things break. But if you'd asked me what actually happens when I run &lt;code&gt;git commit&lt;/code&gt;, I'd have given you some vague answer about "saving changes" and hoped you wouldn't ask more questions.&lt;/p&gt;

&lt;p&gt;That bothered me. So I built &lt;a href="https://github.com/Kayleexx/veridian" rel="noopener noreferrer"&gt;Veridian&lt;/a&gt;, my own version control system in Rust. Not because the world needs another Git, but because I needed to understand the one we already have.&lt;/p&gt;

&lt;p&gt;Turns out, Git is way simpler than I thought.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Everyone Finds Git Confusing
&lt;/h2&gt;

&lt;p&gt;We learn Git backwards. We memorize commands without understanding what they do. &lt;code&gt;git add&lt;/code&gt; stages files. Okay, but what does staging actually mean? &lt;code&gt;git commit&lt;/code&gt; saves your work. Cool, but saves it where and how?&lt;/p&gt;

&lt;p&gt;I spent years just following commands. I could use Git, but I couldn't understand it. Building Veridian changed that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Here's What Git Actually Is
&lt;/h2&gt;

&lt;p&gt;Strip away all the commands and features, and Git is just a content-addressable storage system. Sounds complicated, but it's not.&lt;/p&gt;

&lt;p&gt;You have a storage system where things are saved by their content, not their name. Put in the same content twice? Same storage location. Change one character? Different location.&lt;/p&gt;

&lt;p&gt;That's Git. The "location" is a SHA-1 hash. The "storage" is the &lt;code&gt;.git/objects&lt;/code&gt; folder.&lt;/p&gt;

&lt;h3&gt;
  
  
  Three Types of Objects
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Blobs&lt;/strong&gt; are file contents. Take your file, add a header like &lt;code&gt;blob &amp;lt;size&amp;gt;\0&lt;/code&gt;, hash it, compress it, store it. Done. Git doesn't care about filenames here. Only content.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trees&lt;/strong&gt; are directory listings. They say "here's what this folder looked like" by listing files and folders with their hashes. Trees point to blobs and other trees.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Commits&lt;/strong&gt; are snapshots with context. Each commit points to a tree (what your project looked like), points to parent commits (what came before), and has metadata like author, time, and message.&lt;/p&gt;

&lt;p&gt;Three object types. That's the whole system.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why the Hash System is Smart
&lt;/h3&gt;

&lt;p&gt;Same file in multiple commits? Stored once. Changed one line in a big file? Only the new version gets stored. Want to check if two files are identical? Compare hashes, instant answer.&lt;/p&gt;

&lt;p&gt;Git isn't making copies of your project over and over. It's storing unique pieces and building snapshots from them. That's why repos with hundreds of commits aren't huge.&lt;/p&gt;

&lt;h3&gt;
  
  
  Branches Are Just Files
&lt;/h3&gt;

&lt;p&gt;A branch is literally a file with a commit hash in it.&lt;/p&gt;

&lt;p&gt;The file &lt;code&gt;.git/refs/heads/main&lt;/code&gt; has 40 characters in it, the hash of your latest commit. When you make a branch, Git writes a new file with the current commit hash. When you commit, Git updates the file with the new hash.&lt;/p&gt;

&lt;p&gt;No copying. Just updating a small text file. That's why branches are "lightweight."&lt;/p&gt;

&lt;h3&gt;
  
  
  The Compression Part is Cool
&lt;/h3&gt;

&lt;p&gt;Git uses zlib to compress everything before storing it. So your object files aren't just raw content, they're compressed. When I was building Veridian, I had to handle this compression and decompression for every read and write.&lt;/p&gt;

&lt;p&gt;Here's what happens: Git takes your blob (with header), compresses it, then stores it in &lt;code&gt;.git/objects/ab/cdef123...&lt;/code&gt; where &lt;code&gt;ab&lt;/code&gt; is the first two characters of the hash and &lt;code&gt;cdef123...&lt;/code&gt; is the rest. The two-character split is just to avoid having thousands of files in one directory, which would slow down file systems.&lt;/p&gt;

&lt;p&gt;Reading it back means finding the file, decompressing with zlib, parsing the header to check object type and size, then giving you the content. Rust's standard library doesn't have zlib built in, so I used the &lt;code&gt;flate2&lt;/code&gt; crate for this. Took like 5 lines of code.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Building Veridian Taught Me
&lt;/h2&gt;

&lt;p&gt;I thought building a version control system would be hard. It wasn't.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkvxrekylocap5m6beuah.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkvxrekylocap5m6beuah.png" alt="Veridian Architecture" width="800" height="409"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Building in Rust was interesting because Rust makes you think about memory and ownership. When you're hashing files and building trees, you need to handle errors properly (what if the file doesn't exist?) and manage buffers carefully (you can't just load a 5GB file into memory).&lt;/p&gt;

&lt;p&gt;But honestly, the version control logic itself is simple. Most of my code is just reading files, computing SHA-1 hashes, and writing compressed data. The hard part wasn't the algorithm, it was understanding what Git was actually doing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Init Command
&lt;/h3&gt;

&lt;p&gt;Make a &lt;code&gt;.veridian&lt;/code&gt; folder. Add subfolders for objects and refs. Create a HEAD file. Done, you have a repo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hash-Object Command
&lt;/h3&gt;

&lt;p&gt;Read file, add header, hash it with SHA-1, compress with zlib, write to &lt;code&gt;.veridian/objects/&lt;/code&gt;. Return the hash. That's how files enter the system.&lt;/p&gt;

&lt;h3&gt;
  
  
  Write-Tree Command
&lt;/h3&gt;

&lt;p&gt;Go through a directory. Hash every file (making blobs). Put all the names and hashes into a tree object. Hash that tree. Now you have a snapshot of your directory.&lt;/p&gt;

&lt;p&gt;One thing I learned: tree entries need to be sorted by filename. If you don't sort them, the same directory structure produces different hashes depending on the order you process files. Git sorts them to keep hashes consistent. Small detail, but it matters.&lt;/p&gt;

&lt;h3&gt;
  
  
  Commit-Tree Command
&lt;/h3&gt;

&lt;p&gt;Take a tree hash. Add parent commit hash if there is one. Add author info and time. Add message. Hash it all. Write to objects. Update branch pointer. Update HEAD. That's a commit.&lt;/p&gt;

&lt;p&gt;The implementation is surprisingly small.It works like Git because Git is actually this simple.&lt;/p&gt;

&lt;p&gt;Fun fact: Git stores timestamps as Unix timestamps (seconds since 1970) with timezone info. So a commit object has something like &lt;code&gt;1760211794 +0530&lt;/code&gt; which is the timestamp and timezone offset. When you &lt;code&gt;git commit&lt;/code&gt;, it grabs your system time and timezone. I used Rust's &lt;code&gt;chrono&lt;/code&gt; crate for this, but you could do it with any language.&lt;/p&gt;

&lt;h2&gt;
  
  
  Things That Finally Clicked
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Why Git is fast:&lt;/strong&gt; It compares hashes, not file contents. 40 character strings. Super quick.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why detached HEAD happens:&lt;/strong&gt; HEAD normally points to a branch file, which points to a commit. Check out a commit directly? HEAD points at the commit, skipping the branch. You're detached because you're not on a branch, you're on a specific commit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why you can recover deleted commits:&lt;/strong&gt; They're still in &lt;code&gt;.git/objects&lt;/code&gt;. Just unreferenced. Use &lt;code&gt;git reflog&lt;/code&gt;, find the hash, get it back. Only garbage collection deletes them for real.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why merge conflicts exist:&lt;/strong&gt; Two commits have the same parent but different changes to the same file. Git can't pick which one wins. It needs you to decide.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;p&gt;Git isn't hard because it's complicated. It's hard because we learn it wrong.&lt;/p&gt;

&lt;p&gt;Once you get that Git is a key-value store where the key is a content hash, and there are three types of values (blob, tree, commit), everything makes sense. Branches are pointers. Merging combines trees. Rebasing replays commits on a different parent.&lt;/p&gt;

&lt;p&gt;I used Git for years without getting it. Then I built Veridian in a week and suddenly Git made sense. Not because building is magic, but because it forces you to understand what's happening.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why You Should Try This
&lt;/h2&gt;

&lt;p&gt;You don't need to build something perfect. Just start.&lt;/p&gt;

&lt;p&gt;Make a repo. Store a file as a blob. Build a tree. Make a commit. Do those four things and you'll understand Git better than most developers.&lt;/p&gt;

&lt;p&gt;Building Veridian took maybe a week. Now when I use Git, I actually know what's happening. It's just data structures and file operations. Nothing complicated.&lt;/p&gt;

&lt;p&gt;Veridian isn't perfect. It's missing features. Probably has bugs. But it taught me how Git works, and that was the point.&lt;/p&gt;

&lt;p&gt;If you want to actually learn Git, not just use it, build something. Even if it's small. Even if it breaks. You'll learn more building for a week than reading docs for months.&lt;/p&gt;

&lt;p&gt;Check out &lt;a href="https://github.com/Kayleexx/veridian" rel="noopener noreferrer"&gt;Veridian on GitHub&lt;/a&gt;. Break it, fix it, learn from it. That's how this works.&lt;/p&gt;

</description>
      <category>git</category>
      <category>rust</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
