<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged sideproject</title>
<link>https://coderlegion.com/tag/sideproject</link>
<description>Powered by Question2Answer</description>
<item>
<title>A $1 market for side projects – first 100 listings free</title>
<link>https://coderlegion.com/26324/a-1-market-for-side-projects-first-100-listings-free</link>
<description>&lt;p&gt;Hey everyone,&lt;/p&gt;
&lt;p&gt;I'm running a small experiment called AgentShare Market.&lt;/p&gt;
&lt;p&gt;The idea is dead simple: you list your web app, tool, or API for $1. People browse. If someone wants it, they reach out. That's it.&lt;/p&gt;
&lt;p&gt;No chat, no escrow, no promises. Just a board for the curious.&lt;/p&gt;
&lt;p&gt;Why?&lt;br&gt;
I've noticed a lot of vibe coders and indie makers building cool stuff but struggling to get any traction. This is a low-friction way to put your project out there and see if anyone bites.&lt;/p&gt;
&lt;p&gt;First 100 listings are FREE to test the waters.&lt;/p&gt;
&lt;p&gt;If you've got a side project collecting dust, give it a shot: &lt;a rel=&quot;nofollow&quot; href=&quot;https://agentshare.dev/market&quot;&gt;https://agentshare.dev/market&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Would you ever buy or sell a side project? Curious to hear your thoughts.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/26324/a-1-market-for-side-projects-first-100-listings-free</guid>
<pubDate>Sun, 06 Sep 2026 14:45:32 +0000</pubDate>
</item>
<item>
<title>Building MOT History Free: a UK vehicle history checker on Next.js + DVSA's API</title>
<link>https://coderlegion.com/24341/building-mot-history-free-a-uk-vehicle-history-checker-on-next-js-dvsas-api</link>
<description>&lt;p&gt;I've spent the last few months building MOT History Free, a UK vehicle history checker — think &quot;paste your number plate, get the full MOT/tax/mileage story&quot; — and wanted to share some of the technical decisions behind it.&lt;/p&gt;
&lt;p&gt;The problem&lt;/p&gt;
&lt;p&gt;The UK government exposes a free &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.mothistoryfree.co.uk/MOT-history-check&quot;&gt;MOT history&lt;/a&gt; API (DVSA), and most &quot;MOT checker&quot; sites are just thin wrappers around it with heavy ads. I wanted to build something that goes further: cross-referencing mileage anomalies (the classic &quot;ghost MOT&quot; fraud pattern — a car skipping an expected test, or mileage that quietly drops between records), tax/SORN status, and V5C logbook history, packaged into one report instead of five different gov.uk lookups.&lt;/p&gt;
&lt;p&gt;Stack&lt;/p&gt;
&lt;p&gt;Next.js (App Router) on the frontend, server actions for the pre-check flow&lt;br&gt;
A guest checkout flow with PayPal — no account required, £0.99 per report&lt;br&gt;
The trickiest part wasn't the report itself, it was the payment UX: PayPal's Buttons() component renders a cross-origin iframe for card fields, which means zero CSS control over anything inside it (learned that one the hard way — spent an evening trying to override an inline color on their legal disclaimer text before realizing it's a different document entirely). If you need actual style control over card fields, CardFields() (Advanced Card Payments) is the only path — hosted fields you can theme, versus the all-in-one iframe you can't touch.&lt;/p&gt;
&lt;p&gt;Conversion detail worth sharing&lt;/p&gt;
&lt;p&gt;Instead of a generic &quot;here's what you get&quot; bullet list before checkout, I show a locked/blurred preview of real report fields (tax status, MOT expiry, last V5C issue date, etc.) with a lock icon over each — same pattern as LinkedIn's &quot;who viewed your profile.&quot; Concrete-looking blurred data converts noticeably better than abstract feature descriptions, because the brain registers &quot;there's a real answer here&quot; instead of &quot;here's a list of promises.&quot;&lt;/p&gt;
&lt;p&gt;What's next&lt;/p&gt;
&lt;p&gt;Working on surfacing mileage-rollback detection more prominently in the free pre-check, since that's the single biggest &quot;oh, I need this&quot; moment for most visitors before they even see the paywall.&lt;/p&gt;
&lt;p&gt;Happy to go deeper on the DVSA API integration or the PayPal guest-checkout flow if anyone's curious — AMA in the comments.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/24341/building-mot-history-free-a-uk-vehicle-history-checker-on-next-js-dvsas-api</guid>
<pubDate>Sun, 09 Aug 2026 16:58:35 +0000</pubDate>
</item>
<item>
<title>I added a full analytics dashboard to my GitHub solar system visualizer</title>
<link>https://coderlegion.com/14615/i-added-a-full-analytics-dashboard-to-my-github-solar-system-visualizer</link>
<description>&lt;p&gt;Phase 7 of Stack Universe just shipped. The solar system is still there. Now there is a clean analytics dashboard sitting behind it showing everything the planets communicate visually but in graphs and charts a manager or recruiter can actually read.&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://stack-universe.vercel.app&quot;&gt;→ Stack Universe&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/buy3go7lhydygmadfpbn.jpeg&quot; alt=&quot;Image description&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Quick context if you are new&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Stack Universe&lt;/strong&gt; turns any GitHub username into a unique 3D solar system. Repos are planets sized by star count orbiting at speeds from last push date. Commit messages float on shooting stars. CI/CD runs are live space weather. Failing builds crack your planets. Deploy streaks build golden auras. Every developer gets a permanent URL as their coordinate in the multiverse.&lt;/p&gt;
&lt;p&gt;Previous phases added repo health scores, GitHub Actions weather, OAuth to claim your universe, README embeds, a full AI layer with roast mode and developer identity, a flyable spaceship through the multiverse, constellation maps, multiplayer presence, and universe radio.&lt;/p&gt;
&lt;p&gt;Phase 7 gives all that data a professional face.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What shipped in Phase 7&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Click the &lt;strong&gt;ANALYTICS&lt;/strong&gt; button in the HUD and a full screen dashboard slides open. Six tabs. Every tab is a different lens on your GitHub data.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Overview tab&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Two arc gauges sit at the center. Universe score in gold showing your exact score with the distance tier label underneath it. System health in cyan showing your 0 to 100 health score. Below both gauges a stats row shows total stars, repo count, language count, current streak, account age, and universe score all in one line&lt;/p&gt;
&lt;p&gt;The score breakdown is the part I am most proud of. A horizontal stacked bar shows exactly how your universe score was calculated. Stars contribution, repos contribution, languages contribution, account age contribution. Each segment is colored and labeled with both the percentage and the actual points. For the first time developers can see exactly why their score is what it is and what they need to improve to move closer to the Multiverse Core.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/buy3go7lhydygmadfpbn.jpeg&quot; alt=&quot;Image description&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Repos tab&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Horizontal bar chart with every repo on the Y axis and health score on the X axis. Bars are color coded matching planet colors exactly so the analytics and the solar system feel connected. Green is healthy, yellow is decent, orange is struggling, red is critical. Sortable by health score, star count, and last push date. Clicking any repo row pulses that planet in the solar system behind the panel.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rrszl2rfqf6vngj1igy6.jpeg&quot; alt=&quot;Image description&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Activity tab&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;12 month area chart showing commit frequency across the year. Multiple colored lines for the top three repos so you can see which ones are driving activity and which ones went quiet. Most active month is highlighted. Quiet periods are visible immediately.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/98boyta2pjaat0p1i1p0.jpeg&quot; alt=&quot;Image description&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Languages tab&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Donut chart with language percentages matching planet colors exactly. Hover any segment for language name, percentage, and repo count. Language list below sorted by percentage with colored bars. Trend arrows show which languages are growing versus shrinking if historical snapshot data exists.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m5l7vjt9al8cokealu4z.jpeg&quot; alt=&quot;Image description&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CI/CD tab&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Only appears if GitHub Actions exists on tier one repos. Grouped bar chart per repo showing last ten builds. Green is passed, red is failed. Pass rate percentage per repo with a progress bar. Current deploy streak number. Empty state for repos without Actions: No GitHub Actions detected, add a workflow to see your space weather history here.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Growth tab&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Line chart showing cumulative stars over account lifetime. Spike annotations appear when the line jumps significantly labeling the repo that caused the spike. Below the chart a scatter plot shows repo age on the X axis and star count on the Y axis with each dot colored by language. Shows at a glance which repos are veterans still earning stars, which are rising fast, and which were one hit wonders.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xvtqjccrrchke238rb5c.jpeg&quot; alt=&quot;Image description&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Export and share&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;PDF button top right generates a clean formatted report. Share button generates a public read only link at &lt;a rel=&quot;nofollow&quot; href=&quot;https://stack-universe.vercel.app/analytics/username&quot;&gt;https://stack-universe.vercel.app/analytics/username&lt;/a&gt;. Send it to a recruiter or manager and they can read your GitHub health without needing to understand solar systems.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why this phase matters&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A developer who visits Stack Universe and searches their username gets the wow moment from the solar system. That wow moment makes them share it once. The analytics dashboard is what makes them come back.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What the full product looks like now&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Phase 1 gave every developer a beautiful universe. Phase 2 made every planet informative with health scores and PR moons. Phase 3 made it live with GitHub Actions weather. Phase 4 gave developers ownership through OAuth and README embeds. Phase 5 gave it a voice with AI roast, narrator, horoscope, and identity. Phase 6 connected every universe into a community with a flyable spaceship and constellation map. Phase 7 made it professional with a full analytics dashboard.&lt;/p&gt;
&lt;p&gt;Phase 8 is next | the combat system. Universe battles where your GitHub stats become weapons. Stars fire as cannons. Commit streak is your damage multiplier. Followers are your shield rating. After that Phase 9 is monetisation with the Pro tier launch via Lemon Squeezy.&lt;/p&gt;
&lt;p&gt;An honest note&lt;/p&gt;
&lt;p&gt;This is a side project and I am still learning and improving with every phase I ship. Seven phases has taught me more than anything else I have built. If you are an experienced developer and see something I should be doing differently in the Recharts implementation, the PDF generation, the analytics data modeling, or anything else I genuinely want to hear it.&lt;br&gt;
The analytics dashboard screenshot is honestly the thing I am most proud of shipping so far. It looks like something a funded team built. It was built solo as a side project.&lt;/p&gt;
&lt;p&gt;Try yours at &lt;a rel=&quot;nofollow&quot; href=&quot;https://stack-universe.vercel.app&quot;&gt;Stack Universe&lt;/a&gt; and click the ANALYTICS button.&lt;/p&gt;
&lt;p&gt;Drop your universe URL in the comments.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/14615/i-added-a-full-analytics-dashboard-to-my-github-solar-system-visualizer</guid>
<pubDate>Sun, 12 Apr 2026 21:22:52 +0000</pubDate>
</item>
<item>
<title>CPU - Traditional Version (2)</title>
<link>https://coderlegion.com/10965/cpu-traditional-version-2</link>
<description>&lt;p&gt;Continue on how CPU works. As we already know that CPU only knows numbers and calculate number. And So a natural question is &quot;&lt;em&gt;how CPU loops and create condition if the CPU only know how to calculate?&lt;/em&gt;&quot;.&lt;/p&gt;
&lt;p&gt;To put it simply, CPUs have special instructions that allow them to jump between instructions. We can &quot;emulate&quot; loop and condition, for example in my CPU simulation i have this instruction called &lt;code&gt;JZ&lt;/code&gt; (jump if zero). As the name suggests, it jumps to another instruction if a certain value is zero.&lt;/p&gt;
&lt;p&gt;example:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-asm&quot;&gt;LOAD A, 1
LOAD B, 1

CMP A, B
JZ exit
STOREM A, 0 ; store value register A to memory
exit:

HALT
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At this point, a question appears: &quot;&lt;em&gt;what value does JZ actually check?&lt;/em&gt;&quot; we know that &lt;code&gt;exit&lt;/code&gt; is just a label on which line it's referring to, not a value. So how does &lt;code&gt;JZ&lt;/code&gt; know when to jump, and This is where branching flags come in.&lt;/p&gt;
&lt;p&gt;Before &lt;code&gt;JZ&lt;/code&gt; instruction, there's called &lt;code&gt;CMP&lt;/code&gt; instruction As the name implies is a compare instruction, like example above it compare register A value and register B value.&lt;/p&gt;
&lt;p&gt;During this comparison, the CPU updates special internal flags. The most important ones are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Z (Zero flag): true if the result is zero&lt;/li&gt;
&lt;li&gt;N (Negative flag): true if the result is negative&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In my simulation, I explicitly store these flags. In real CPUs, these flags are stored in a special register (often called a status register or flags register).&lt;/p&gt;
&lt;p&gt;After the calculation for &lt;code&gt;CMP&lt;/code&gt; complete the CPU updates the Z and N flags. And when &lt;code&gt;JZ&lt;/code&gt; instruction start they will look at Z flag. And if the the Z flag is true (or 1), execute the jump to chosen location.&lt;/p&gt;
&lt;p&gt;Same as Loop, like example below&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-asm&quot;&gt;LOAD A, 4
LOAD B, 1
LOAD C, 1

loop:
SUB A, B ; substract A with B
CMP A, C
JZ exit ; if A == C
JMP loop ; not equal than repeat
exit:

HALT
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you see can see above this instruction is the simplest loop where if A is equal to B exit loop. &lt;/p&gt;
&lt;p&gt;To create the loop, we need two jump instructions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;JZ&lt;/code&gt; for the conditional jump.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;JMP&lt;/code&gt; for the unconditional jump back to the loop. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If the &lt;code&gt;JZ&lt;/code&gt; condition is not satisfied, the CPU moves to the next instruction, which is &lt;code&gt;JMP&lt;/code&gt;. Since &lt;code&gt;JMP&lt;/code&gt; has no condition, the CPU will always follow it.&lt;/p&gt;
&lt;p&gt;In my simulation, the code for &lt;code&gt;CMP&lt;/code&gt; looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;// get value from register and substract
int temp = reg.r[inst.operandA] - reg.r[inst.operandB];
// check if zero or negative 
flag.zero = (temp == 0);
flag.negative = (temp &amp;lt; 0);
programCounter++;
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;&lt;p&gt;The important rule is that the &lt;code&gt;CMP&lt;/code&gt; instruction should not store any new value in registers or memory. It only updates the flags.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Of course there is other instruction other than &lt;code&gt;JZ&lt;/code&gt; such as: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;JG&lt;/code&gt; (jump if greater),&lt;/li&gt;
&lt;li&gt;&lt;code&gt;JL&lt;/code&gt; (jump if less),&lt;/li&gt;
&lt;li&gt;&lt;code&gt;JNZ&lt;/code&gt; (jump if not zero),&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;and many others, depending on the CPU design.&lt;/p&gt;
&lt;p&gt;So when you see a code like:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;int valueA = 2
int valueB = 3

if (valueA == valueB) {
    // do stuff
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;in CPU it basically try to subtract &lt;code&gt;valueA&lt;/code&gt; and &lt;code&gt;valueB&lt;/code&gt; and if zero condition fulfill (ignoring compiler optimizations).&lt;/p&gt;
&lt;p&gt;And from this branching flags alone, there are many possibility you can create in here because from my experience no matter the fancy code is inside are just bunch of condition and loop. &lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/10965/cpu-traditional-version-2</guid>
<pubDate>Tue, 03 Feb 2026 09:10:33 +0000</pubDate>
</item>
<item>
<title>I Turned Images Into 10,000 Tiny HTML Elements Because Why Not</title>
<link>https://coderlegion.com/10715/i-turned-images-into-10-000-tiny-html-elements-because-why-not</link>
<description>&lt;p&gt;&lt;em&gt;Sometimes the best projects are the ones that solve problems nobody has.&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Last weekend, I found myself staring at my screen, thinking about images. Not in a productive way. Not &quot;how can I optimize image loading&quot; or &quot;what's the best format for web.&quot; No, I was thinking something far more unhinged:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What if every pixel was just a tiny HTML element?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;And thus, IMGML was born.&lt;/p&gt;
&lt;h3 id=&quot;the-premise&quot;&gt;The Premise&lt;/h3&gt;
&lt;p&gt;Here's the concept: take an image, read it pixel by pixel, and generate an HTML file where each pixel is represented by a 1x1 &lt;code&gt;&amp;lt;hr&amp;gt;&lt;/code&gt; element with a background color matching the original pixel.&lt;/p&gt;
&lt;p&gt;That's it. That's the whole thing.&lt;/p&gt;
&lt;p&gt;No &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tags. No &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt;. No SVG. Just thousands upon thousands of microscopic horizontal rules, arranged in a grid, pretending to be an image.&lt;/p&gt;
&lt;h3 id=&quot;does-it-work-&quot;&gt;Does It Work?&lt;/h3&gt;
&lt;p&gt;Technically? Yes.&lt;/p&gt;
&lt;p&gt;Practically? That's a strong word.&lt;/p&gt;
&lt;p&gt;Upload a 100x100 pixel image and you get 10,000 HTML elements. A 200x200 image? 40,000 elements. Your browser will render it. Your browser might also ask you why you've done this.&lt;/p&gt;
&lt;p&gt;But here's the thing — it &lt;em&gt;does&lt;/em&gt; look like the image. Open the HTML file and there it is, your photo, reconstructed entirely from styled &lt;code&gt;&amp;lt;hr&amp;gt;&lt;/code&gt; tags. It's beautiful in the way that a Rube Goldberg machine is beautiful. Unnecessarily complex, deeply impractical, and yet somehow satisfying.&lt;/p&gt;
&lt;h3 id=&quot;why-though-&quot;&gt;Why Though?&lt;/h3&gt;
&lt;p&gt;I get asked this a lot. &quot;Why would you do this?&quot; &quot;What's the use case?&quot; &quot;Are you okay?&quot;&lt;/p&gt;
&lt;p&gt;The answers are: because I could, there isn't one, and debatable.&lt;/p&gt;
&lt;p&gt;This is a &quot;what if&quot; project. It exists in that space between curiosity and questionable judgment. The space where you wonder &quot;can I do this?&quot; before asking &quot;should I do this?&quot;&lt;/p&gt;
&lt;p&gt;Some might call it a waste of time. I call it a learning experience wrapped in absurdity.&lt;/p&gt;
&lt;h3 id=&quot;the-tech&quot;&gt;The Tech&lt;/h3&gt;
&lt;p&gt;For those curious, it's built with Laravel 12 and Livewire. Upload an image, the backend processes it pixel by pixel, and you download your freshly minted HTML monstrosity.&lt;/p&gt;
&lt;p&gt;Here's what the output looks like — just a wall of &lt;code&gt;&amp;lt;hr&amp;gt;&lt;/code&gt; tags, each with an inline background color:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;lt;r&amp;gt;
  &amp;lt;hr style=&quot;background:#cad5d9&quot; /&amp;gt;
  &amp;lt;hr style=&quot;background:#c5ced3&quot; /&amp;gt;
  &amp;lt;hr style=&quot;background:#cdd6db&quot; /&amp;gt;
  &amp;lt;hr style=&quot;background:#dde4ea&quot; /&amp;gt;
  &amp;lt;hr style=&quot;background:#e4ebf1&quot; /&amp;gt;
  &amp;lt;hr style=&quot;background:#e1e6ec&quot; /&amp;gt;
  &amp;lt;hr style=&quot;background:#dadfe5&quot; /&amp;gt;
  &amp;lt;hr style=&quot;background:#d7dadf&quot; /&amp;gt;
  ...
&amp;lt;/r&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The code is straightforward. PHP's image functions handle the pixel reading, a loop builds the markup, and Livewire makes the upload/download flow seamless. Nothing revolutionary — just reasonable tools applied to an unreasonable idea.&lt;/p&gt;
&lt;h3 id=&quot;the-optimization-rabbit-hole&quot;&gt;The Optimization Rabbit Hole&lt;/h3&gt;
&lt;p&gt;Once I committed to this absurd idea, I became obsessed with making each pixel as small as possible. Here's how that went:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Attempt 1: RGB&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;lt;hr style=&quot;background:rgb(255, 255, 255)&quot;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Works, but verbose. All those characters add up.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Attempt 2: Hex&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;lt;hr style=&quot;background:#c5ced3&quot;/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Shorter. Hex codes are more compact than RGB.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Attempt 3: Drop the self-closing slash&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;lt;hr style=&quot;background:#c5ced3&quot;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It's optional in HTML5. Every byte counts.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Attempt 4: Drop the quotes&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;lt;hr style=background:#c5ced3&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Also valid HTML. We're getting minimal.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Attempt 5: The bgcolor attribute&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;lt;hr bgcolor=&quot;#c5ced3&quot;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Deprecated, and for some reason only works on &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt;. Dead end.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Attempt 6: The color attribute&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;lt;hr color=#c5ced3&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This works. It's deprecated, it's not recommended, and it's perfect for this project.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Attempt 7: Drop the hashtag&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;lt;hr color=c5ced3&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Turns out the &lt;code&gt;#&lt;/code&gt; is optional on hex colors. One more character gone.&lt;/p&gt;
&lt;p&gt;This is the shortest I could make each pixel. If you know a way to make it smaller, I'm genuinely curious.&lt;/p&gt;
&lt;p&gt;The code is straightforward. PHP's image functions handle the pixel reading:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;// Resize to keep things manageable
$image = $this-&amp;gt;resizeImage($path, 200, 200);
$resource = imagecreatefromjpeg($image);

$width = imagesx($resource);
$height = imagesy($resource);
$pixels = [];

// Loop through every pixel
for ($y = 0; $y &amp;lt; $height; $y++) {
    for ($x = 0; $x &amp;lt; $width; $x++) {
        // Get color index at this coordinate
        $color = imagecolorat($resource, $x, $y);

        // Convert to RGB array
        $rgb = imagecolorsforindex($resource, $color);

        // Format as hex (no hashtag needed)
        $hex = sprintf('%02x%02x%02x', $rgb['red'], $rgb['green'], $rgb['blue']);

        $pixels[] = $hex;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Loop through each row, each column, grab the color, convert to hex, done. Livewire handles the upload/download flow. Nothing revolutionary — just reasonable tools applied to an unreasonable idea.&lt;/p&gt;
&lt;h3 id=&quot;what-i-actually-learned&quot;&gt;What I Actually Learned&lt;/h3&gt;
&lt;p&gt;Despite the silliness, building IMGML reminded me of a few things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Constraints breed creativity.&lt;/strong&gt; Limiting myself to just HTML elements forced me to think differently about rendering.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Performance matters everywhere.&lt;/strong&gt; Processing images pixel by pixel taught me to respect the work that actual image libraries do.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Side projects don't need purpose.&lt;/strong&gt; Not everything has to ship, scale, or solve a real problem. Sometimes you just build something weird and smile.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;should-you-use-this-&quot;&gt;Should You Use This?&lt;/h3&gt;
&lt;p&gt;Absolutely not.&lt;/p&gt;
&lt;p&gt;Well, maybe. If you need to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Confuse a web developer&lt;/li&gt;
&lt;li&gt;Create the world's least efficient image format&lt;/li&gt;
&lt;li&gt;Prove a point about HTML being turing complete (it's not, but this feels adjacent)&lt;/li&gt;
&lt;li&gt;Kill time on a Saturday&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then yes, IMGML is for you.&lt;/p&gt;
&lt;h3 id=&quot;try-it-yourself&quot;&gt;Try It Yourself&lt;/h3&gt;
&lt;p&gt;The project is open source. Clone it, run it, upload an image, and watch your browser question its life choices as it renders your photo one &lt;code&gt;&amp;lt;hr&amp;gt;&lt;/code&gt; at a time.&lt;/p&gt;
&lt;p&gt;Will it change the world? No.&lt;/p&gt;
&lt;p&gt;Will it make you briefly happy in a &quot;wow, that's dumb&quot; kind of way? Almost certainly.&lt;/p&gt;
&lt;p&gt;And sometimes, that's enough.&lt;/p&gt;
&lt;p&gt;Here's &lt;a rel=&quot;nofollow&quot; href=&quot;https://placeholderblog.netlify.app/assets/blog/imgml.html&quot;&gt;my GitHub avatar in IMGML format&lt;/a&gt; if you want to see it in action.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;IMGML is available on &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/brunoabpinto/IMGML&quot;&gt;GitHub&lt;/a&gt;. Star it if you appreciate the absurdity.&lt;/em&gt;&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/10715/i-turned-images-into-10-000-tiny-html-elements-because-why-not</guid>
<pubDate>Thu, 29 Jan 2026 23:34:43 +0000</pubDate>
</item>
<item>
<title>CPU - Traditional Version</title>
<link>https://coderlegion.com/10661/cpu-traditional-version</link>
<description>&lt;p&gt;I've been building quite a few projects and one of them is this CPU Simulation. I've been in the web world for 4 years, but i still did not understand what CPU is. So in the past week i start to build a small project CPU-Simulation that follow the behavior in the CPU.&lt;/p&gt;
&lt;p&gt;Why the sudden interest in CPUs? Curiosity. There was a trigger after reading an article on how CPU work and they the work is quite simple, that got me thinking &quot;hey, i can build that&quot;.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Note: This is the article &lt;a rel=&quot;nofollow&quot; href=&quot;https://homepage.cs.uri.edu/faculty/wolfe/book/Readings/Reading04.htm&quot;&gt;CPU&lt;/a&gt; and this one &lt;a rel=&quot;nofollow&quot; href=&quot;https://cpu.land/the-basics&quot;&gt;CPU&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So, in CPU they have two important component called Control Unit and ALU (Arithmetic Logic Unit). At a high level, they follow a simple idea often described as “fetch and execute.” In more detail, the cycle looks like this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Control Unit&lt;br&gt;
This Control Unit responsible for fetch instruction from memory and decode the instruction into something ALU can read. by decoding means they translate the instruction into control signal that the ALU can act on.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Arithmetic Logic Unit (ALU)&lt;br&gt;
ALU is responsible for execution the instruction that producing a result and storing the result in register or memory.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So to put it simple it more like fetch -&amp;gt; decode -&amp;gt; execute -&amp;gt; store -&amp;gt; next. That's the whole cycle, the cycle repeat until all instruction is complete.&lt;/p&gt;
&lt;p&gt;From this it's tell me that, the computer work in a simple and predictable manner. The CPU does not care what program it given, it only cares whether an instruction is valid and whether it can be executed.&lt;/p&gt;
&lt;p&gt;So i did manage to build the simulation using java, and it can be improve later. Here some code &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/IkhwanAL/cpu-simulation&quot;&gt;Github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I use web browser to interact with the cpu, the cpu have 4 register index and 100 bytes of memory. But right now i only create small portion on how CPU work.&lt;/p&gt;
&lt;p&gt;Here gist code &lt;a rel=&quot;nofollow&quot; href=&quot;https://gist.github.com/IkhwanAL/cfecd57953df84835d71a61f8524d9bf&quot;&gt;CU &amp;amp; ALU&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As you can see from github code the CU or Control Unit have it's own class. The class contain few important part and there is fetch the program convert to stream and decode it, to something that Simulation ALU can read.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;  private int resolveInstruction(Operand op) {

    // Convert to Number
    if (op instanceof LabelRef label) {
      Integer addr = labels.get(label.name());

      if (addr == null) {
        throw new IllegalStateException(&quot;Unknow Label :&quot; + label.name());
      }

      return addr;
    }

    // Convert to Number
    if (op instanceof HexCode hx) {
      return Integer.decode(hx.value());
    }

    // Convert to Number
    if (op instanceof Immediate imm) {
      return imm.value();
    }

    // Convert to Number
    if (op instanceof RegisterCode rc) {
      return parseRegister(rc.value());
    }

    return 0;
  }

  private Instruction resolver(RawInstruction ins) {
    var instruction = new Instruction();
    instruction.opcode = ins.opcode;
    switch (ins.opcode) {
      case HALT:
        break;
      case JMP:
        instruction.dest = resolveInstruction(ins.dest);
        break;
      case STOREM:
      case LOADM:
        instruction.dest = resolveInstruction(ins.dest);
        instruction.src = resolveInstruction(ins.src);
        break;
      case LOAD:
        instruction.dest = resolveInstruction(ins.dest);
        instruction.src = resolveInstruction(ins.src);
        break;
      case CMP:
      case ADD:
        instruction.dest = resolveInstruction(ins.dest);
        instruction.src = resolveInstruction(ins.src);
        break;
      case JZ:
        instruction.dest = resolveInstruction(ins.dest);
        break;
      case null:
      default:
        break;
    }

    return instruction;
  }

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can see from function called &lt;code&gt;resolver&lt;/code&gt; it convert every value into number. Because CPU does not talk other than number.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java&quot;&gt;  void execute(Register reg, Memory mem, ArrayList&amp;lt;Instruction&amp;gt; program) {
    if (programCounter &amp;lt; 0 || programCounter &amp;gt;= program.size()) {
      halted = true;
      fault = CpuFault.INVALID_PC;
      return;
    }

    Instruction inst = program.get(programCounter);

    switch (inst.opcode) {
      case LOAD:
      case STOREM:
      case LOADM:
      case ADD: // register to register
        this.store(inst, reg, mem);
        break;
      case CMP:
        int temp = reg.r[inst.dest] - reg.r[inst.src];
        flag.zero = (temp == 0);
        flag.negative = (temp &amp;lt; 0);
        programCounter++;
        break;
      case JMP:
        programCounter = inst.dest - 1;
        break;
      case JZ:
        if (flag.zero) {
          programCounter = inst.dest - 1;
        } else {
          programCounter++;
        }
        break;
      case HALT:
        halted = true;
        break;
      case null:
      default:
        fault = CpuFault.ILLEGAL_INSTRUCTION;
        halted = true;
    }
  }

  private void store(Instruction inst, Register reg, Memory mem) {
    switch (inst.opcode) {
      case LOADM:
        if (inst.src &amp;gt; mem.ram.length) {
          halted = true;
          fault = CpuFault.INVALID_MEM;
          break;
        }
        reg.r[inst.dest] = mem.ram[inst.src];
        programCounter++;
        break;
      case STOREM:
        if (inst.src &amp;gt; mem.ram.length) {
          halted = true;
          fault = CpuFault.INVALID_MEM;
          break;
        }
        mem.ram[inst.src] = reg.r[inst.dest];
        programCounter++;
        break;
      case ADD:
        int res = reg.r[inst.dest] + reg.r[inst.src];
        reg.r[inst.dest] = res;
        flag.zero = (res == 0);
        flag.negative = (res &amp;lt; 0);
        programCounter++;
        break;
      case LOAD:
        reg.r[inst.dest] = inst.src;
        programCounter++;
        break;
      default:
        break;
    }
  }

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And above code block is an important function in ALU Class, which contain execute function where it take the decoded instruction from Control Unit Class and execute it. And of course i add an error handler, the error handler in CPU are quite similar to most program, if there some illegal instruction or incorrect instruction they halted the program from execute. If you ever use a tool like &lt;code&gt;sudo&lt;/code&gt; or other linux command it's the same, if it's error stop the program.&lt;/p&gt;
&lt;p&gt;And other interesting part is the label tag like &lt;code&gt;loop:&lt;/code&gt; or &lt;code&gt;exit:&lt;/code&gt;. That label are just for parser to remember what line are they referring to. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-asm&quot;&gt;LOAD A, 1
LOAD B, 1

loop:
ADD A, B
CMP A, 7
JZ exit
JMP loop

exit:
HALT
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;above instruction are a simple instruction for loop if value reach zero stop the loop. Equivalent with:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;
int A = 1
while (A != 7) {
    A += 1
}
return

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If i swap the &lt;code&gt;JZ exit&lt;/code&gt; with &lt;code&gt;JMP loop&lt;/code&gt; it can cause infinite loop. &lt;/p&gt;
&lt;p&gt;There are many more modern concepts in CPU design, but for now, I think a traditional CPU model is enough to understand the fundamentals.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/10661/cpu-traditional-version</guid>
<pubDate>Thu, 29 Jan 2026 05:57:40 +0000</pubDate>
</item>
</channel>
</rss>