<?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: ShatilKhan</title>
    <description>The latest articles on DEV Community by ShatilKhan (@siren).</description>
    <link>https://dev.to/siren</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%2F558537%2F82f48ad4-591e-4a86-816a-10250ca198cb.jpg</url>
      <title>DEV Community: ShatilKhan</title>
      <link>https://dev.to/siren</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/siren"/>
    <language>en</language>
    <item>
      <title>Hijacking OpenClaw with Claude</title>
      <dc:creator>ShatilKhan</dc:creator>
      <pubDate>Sat, 25 Apr 2026 21:55:41 +0000</pubDate>
      <link>https://dev.to/siren/hijacking-openclaw-with-claude-49dg</link>
      <guid>https://dev.to/siren/hijacking-openclaw-with-claude-49dg</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/openclaw-2026-04-16"&gt;OpenClaw Writing Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ClawCon Michigan
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Prelude
&lt;/h2&gt;

&lt;p&gt;My boss has been nagging me about "being more verbal" and "showing proof of work" and here I was pushing code when no one was seeing it.&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%2Fp0f5g1b6sb4hwvnaotwl.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%2Fp0f5g1b6sb4hwvnaotwl.png" alt="gigachadvscrawny" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So I decided to try out OpenClaw for as our product manager (our human product manager ran away to Thailand, it's True!)&lt;/p&gt;

&lt;p&gt;I have no idea how to set it up or how it works. I had only seen tiktoks saying both good and bad stuff. And a Fireship video I saw weeks ago. That's pretty much my knowledge on this crab.&lt;br&gt;
So today we make it folks!&lt;br&gt;
Our Clawfficer!&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%2Flpjnmyh09klfyu1wfat1.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%2Flpjnmyh09klfyu1wfat1.png" alt=" " width="755" height="572"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The Problem: We Had Claude Code, But Not Claude
&lt;/h2&gt;

&lt;p&gt;Here's the thing. My company gave us access to &lt;strong&gt;Claude Code&lt;/strong&gt; (the CLI tool) through our dev environments. But they didn't give us &lt;strong&gt;Claude web accounts&lt;/strong&gt; or API keys. No &lt;code&gt;console.anthropic.com&lt;/code&gt;. No OAuth flow. No nothing.&lt;/p&gt;

&lt;p&gt;So I'm sitting there with this powerful CLI tool installed, but I can't even log in the "normal" way because that requires a web account.&lt;/p&gt;

&lt;p&gt;Sound familiar? If your office IT is anything like mine, you probably have access to tools but not the accounts that make them "officially" work.&lt;/p&gt;

&lt;p&gt;Time to mad-scientist our way through this.&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%2F67uovgarcm1hafigxeh3.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%2F67uovgarcm1hafigxeh3.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  What even is OpenClaw?
&lt;/h2&gt;

&lt;p&gt;If you've come this far to read my post I'm assuming you know what &lt;a href="https://openclaw.ai/" rel="noopener noreferrer"&gt;OpenClaw&lt;/a&gt; is ¯_(ツ)&lt;em&gt;/¯&lt;br&gt;
I mean it's not like it has the largest growing repo in history ¯_(ツ)&lt;/em&gt;/¯&lt;/p&gt;

&lt;p&gt;But here's the catch: OpenClaw needs Claude(or any other AI model) to actually &lt;em&gt;do&lt;/em&gt; the thinking. And Claude usually needs an API key or web OAuth to work.&lt;/p&gt;

&lt;p&gt;Except... we already have Claude Code installed. And Claude Code has a trick.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Symlink Hack
&lt;/h2&gt;

&lt;p&gt;When you install Claude Code globally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @anthropic-ai/claude-code
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It creates a &lt;code&gt;claude&lt;/code&gt; binary in your PATH. But most people don't realize, this binary carries its OWN AUTHENTICATION!&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%2Fyeyb43xef49nw70crg7r.gif" 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%2Fyeyb43xef49nw70crg7r.gif" alt=" " width="498" height="330"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you run &lt;code&gt;claude /login&lt;/code&gt; (which we &lt;em&gt;could&lt;/em&gt; do because we had the CLI but we can't because boss removed the email account  ┐( ˘_˘)┌ ), it opens a browser and does OAuth with your Claude Pro/Max subscription. It then stores a refresh token at:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;~/.claude/.credentials.json&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now here's the beautiful part: &lt;strong&gt;Claude Code can run in headless mode&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Summarize these commits"&lt;/span&gt; | claude &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="nt"&gt;--output-format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;text
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No API key. No &lt;code&gt;ANTHROPIC_API_KEY&lt;/code&gt; env var. No web console. Just the OAuth token that Claude Code manages itself, auto-refreshing forever.&lt;/p&gt;

&lt;p&gt;We basically &lt;strong&gt;hijacked&lt;/strong&gt; the Claude Code CLI's authentication mechanism and piped it into our OpenClaw workflow. The CLI becomes our "API layer" without us ever touching an API key.&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%2Fftciwhgxaegfea9cq85p.gif" 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%2Fftciwhgxaegfea9cq85p.gif" alt=" " width="498" height="308"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is how Claude Code's OAuth flows into our OpenClaw setup without ever exposing an API key&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%2F1p72ibopitioppxh5u83.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%2F1p72ibopitioppxh5u83.png" alt="System Architecture for OpenClaw with Clause Code CLI" width="800" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But of course we ain't done yet!&lt;/p&gt;

&lt;h2&gt;
  
  
  LOOP!
&lt;/h2&gt;

&lt;p&gt;We have an agent, we have a runtime.&lt;br&gt;
So we still gotta make it survive restarts "( – ⌓ – )&lt;/p&gt;

&lt;p&gt;So we wrap it as a systemd user service. Voila! now it starts on boot and restarts if crashes&lt;/p&gt;

&lt;p&gt;We override &lt;code&gt;PATH&lt;/code&gt; in the systemd unit so it can find the &lt;code&gt;claude&lt;/code&gt; symlink.&lt;br&gt;
Without that PATH override, systemd's stripped-down environment can't find Claude Code, and the whole digest flow breaks. It's a one-line fix that took us an embarrassing amount of time to figure 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%2Fjvvhs1yrjm6wx5gj4vct.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%2Fjvvhs1yrjm6wx5gj4vct.png" alt="openclaw as a systemd service" width="800" height="85"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Meet the Clawfficer
&lt;/h2&gt;

&lt;p&gt;So what does our "mad science" actually &lt;em&gt;do&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;We built a Discord bot that acts as our product manager. We call it the &lt;strong&gt;Clawfficer&lt;/strong&gt;.&lt;br&gt;
If you add clawfficer to your server channel , he will summarize daily and weekly github updates in Natural language.. SO not just generic auto generated bullet points, you could ask it "Hey what's the update on this project?" or "Hey we should add this to the roadmap and assign Shatil" or "I found this issue , can you assign Shatil to get a look at it?" , clawfficer will do his due diligence and assign the respective dev AND tag the message url in the github issue!&lt;/p&gt;

&lt;p&gt;Here's some photos we took of Clawfficer in Action!&lt;/p&gt;

&lt;p&gt;Here I ask Clawfficer to assign Mahim(my college) to an issue&lt;br&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%2Fy87v9758z7b0ue6lwuay.jpeg" 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%2Fy87v9758z7b0ue6lwuay.jpeg" alt="assign to issue" width="800" height="535"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we see the issue was created and assigned with the discord message refrence&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%2F5mdcpya87ne1i4pvnej5.jpeg" 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%2F5mdcpya87ne1i4pvnej5.jpeg" alt="issue with discord message" width="800" height="535"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's shown that the issue was created by me because I used my own github PAT(personal access token) for the repo access.&lt;/p&gt;

&lt;p&gt;Here we see Clawfficer in his natural environment sharing summaries&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%2F24xpqxak7f4uoq79eeiq.jpeg" 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%2F24xpqxak7f4uoq79eeiq.jpeg" alt="daily summary" width="800" height="525"&gt;&lt;/a&gt;&lt;br&gt;
Every day at 9 AM and every Sunday at 10 AM, the bot pulls activity from all 8 of our repos across &lt;strong&gt;all branches&lt;/strong&gt; (not just main , we have more repos but just included the most active ones for testing on the agent).&lt;/p&gt;

&lt;p&gt;Then it pipes all that data into:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="nt"&gt;--output-format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;text
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And Claude spits back a human-readable prose summary. Not bullet points. Not raw JSON. Actual sentences like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Medihelp saw 12 commits across 3 branches this week, mostly schema migrations by Mahim. The eyecraft landing page got its first PR review."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The bot posts this to &lt;code&gt;#roadmap&lt;/code&gt;. My boss sees it. I stop getting nagged about "proof of work."&lt;/p&gt;

&lt;p&gt;Everyone wins.&lt;/p&gt;

&lt;p&gt;The Claude Code symlink approach means you can:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Use your existing subscription&lt;/strong&gt; (Claude Pro/Max)- same billing bucket as your interactive usage&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run headlessly&lt;/strong&gt; in scripts, cron jobs, and bots&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Never handle an API key&lt;/strong&gt; - OAuth tokens live in &lt;code&gt;~/.claude/&lt;/code&gt; and auto-refresh&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deploy anywhere&lt;/strong&gt; that has Node.js and your user context&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It's not "officially supported" as an API replacement. But it works. And for internal tools that need to "just work" without procurement battles, that's gold.&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%2F71mvqidypn3sr0vakg5j.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%2F71mvqidypn3sr0vakg5j.png" alt="OpenClaw Harness with Claude Code AI Engine in Node Runtime" width="800" height="345"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Stuff I Spent way too much time on
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Branch Coverage Matters
&lt;/h3&gt;

&lt;p&gt;GitHub's &lt;code&gt;/commits&lt;/code&gt; endpoint defaults to the default branch. If your team works on feature branches (and they should), your digest will look empty even when people are pushing code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; Iterate all branches, dedupe by commit SHA. Obvious in hindsight, painful in production.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. The OAuth Token is Everything
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;~/.claude/.credentials.json&lt;/code&gt; file is the single point of auth failure. If it expires or gets corrupted, &lt;code&gt;claude -p&lt;/code&gt; exits with code 1 and your digest falls back to bullet points.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; Run &lt;code&gt;claude&lt;/code&gt; interactively once to re-auth. The CLI handles refresh tokens automatically after that.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. systemd PATH is Not Your Shell PATH
&lt;/h3&gt;

&lt;p&gt;Your interactive shell has &lt;code&gt;claude&lt;/code&gt; in PATH. systemd doesn't. Explicitly set &lt;code&gt;Environment=PATH=...&lt;/code&gt; in your unit file or the spawn fails silently.&lt;/p&gt;

&lt;p&gt;The Clawfficer is intentionally minimal. I deliberately didn't build a lot of other regular features. (I mean I only built it yesterday in 8 hours without any prior knowledge of Claw so ¯_(ツ)_/¯ )&lt;br&gt;
But the foundation is there. And more importantly, the &lt;strong&gt;authentication pattern&lt;/strong&gt; is there.Claude Code's CLI isn't just an interactive coding assistant , it's a headless LLM engine that happens to already be authenticated.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://github.com/ShatilKhan" rel="noopener noreferrer"&gt;Shatil Khan&lt;/a&gt; builds things at Anchorblock and argues with crabs on the internet. Follow for more questionable engineering decisions that somehow work.&lt;/em&gt;&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%2F8gc8wjm2n6pve2al0zvl.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%2F8gc8wjm2n6pve2al0zvl.png" alt="Yeah Baby!" width="320" height="276"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>openclawchallenge</category>
      <category>claude</category>
      <category>ai</category>
    </item>
    <item>
      <title>Giving Your Accounting App a Brain: NestJS "MCP"</title>
      <dc:creator>ShatilKhan</dc:creator>
      <pubDate>Thu, 23 Apr 2026 23:23:42 +0000</pubDate>
      <link>https://dev.to/siren/giving-your-accounting-app-a-brain-nestjs-mcp-4nfc</link>
      <guid>https://dev.to/siren/giving-your-accounting-app-a-brain-nestjs-mcp-4nfc</guid>
      <description>&lt;h2&gt;
  
  
  Recap
&lt;/h2&gt;

&lt;p&gt;Let's be real: in the &lt;a href="https://dev.to/siren/building-my-first-mcp-server-using-swagger-openapitools-38kg"&gt;last blog&lt;/a&gt; we were running a local MCP server on my pc, wiring it up to GitHub Copilot like mad scientists. It was awesome. But it was a lab experiment. The "brain" was tethered to my machine.&lt;/p&gt;

&lt;p&gt;So... what if we built the brain into the app itself?&lt;/p&gt;

&lt;h2&gt;
  
  
  The System
&lt;/h2&gt;

&lt;p&gt;So here's the setup. We have three players in this game:&lt;/p&gt;

&lt;p&gt;The Web App: React, Vite, Redux Toolkit. The chat lives at /magic-bookkeeping.&lt;br&gt;
The Backend: NestJS, PostgreSQL, Redis. This is where the real work happens.&lt;br&gt;
The AI Service: Claude Haiku 3.5 via Requesty.AI, sitting in between.&lt;/p&gt;

&lt;p&gt;User be like: Yo what items we got?&lt;br&gt;
Agent: Calls the itemAll tool to check the item inventory and then &lt;em&gt;cool pause&lt;/em&gt; RENDERS a Full UI Component with item details! Not texts! &lt;br&gt;
Also works for like Bengali and Voice inputs by the way&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%2Fbi0h822ytz01di06vfhx.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%2Fbi0h822ytz01di06vfhx.png" alt="system" width="800" height="251"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The frontend Contract:&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%2F0aitxyfgfqv8ziigb75j.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%2F0aitxyfgfqv8ziigb75j.png" alt="frontend connection to mcp service" width="800" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is what's keeping them connected.&lt;/p&gt;

&lt;h2&gt;
  
  
  The MCP Layer: But Not Actually MCP?
&lt;/h2&gt;

&lt;p&gt;Plot twist: we call it MCP, but it's not really the Model Context Protocol. There's no stdio. No SSE. No @modelcontextprotocol/sdk. No JSON-RPC. We basically built our own tool-calling façade that looks like OpenAI's function spec so Claude knows what to do with it.&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%2Fc1jd6zd0k5zfgfs7l5zx.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%2Fc1jd6zd0k5zfgfs7l5zx.png" alt="mcp" width="800" height="253"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since this was already a heavy enough ERP system with a lot of code that was written before the AI era,adapting it to a separate mcp server wouldn't be that easy, plus it would also mean we would have to maintain another server.&lt;/p&gt;

&lt;p&gt;The Controller (only two endpoints!):&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%2F4h0133lbi0j9nc1q3uwy.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%2F4h0133lbi0j9nc1q3uwy.png" alt="mcp tool controller" width="800" height="678"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;when a user first requests any info &lt;code&gt;list_tool&lt;/code&gt; will list all available tools for the ai model&lt;br&gt;
&lt;code&gt;call_tool&lt;/code&gt; is where the magic happens, we pass in a system prompt for the ai service so that it knows how to select the tools for any specific operations or which tools to call for let's say getting items or adding new item to inventory. &lt;/p&gt;

&lt;p&gt;the tool dto:&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%2Fp9hlsglcpq7upavmn25p.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%2Fp9hlsglcpq7upavmn25p.png" alt="call tool dto" width="800" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;why "any" ? &lt;br&gt;
Because every tool has a different structure.&lt;br&gt;
&lt;code&gt;arguments: any&lt;/code&gt; is probably the most honest TypeScript type ever written&lt;/p&gt;

&lt;p&gt;And here is how the tools are dispatched:&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%2Fix5md576njgwmfjfuym4.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%2Fix5md576njgwmfjfuym4.png" alt="mcp tool dispatch" width="800" height="530"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;tools.json&lt;/code&gt; is read from disk on every request, not cached. The switch pattern means adding a tool requires editing both the JSON file and this service. (cut me some slack , it was my first time building stuff like this :))&lt;/p&gt;

&lt;h3&gt;
  
  
  Anatomy of a mcp tool
&lt;/h3&gt;

&lt;p&gt;there's two types of tools for this project&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Data Tools&lt;/li&gt;
&lt;li&gt;Component Tools
data tools handles the actual service calls and response payloads while component tool is just used used for generative UI which we'll get to later.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;here's a data tool declared inside tools.json:&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%2Fht0k7e6uwkt49u9jdb5f.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%2Fht0k7e6uwkt49u9jdb5f.png" alt="mcp tool declaration" width="800" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;this is how we handle the tool via our mcp service:&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%2F1nb8mslbc1j3yqhp5nog.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%2F1nb8mslbc1j3yqhp5nog.png" alt="mcp data tool handler" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Result is the raw entity returned by the domain service.&lt;/p&gt;

&lt;p&gt;Now compare it to the component tool&lt;br&gt;
a create item tool in tools.json:&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%2F830p19ud7o4lsbwrwpbf.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%2F830p19ud7o4lsbwrwpbf.png" alt="mcp create item tool" width="800" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;handler in mcp.service.ts:&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%2Faeo0988ede3e8l55d12k.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%2Faeo0988ede3e8l55d12k.png" alt="mcp service typescript" width="800" height="580"&gt;&lt;/a&gt;&lt;br&gt;
Instead of touching the database the backend returns a "render this component" envelope. The frontend's registry maps AiItemForm to the actual React component.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Cool Part: Generative UI
&lt;/h2&gt;

&lt;p&gt;Okay so the AI can fetch data. Great. But here's where it gets spicy. What if instead of returning boring JSON, the backend says: "Hey frontend, render this form"?&lt;/p&gt;

&lt;p&gt;But we can't just ask it to use html templates , no? The forms need to dynamic, the same form the user uses to enter item details or add a new entry to the inventory should also be rendered here basically. But how did I achieve this? &lt;br&gt;
Quite simply I wrap those already existing form components as separate render-able components , put them in a component registry and then it's just a matter of prompting the model correctly so it renders the right form based on user intent.&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%2Flijawj0l0z8mcn8nwg0g.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%2Flijawj0l0z8mcn8nwg0g.png" alt="generative ui flow" width="800" height="113"&gt;&lt;/a&gt;&lt;br&gt;
The response type that makes this possible:&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%2Fixgvcmqjxxgbjjysx56k.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%2Fixgvcmqjxxgbjjysx56k.png" alt="generative ui tool response schema" width="800" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When &lt;code&gt;render_type === 'component'&lt;/code&gt;, the frontend looks up a component by name in a static registry and renders it inline in the chat. No LLM-generated markup, no code-eval; the model only selects which component and fills its props from the Tool Registry:&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%2F4qk721dyo0effpfkhhpe.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%2F4qk721dyo0effpfkhhpe.png" alt="tool registry" width="757" height="391"&gt;&lt;/a&gt;&lt;br&gt;
Adding a new generative component requires editing this file. There is no runtime discovery ,the server can only refer to components the frontend has already imported.&lt;/p&gt;

&lt;p&gt;Finally it all comes together inside the Chat!&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%2Fd6szyjt7n27l0hhsps2d.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%2Fd6szyjt7n27l0hhsps2d.png" alt="generative chat ui" width="800" height="655"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If component_name isn't in the registry, the branch silently falls through to  , no error, no fallback UI.Callbacks are hard-wired for AiItemForm only.(Cause I'm lazy)&lt;br&gt;
The form-vs-list distinction is a string-includes check on the name.&lt;/p&gt;

&lt;p&gt;And lastly here's how a user's message would flow through the system and repond with generative components:&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%2Fhogw5it6i1pjrul1rvxk.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%2Fhogw5it6i1pjrul1rvxk.png" alt="generative-ui" width="800" height="502"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;it's 5 am in my place now so that's it for now, you can checkout the other blogs in the series or don't I don't care, this was a company project so I couldn't share the full code :)&lt;/p&gt;

&lt;p&gt;Sayonara people&lt;/p&gt;

&lt;p&gt;aurthor's note: maybe I'll add in a video later on of the working project, it's obviously not something you could just put in prod but something that at least works, some parts need more work, but if you've Actually read this far! Thanks! &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%2Fvw4w6wdktnxzvaxr1jgv.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%2Fvw4w6wdktnxzvaxr1jgv.png" alt="pickachu waving sayonara" width="278" height="182"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>backend</category>
      <category>llm</category>
      <category>mcp</category>
    </item>
    <item>
      <title>Moneyshot#1: Month 1 till I make $1k MRR</title>
      <dc:creator>ShatilKhan</dc:creator>
      <pubDate>Sat, 21 Feb 2026 20:11:23 +0000</pubDate>
      <link>https://dev.to/siren/moneyshot1-month-1-till-i-make-1k-mrr-2o4a</link>
      <guid>https://dev.to/siren/moneyshot1-month-1-till-i-make-1k-mrr-2o4a</guid>
      <description>&lt;p&gt;Hello again Internet!&lt;br&gt;
I am writing  after a long while and this blog is a bit different from my engineering blogs. This is more of a practical blog of some goals I am going to set for myself, which I had previously done years ago for coding or learning to code &amp;amp; I guess and it has paid off and I wanted to do that again but with a different goal in mind.&lt;/p&gt;

&lt;p&gt;I made this video back in 2023 probably and around the end of 2023 or 2022 I think where I kind of publicly posted that I'd code every day&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/kakDtPbE7gg"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;p&gt;which I mean I didn't code every single day but you know I'll share the GitHub repo or GitHub profile after I had posted that video,&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%2Fcqj4xr3e01u7lg3o30kz.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%2Fcqj4xr3e01u7lg3o30kz.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and I actually committed to it, and I actually started doing some projects and contributing to some open source projects. And I did get to work with pretty amazing people. I did get to work on a project for AWS Open Source, which obviously none of them sprouted into success, or none of them sprouted into major things. But what happened was after that the following year I got my first job and then I have been working professionally with startups and agencies since then So yeah it didn't make sense at that moment when I actually posted the video that I code every day but it now makes sense that I did commit to something and then I started doing it. And I'd done that previously years ago as well when I first started to code. and when I first started I used to do digital art as well so when I first did digital art ,there's thing called Inktoberfest where you would like draw something for the entire month of October and I also did Hacktoberfest where you would code or contribute some code to some repositories (open source repositories) for the entire month of October and these things didn't mean that you would probably be successful at any specific coding area or any specific skilled area but the goal was to be consecutive and consecutively keep doing it without worrying about the results.&lt;/p&gt;

&lt;p&gt;After I started working professionally as a developer since the last  two years, the software industry as a whole has shifted drastically that I've experienced. I do three part-time jobs. One of them is an office job. And I think I'm doing more work than any developer would have done three or four years ago. that's mainly due to AI and AI has enabled people to do more but it has been demanding from people more as well. The one thing that I have looked and I have experienced is that the overall outlook of everyone and every industrial mechanism has changed from improving or focused on results to just making money So the key mechanism of the AI industry or the software industry as a whole has been to make money obviously. But there was a video from GitHub around 5 or 6 years ago, you can watch it on YouTube, it was basically an advertisement for GitHub, but not a typical advertisement. It wasn't advertised in a way like GitHub as a product, but rather it advertised code as a means to connect different parts of society. So, the video was mainly about a girl making a prosthetics arm for her brother, and in another part of the world, somebody else used that code to build something else that they needed.&lt;br&gt;
With the current industrial standards, I feel like that wave has faded. Like actually developing something for betterment, actually trying to, I mean people are still developing things to help people, but most of those things are more focused on profitability. So, they're helping people, but they're also focused on actually making money. And even though I say that the outlook has changed, I don't mean that in a negative way, but moreover it has become much easier for a single person, like for example, Open Claw or Peter Steinberger, people like those to make money or make profitable businesses out of their skillsets. And obviously not everyone can do it, you need a lot of expertise and global experience, but there's also people who have been building, indie hackers who have been developing for years. And I wanna build shitty products that's also one goal is to build a lot of shitty products and have a lot of fucking fun doing it for people, for myself, but mostly to enjoy the process that I have enjoyed before just building things not just software but anything.&lt;/p&gt;

&lt;p&gt;If money is the main goal or like the standards of the industry have changed to making money or making it easier for people to run businesses then let's do that. Let's just go for that and make as much as possible so that we can actually try it out. I've already said that I tried out everything. I tried out art, doing art and doing programming and going all in into it because it was so interesting. And right now this trend of building stuff is very intriguing. So that's why I feel like I should challenge myself, but this time with a specific number in mind to get to that goal.&lt;/p&gt;

&lt;p&gt;This goal is much different from the previous goals I set for myself. The primary one was to just learn things. Learning to code, learning to draw, learning anything basically. And the secondary goal was to earn something, earn some money or some monetary means by doing what I love or doing what I'm good at, which was the skills I had previously learned from my first goal.&lt;/p&gt;

&lt;p&gt;This time I am gonna set a specific amount or specific target in mind for the goal which is the 1k MRR which means that it's not just like a specific amount per month but more of it needs to be be set in some rules and those rules I do need to follow through. So the first and foremost would be that it obviously needs to be a MRR because it needs to be a monthly recurring review. It's not just I need to make that amount once and then the goal is set. It wouldn't work like that.It would need to be a sustainable MRR or a recurring revenue per month. That is why I set the goal with the $1000 in mind.&lt;/p&gt;

&lt;p&gt;These are the rules I’m setting for myself. The product or the way I’m going to reach that monetary target, will be by my own means. So it cannot be any part-time job, any full-time job, or something I’m doing for my employer. I am going to be the owner of the product.&lt;/p&gt;

&lt;p&gt;I’m also keeping the field a bit broad, and maybe I’ll broaden it later. Primarily because I don’t want to focus only on SaaS products. I can do more than SaaS, and I don’t have to confine myself to that. I could do research projects. I know how to program a microcontroller or a Raspberry Pi, I can figure it out. I’ve worked with Arduino and a bit of IoT. I’ve done basic UI/UX design and graphic design. So I can use any of those skills.&lt;/p&gt;

&lt;p&gt;That’s one rule. I’d say that’s the second rule—the first is that it needs to be my own thing, not from an employer. The second is that I can utilize any of the skills I have to produce that amount. The third is using any tools at my disposal. That means not banning AI, but using it efficiently, not as much as possible, because that could ruin things. I try to avoid using AI for everything, and instead use it where it makes sense, where it’s better than doing it myself. For example, I do some QA tasks with AI using specific tools, cloud code, and other workflows.&lt;/p&gt;

&lt;p&gt;Another rule is that working with clients is allowed, as long as I’m the one building the projects. I’ll still own them, even if I’m supplying a service. So it could be like a SaaS, but even if it’s not, there's IoT-based projects or other things I can produce.&lt;/p&gt;

&lt;p&gt;The final step would be to broaden the horizon later on, maybe investing in something beyond software or hardware. I’m not sure yet, but it’s something I think I could explore.&lt;/p&gt;

&lt;p&gt;That’s the primary direction I’m setting for myself, and that’s what I’m going to follow. I’m not sure how far I’ll get, but I’m going to keep going toward this goal.&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%2Flb7h03qhll8st15vq1pr.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%2Flb7h03qhll8st15vq1pr.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devjournal</category>
      <category>saas</category>
      <category>sideprojects</category>
      <category>startup</category>
    </item>
    <item>
      <title>Check out my new blog on MCP!</title>
      <dc:creator>ShatilKhan</dc:creator>
      <pubDate>Wed, 20 Aug 2025 10:02:39 +0000</pubDate>
      <link>https://dev.to/siren/-2n5</link>
      <guid>https://dev.to/siren/-2n5</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/siren/building-my-first-mcp-server-using-swagger-openapitools-38kg" class="crayons-story__hidden-navigation-link"&gt;Building my first Local MCP server using Swagger &amp;amp; OpenAPITools&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/siren" class="crayons-avatar  crayons-avatar--l  "&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%2Fuser%2Fprofile_image%2F558537%2F82f48ad4-591e-4a86-816a-10250ca198cb.jpg" alt="siren profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/siren" class="crayons-story__secondary fw-medium m:hidden"&gt;
              ShatilKhan
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                ShatilKhan
                
              
              &lt;div id="story-author-preview-content-2552018" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/siren" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F558537%2F82f48ad4-591e-4a86-816a-10250ca198cb.jpg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;ShatilKhan&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/siren/building-my-first-mcp-server-using-swagger-openapitools-38kg" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Aug 3 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/siren/building-my-first-mcp-server-using-swagger-openapitools-38kg" id="article-link-2552018"&gt;
          Building my first Local MCP server using Swagger &amp;amp; OpenAPITools
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/mcp"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;mcp&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/openapi"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;openapi&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/softwareengineering"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;softwareengineering&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/tooling"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;tooling&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
            &lt;a href="https://dev.to/siren/building-my-first-mcp-server-using-swagger-openapitools-38kg#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            6 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>mcp</category>
      <category>openapi</category>
      <category>softwareengineering</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Building my first Local MCP server using Swagger &amp; OpenAPITools</title>
      <dc:creator>ShatilKhan</dc:creator>
      <pubDate>Sun, 03 Aug 2025 14:30:00 +0000</pubDate>
      <link>https://dev.to/siren/building-my-first-mcp-server-using-swagger-openapitools-38kg</link>
      <guid>https://dev.to/siren/building-my-first-mcp-server-using-swagger-openapitools-38kg</guid>
      <description>&lt;p&gt;Let's be real: enterprise software can feel like a labyrinth. Our app at AnchorBlock, &lt;a href="https://anchorbooks.ai/its-magic" rel="noopener noreferrer"&gt;AnchorBooks.ai&lt;/a&gt;, is a beast with hundreds of features for finance and bookkeeping. It's powerful, but finding what you need can mean a dozen clicks through a maze of menus.&lt;/p&gt;

&lt;p&gt;So, I got this crazy idea: what if you could just talk to the app? What if you could say, "Hey, create an invoice for client X with these items," and it would just... happen?&lt;/p&gt;

&lt;p&gt;That's the dream, right? To give our app a brain. This is the story of how I took the first step, moving from a complex API to a simple chat prompt. In this first part of our two-part series, we're going full mad-scientist-in-the-lab. We'll build a local tool server using the Model Context Protocol (MCP) and hook it up to GitHub Copilot, proving we can control our entire backend with plain English.&lt;/p&gt;

&lt;p&gt;Let's get our hands dirty.&lt;/p&gt;

&lt;p&gt;Step 1: The Rosetta Stone for AI - Turning an API into Tools&lt;/p&gt;

&lt;p&gt;An AI model, as smart as it is, has no idea what a POST /api/item request is. You can't just give it your backend URL and hope for the best. It needs a manual, an instruction book that clearly explains what's possible.&lt;/p&gt;

&lt;p&gt;For us, that manual was our Swagger (OpenAPI) documentation. With over 249 endpoints, our NestJS backend was well-documented, which turned out to be the secret ingredient. Each endpoint definition, with its inputs and outputs, was a potential "skill" we could teach our AI.&lt;/p&gt;

&lt;p&gt;But was I going to manually write a wrapper script for all 249 endpoints? Absolutely not. My laziness (I call it efficiency) led me to a game-changing tool: &lt;a href="https://openapitools.com/" rel="noopener noreferrer"&gt;OpenAPITools&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Think of OpenAPITools as a magic translator. You feed it your swagger.json file, and it spits out a ready-to-use MCP server structure, complete with Python scripts for every single API endpoint. It's like giving the AI a universal remote for our app, and OpenAPITools just programmed all the buttons for us.&lt;/p&gt;

&lt;p&gt;Here’s a quick look at that workflow:&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%2Fqakpfjyx1gotadypzpt0.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%2Fqakpfjyx1gotadypzpt0.png" alt="mcp flow" width="694" height="1317"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Step 2: A Peek Under the Hood: The Anatomy of a Single Tool&lt;/p&gt;

&lt;p&gt;Let's zoom in on one example to see how this actually works. Say we want to create a new item in our inventory.&lt;/p&gt;

&lt;p&gt;In our NestJS backend, we have a CreateItemDto that defines exactly what data is needed. It's decorated with @ApiProperty for Swagger, which is key.&lt;/p&gt;

&lt;p&gt;The Source of Truth: dto/create-item.dto.ts&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%2Fz9oqyox9c7vf8425bx62.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%2Fz9oqyox9c7vf8425bx62.png" alt="item dto" width="800" height="541"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When OpenAPITools reads this, it generates two crucial files:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The AI's Cheat Sheet: tools.json (Snippet)
This file is the manifest. It tells the AI, "Hey, there's a tool called ItemCreator. It needs a name, a type, a price, and so on." The schema here is a direct translation of our DTO.&lt;/li&gt;
&lt;/ol&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%2Fo90e5aut21y8uqj18r57.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%2Fo90e5aut21y8uqj18r57.png" alt="toolsjson" width="800" height="837"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The Worker Bee: ItemCreator-main.py
This Python script is the muscle. Its job is dead simple: get the JSON input from the AI, build a real HTTP request with the right headers (including our JWT token for auth!), and fire it off to our actual NestJS backend.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Extract parameters from the AI's request
&lt;/h3&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%2Fbovozh0bw3r55bzlun4x.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%2Fbovozh0bw3r55bzlun4x.png" alt="boilerplate" width="800" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Build the payload for our NestJS API
&lt;/h3&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%2F6f3574ay53fsdmnmcm96.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%2F6f3574ay53fsdmnmcm96.png" alt="payload" width="800" height="546"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Get our secret JWT token from the environment
&lt;/h3&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%2F4rjd6uhaamsqkb3zam33.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%2F4rjd6uhaamsqkb3zam33.png" alt=" " width="800" height="465"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Make the actual API call!
&lt;/h3&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%2F1fse2ys57dfwaaqm3drp.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%2F1fse2ys57dfwaaqm3drp.png" alt="api call" width="800" height="180"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Send the result back to the AI
&lt;/h3&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%2Ft659uvpmbblti8wery2a.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%2Ft659uvpmbblti8wery2a.png" alt=" " width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And just like that, every single one of our 249 endpoints had its own little Python worker, ready and waiting for orders.&lt;/p&gt;

&lt;p&gt;Step 3: Firing Up the Local Brain&lt;/p&gt;

&lt;p&gt;With our tools ready, we needed a "switchboard operator" to direct traffic from the AI agent to the correct Python script. The generated project includes a lightweight Node.js server that does exactly this. For local testing, it runs in stdio mode, communicating silently in the background.&lt;/p&gt;

&lt;p&gt;The stdio-server.js file orchestrates everything, but the gist is simple:&lt;/p&gt;

&lt;p&gt;It starts up and reads our tools.json to know what tools are available.&lt;/p&gt;

&lt;p&gt;It listens for two main commands from an agent: ListTools (what can you do?) and CallTool (do this thing!).&lt;/p&gt;

&lt;p&gt;When CallTool comes in, it finds the right Python script, passes along the inputs, and pipes the result back to the agent.&lt;/p&gt;

&lt;p&gt;I just pop open my terminal, run node index.js, and my local AI "brain" is online.&lt;/p&gt;

&lt;p&gt;Step 4: The "It's Alive!" Moment: Hooking up GitHub Copilot&lt;/p&gt;

&lt;p&gt;This is where it gets really cool. We have a server running on our machine that knows how to use our app. Now, let's connect an AI to it. GitHub Copilot's agent mode is perfect for this.&lt;/p&gt;

&lt;p&gt;Here’s how you can do it too:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Light Up the Server
In your terminal, navigate to your MCP project folder and run the server.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will just sit there, waiting. That's what it's supposed to do!&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Tweak Your VS Code Settings&lt;br&gt;
Open your VS Code User settings.json file. The easiest way is to press Ctrl+Shift+P (or Cmd+Shift+P) and type Preferences: Open User Settings (JSON).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tell Copilot About Your Server&lt;br&gt;
Add this snippet to your settings.json. This tells Copilot, "Hey, there's a tool server available. If I say @anchorbooks, you should run this command to talk to it."&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  // ...your other settings...
  "github.copilot.mcp.enabled": true,
  "github.copilot.mcp.servers": {
    "anchorbooks": { // Call it whatever you want
      "command": "node",
      "args": [
        // IMPORTANT: Use the FULL, absolute path to your index.js file
        "G:\\Office\\anchorbooks\\item-mcp-tool\\index.js"
      ]
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pro Tip: Make sure the path is correct! This trips up a lot of people.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Let the Magic Happen
Restart VS Code to make sure the settings take effect. Now, open the GitHub Copilot chat panel and type @—you should see your server's name (@anchorbooks) pop up!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I sent my first command:&lt;/p&gt;

&lt;p&gt;@anchorbooks create a new item of type goods named "Premium Arabica Beans" with a selling price of 25 and purchase price of 15. Use unit "kg", sales account 1, purchase account 2, for organization 1.&lt;/p&gt;

&lt;p&gt;I held my breath. A few seconds later... success!&lt;/p&gt;

&lt;p&gt;Copilot parsed my sentence, correctly identified the ItemCreator tool, mapped all the parameters, and sent the request to my local Node.js server. The server executed the Python script, which made a real, authenticated API call to my backend. A new item was created in my database, and the JSON response appeared right in my chat window.&lt;/p&gt;

&lt;p&gt;(Placeholder: Screenshot of the Copilot chat with the prompt and the successful tool execution and JSON response)&lt;/p&gt;

&lt;p&gt;It felt like magic. I could now manage invoices, update bills, transfer stock—perform over 33 complex backend operations—just by chatting with Copilot.&lt;/p&gt;

&lt;p&gt;What's Next?&lt;/p&gt;

&lt;p&gt;We've built a powerful local playground. We proved that we can bridge the gap between human language and a complex API. But let's be honest, this is a lab experiment. The "brain" is tethered to my machine and depends on an external tool like VS Code.&lt;/p&gt;

&lt;p&gt;This setup is awesome, but it's not a product.&lt;/p&gt;

&lt;p&gt;In Part 2 of this series, we're cutting the cord. I’ll show you how we took this successful experiment and turned it into a real, integrated feature by:&lt;/p&gt;

&lt;p&gt;Ditching the local server and building the MCP logic directly into our NestJS backend.&lt;/p&gt;

&lt;p&gt;Creating our very own chat interface right inside the AnchorBooks.ai app.&lt;/p&gt;

&lt;p&gt;Plugging into powerful models like Claude 3.5 for smarter, faster tool use.&lt;/p&gt;

&lt;p&gt;Stay tuned, because that's when we truly give our application a mind of its own.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Author's Note:&lt;/em&gt; No code repos shared here since it was a company project. I wanted to share my experience building stuff &amp;amp; will continue the story in the 2nd blog along with more code examples for better understanding. This workflows also works with complex operations like invoice creation or generating new customer and multi stage workflows as well which we'll discuss in future blogs.&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>openapi</category>
      <category>softwareengineering</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Stop Your Code From Having a Mid-Life Crisis. An Introduction to OOP.</title>
      <dc:creator>ShatilKhan</dc:creator>
      <pubDate>Sun, 27 Jul 2025 18:34:46 +0000</pubDate>
      <link>https://dev.to/siren/stop-your-code-from-having-a-mid-life-crisis-an-introduction-to-oop-28j7</link>
      <guid>https://dev.to/siren/stop-your-code-from-having-a-mid-life-crisis-an-introduction-to-oop-28j7</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/siren/engineering-of-small-things-5-oop-basics-in-typescript-2k1h" class="crayons-story__hidden-navigation-link"&gt;Engineering of Small Things #5: OOP Basics in TypeScript&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/siren" class="crayons-avatar  crayons-avatar--l  "&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%2Fuser%2Fprofile_image%2F558537%2F82f48ad4-591e-4a86-816a-10250ca198cb.jpg" alt="siren profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/siren" class="crayons-story__secondary fw-medium m:hidden"&gt;
              ShatilKhan
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                ShatilKhan
                
              
              &lt;div id="story-author-preview-content-2188485" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/siren" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F558537%2F82f48ad4-591e-4a86-816a-10250ca198cb.jpg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;ShatilKhan&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/siren/engineering-of-small-things-5-oop-basics-in-typescript-2k1h" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jul 27 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/siren/engineering-of-small-things-5-oop-basics-in-typescript-2k1h" id="article-link-2188485"&gt;
          Engineering of Small Things #5: OOP Basics in TypeScript
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/typescript"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;typescript&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/beginners"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;beginners&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/tutorial"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;tutorial&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/oop"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;oop&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
            &lt;a href="https://dev.to/siren/engineering-of-small-things-5-oop-basics-in-typescript-2k1h#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            5 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>typescript</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>oop</category>
    </item>
    <item>
      <title>Engineering of Small Things #5: OOP Basics in TypeScript</title>
      <dc:creator>ShatilKhan</dc:creator>
      <pubDate>Sun, 27 Jul 2025 14:30:00 +0000</pubDate>
      <link>https://dev.to/siren/engineering-of-small-things-5-oop-basics-in-typescript-2k1h</link>
      <guid>https://dev.to/siren/engineering-of-small-things-5-oop-basics-in-typescript-2k1h</guid>
      <description>&lt;p&gt;Ahoy!&lt;br&gt;
Back after quite a while, I originally planned to release this blog &amp;amp; couple others a long time ago but I guess life gets in the way.&lt;/p&gt;

&lt;p&gt;Today we are going to look into some basic concepts of Object Oriented Programming.&lt;br&gt;
And this isn't meant to be any kind of high level overview. Just me sharing my learning.&lt;br&gt;
So! with that , let's begin!&lt;/p&gt;
&lt;h2&gt;
  
  
  What is Object Oriented Programming anyway?
&lt;/h2&gt;

&lt;p&gt;Object-oriented programming (OOP) is a programming paradigm based on the concept of "objects", which can contain data and code: data in the form of fields (often known as attributes or properties), and code, in the form of procedures (often known as methods). &lt;/p&gt;
&lt;h3&gt;
  
  
  The Six Pillars of OOP: A Family Story
&lt;/h3&gt;
&lt;h4&gt;
  
  
  1. Classes: The Blueprint of You
&lt;/h4&gt;

&lt;p&gt;First things first, what's a class?&lt;/p&gt;

&lt;p&gt;Think of a &lt;strong&gt;Class&lt;/strong&gt; as a blueprint. It's not a person, but it &lt;em&gt;describes&lt;/em&gt; what makes a person. For instance, a &lt;code&gt;Human&lt;/code&gt; class would be a blueprint defining that all humans have properties like a &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;age&lt;/code&gt;, and &lt;code&gt;eyeColor&lt;/code&gt;.&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%2Fkbguhuz3qnwlx5p5a853.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%2Fkbguhuz3qnwlx5p5a853.png" alt="Class"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  2. Objects: You, the Instance
&lt;/h4&gt;

&lt;p&gt;So if a Class is the blueprint, what are you? You, my friend, are an Object.&lt;/p&gt;

&lt;p&gt;An object is a real, living, breathing instance created from a class. While the Human class is the idea, you are the implementation. You have a specific name, a specific age, and so on. In code, we create a 'new' object from our class.&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%2Fxsnixzkqxbmgj8h4uh78.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%2Fxsnixzkqxbmgj8h4uh78.png" alt="Object"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A better visualization of the difference between Objects &amp;amp; Classes:&lt;br&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%2Fuml0nml9crwwzhbzb5fm.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%2Fuml0nml9crwwzhbzb5fm.png" alt="Class &amp;amp; Object"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  3. Encapsulation: Your Personal Bubble
&lt;/h4&gt;

&lt;p&gt;Encapsulation is about bundling your properties (data) and your methods (behaviors) together in that neat little Human object. It also means you can have secrets!&lt;/p&gt;

&lt;p&gt;Some things about you are public, like your name. Anyone can ask for it. But some things are private, like your deepest, darkest thoughts. You keep those encapsulated. In OOP, this prevents outsiders from messing with the internal state of an object.&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%2Fietq0wado2zexw0nbkdl.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%2Fietq0wado2zexw0nbkdl.png" alt="Encapsulation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Onward we go!&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%2Ffaofs2m4uhfakeds5njc.gif" 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%2Ffaofs2m4uhfakeds5njc.gif" alt="meme"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  4. Abstraction: Don't Overthink it!
&lt;/h4&gt;

&lt;p&gt;Abstraction means hiding the complexity and showing only the essentials.&lt;/p&gt;

&lt;p&gt;Think about meeting someone. You say "Hello!" and they say "Hello!" back. You don't need to know the complex biological processes of how their brain processed your greeting and formulated a response. You just need to know the simple interface: the greet() method. Abstraction hides the messy details.&lt;br&gt;
Similar stuff happens when you go for a walk, you don't need to understand how your body keeps balance or how it pushes you forward to follow Newton's law. You just need to put one feet in front of the other.&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%2Fgt9roe7u1ypmk8bq368s.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%2Fgt9roe7u1ypmk8bq368s.png" alt="Abstraction"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You don't get the whole story, just the parts you need to interact with.&lt;/p&gt;
&lt;h4&gt;
  
  
  5. Inheritance: Your Family Legacy
&lt;/h4&gt;

&lt;p&gt;Serious Life Talk!&lt;br&gt;
Let's say you fall in love! And Decide to have babies!&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%2Fhjuq1kh0a6smc2lgds2n.gif" 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%2Fhjuq1kh0a6smc2lgds2n.gif" alt="baby"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Your children will inherit traits from you. They might get your last name or your eye color.&lt;/p&gt;

&lt;p&gt;Inheritance lets a new class (a Child) adopt the properties and methods of an existing class (a Parent). This saves you from rewriting the same code over and over. The child can have all the parent's features, plus their own unique ones.&lt;/p&gt;

&lt;p&gt;So let's say YOU , The Parent, are a human:&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%2F6xzeqthwa1l8m5tin7ei.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%2F6xzeqthwa1l8m5tin7ei.png" alt="Inheritance-1"&gt;&lt;/a&gt;&lt;br&gt;
You have your name, age &amp;amp; last name&lt;br&gt;
And then you decide to have your first child:&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%2F0dqw103hsyunzg29r55z.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%2F0dqw103hsyunzg29r55z.png" alt="Inheritance-2"&gt;&lt;/a&gt;&lt;br&gt;
You name your first child "Itchy"&lt;br&gt;
So NOW your child will naturally inherit your last name:&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%2Fyk0d57p4dw5w2mru23u7.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%2Fyk0d57p4dw5w2mru23u7.png" alt="Inheritance-3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we can use the properties the Child inherited from the parent to carry out tasks:&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%2Ffcsqu9qxfpg2wa4i3xq6.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%2Ffcsqu9qxfpg2wa4i3xq6.png" alt="Inh-4"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Just like that your kid got your last name &amp;amp; other stuff from your DNA (Class). Kid could inherit your crippling depression &amp;amp; anxiety as well.&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%2Fmvf2s9cycsw535vtufe3.gif" 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%2Fmvf2s9cycsw535vtufe3.gif" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  6. Polymorphism: Different Folks, Different Strokes
&lt;/h4&gt;

&lt;p&gt;Polymorphism is a big word for a simple idea: "many forms." It means you can treat objects of different classes in the same way, but they each behave in their own unique style.&lt;/p&gt;

&lt;p&gt;Imagine you ask everyone in the family to doTheirChore().&lt;br&gt;
The Parent might respond by "mowing the lawn", while the Child responds by "tidying up toys". The same instruction (doTheirChore()) produces different results. That's polymorphism in action!&lt;br&gt;
We could add a chore(funtion) to each respective Classes (Parent &amp;amp; Child)&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%2Fj60pxfwrvax38s5znssi.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%2Fj60pxfwrvax38s5znssi.png" alt="polymorphism1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can then assign the chores to the classes:&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%2Fsdon1w14m2v5p5d4w0sh.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%2Fsdon1w14m2v5p5d4w0sh.png" alt="polymorphism2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And finally we can add new function calls &amp;amp; execute the Chores!&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%2Fr89a6q2t8te9nzzg3273.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%2Fr89a6q2t8te9nzzg3273.png" alt="polymorphism3"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Wrapping Up
&lt;/h3&gt;

&lt;p&gt;And there you have it! The big ideas of OOP, explained through the story of you and your family. It's a powerful way to structure your code, and once you get the hang of it, you'll see how it makes building complex things so much more manageable.&lt;/p&gt;

&lt;p&gt;I'm still on this learning journey myself. A massive shout-out to the repo that got me started and helped me understand these concepts in depth:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/jafari-dev" rel="noopener noreferrer"&gt;
        jafari-dev
      &lt;/a&gt; / &lt;a href="https://github.com/jafari-dev/oop-expert-with-typescript" rel="noopener noreferrer"&gt;
        oop-expert-with-typescript
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A complete guide for learning object oriented programming pillars, SOLID principles and design patterns with TypeScript!
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Object Oriented Programming Expert with TypeScript&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;This repository is a complete guide and tutorial for the principles and techniques of object-oriented programming. It can be a reference for all interested in programming and software developers. You will find simple and practical examples in all sections to make the concepts easier to understand.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Table of Contents&lt;/h2&gt;
&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://github.com/jafari-dev/oop-expert-with-typescript#fundamentals" rel="noopener noreferrer"&gt;Fundamentals&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/jafari-dev/oop-expert-with-typescript#whats-object-oriented-programming" rel="noopener noreferrer"&gt;What's Object-Oriented-Programming?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jafari-dev/oop-expert-with-typescript#class" rel="noopener noreferrer"&gt;Class&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jafari-dev/oop-expert-with-typescript#objects" rel="noopener noreferrer"&gt;Objects&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jafari-dev/oop-expert-with-typescript#abstraction" rel="noopener noreferrer"&gt;Abstraction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jafari-dev/oop-expert-with-typescript#encapsulation" rel="noopener noreferrer"&gt;Encapsulation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jafari-dev/oop-expert-with-typescript#inheritance" rel="noopener noreferrer"&gt;Inheritance&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jafari-dev/oop-expert-with-typescript#polymorphism" rel="noopener noreferrer"&gt;Polymorphism&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/jafari-dev/oop-expert-with-typescript#solid-principles" rel="noopener noreferrer"&gt;SOLID Principles&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/jafari-dev/oop-expert-with-typescript#whats-solid-meaning" rel="noopener noreferrer"&gt;What's SOLID Meaning?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jafari-dev/oop-expert-with-typescript#1-single-responsibility-srp" rel="noopener noreferrer"&gt;Single Responsibility (SRP)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jafari-dev/oop-expert-with-typescript#2-openclosed-ocp" rel="noopener noreferrer"&gt;Open/Closed (OCP)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jafari-dev/oop-expert-with-typescript#3-liskov-substitution-lsp" rel="noopener noreferrer"&gt;Liskov Substitution (LSP)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jafari-dev/oop-expert-with-typescript#4-interface-segregation-isp" rel="noopener noreferrer"&gt;Interface Segregation (ISP)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jafari-dev/oop-expert-with-typescript#5-dependency-inversion-dip" rel="noopener noreferrer"&gt;Dependency Inversion (DIP)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/jafari-dev/oop-expert-with-typescript#design-patterns" rel="noopener noreferrer"&gt;Design Patterns&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/jafari-dev/oop-expert-with-typescript#whats-a-design-pattern" rel="noopener noreferrer"&gt;What's a Design Pattern?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jafari-dev/oop-expert-with-typescript#abstract-factory" rel="noopener noreferrer"&gt;Creational - Abstract Factory&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jafari-dev/oop-expert-with-typescript#builder" rel="noopener noreferrer"&gt;Creational - Builder&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jafari-dev/oop-expert-with-typescript#factory-method" rel="noopener noreferrer"&gt;Creational - Factory Method or Virtual Constructor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jafari-dev/oop-expert-with-typescript#prototype" rel="noopener noreferrer"&gt;Creational - Prototype or Clone&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jafari-dev/oop-expert-with-typescript#singleton" rel="noopener noreferrer"&gt;Creational - Singleton&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jafari-dev/oop-expert-with-typescript#adapter-wrapper" rel="noopener noreferrer"&gt;Structural - Adapter or Wrapper&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jafari-dev/oop-expert-with-typescript#bridge" rel="noopener noreferrer"&gt;Structural - Bridge&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jafari-dev/oop-expert-with-typescript#composite-object-tree" rel="noopener noreferrer"&gt;Structural - Composite or Object Tree&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jafari-dev/oop-expert-with-typescript#decorator-wrapper" rel="noopener noreferrer"&gt;Structural - Decorator or Wrapper&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jafari-dev/oop-expert-with-typescript#facade" rel="noopener noreferrer"&gt;Structural - Facade&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jafari-dev/oop-expert-with-typescript#flyweight-cache" rel="noopener noreferrer"&gt;Structural - Flyweight or Cache&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jafari-dev/oop-expert-with-typescript#proxy" rel="noopener noreferrer"&gt;Structural - Proxy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jafari-dev/oop-expert-with-typescript#chain-of-responsibility" rel="noopener noreferrer"&gt;Behavioral - Chain of Responsibility&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/jafari-dev/oop-expert-with-typescript#command" rel="noopener noreferrer"&gt;Behavioral - Command or&lt;/a&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/jafari-dev/oop-expert-with-typescript" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;And if you want to see my personal study notes and the code examples I'm tinkering with, I've open-sourced them here:&lt;/p&gt;

&lt;p&gt;My OOP in TS Study Repo:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/ShatilKhan" rel="noopener noreferrer"&gt;
        ShatilKhan
      &lt;/a&gt; / &lt;a href="https://github.com/ShatilKhan/OOP-TS-Study" rel="noopener noreferrer"&gt;
        OOP-TS-Study
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Study on Object Oriented Programming with TypeScript
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://private-user-images.githubusercontent.com/52494840/400137931-74af0377-5c90-4f14-b9b2-1ac214e4a2f7.jpg?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NzQ2NDgzMTUsIm5iZiI6MTc3NDY0ODAxNSwicGF0aCI6Ii81MjQ5NDg0MC80MDAxMzc5MzEtNzRhZjAzNzctNWM5MC00ZjE0LWI5YjItMWFjMjE0ZTRhMmY3LmpwZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjAzMjclMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwMzI3VDIxNDY1NVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPThjZWExYWIyZjZlOTI4NzEzZmRiZDBmNWUxYmM1NzFjNjRiYWIxNzg0MWQzOTRjOTRhODk4NDA5MjkzZmM0YjAmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.5_mQ21vKUH_5mVoOeqkIPt_eMx87CH_aqrQ7gC_jAhk"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fprivate-user-images.githubusercontent.com%2F52494840%2F400137931-74af0377-5c90-4f14-b9b2-1ac214e4a2f7.jpg%3Fjwt%3DeyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NzQ2NDgzMTUsIm5iZiI6MTc3NDY0ODAxNSwicGF0aCI6Ii81MjQ5NDg0MC80MDAxMzc5MzEtNzRhZjAzNzctNWM5MC00ZjE0LWI5YjItMWFjMjE0ZTRhMmY3LmpwZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjAzMjclMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwMzI3VDIxNDY1NVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPThjZWExYWIyZjZlOTI4NzEzZmRiZDBmNWUxYmM1NzFjNjRiYWIxNzg0MWQzOTRjOTRhODk4NDA5MjkzZmM0YjAmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.5_mQ21vKUH_5mVoOeqkIPt_eMx87CH_aqrQ7gC_jAhk" alt="EST#5 (1)"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;OOP-TS-Study&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Study on Object Oriented Programming with TypeScript&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;What's Object-oriented-programming?&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Object-oriented programming (OOP) is a programming paradigm based on the concept of "objects", which can contain data and code: data in the form of fields (often known as attributes or properties), and code, in the form of procedures (often known as methods). There are 6 pillars of OOP, includes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Class&lt;/li&gt;
&lt;li&gt;Objects&lt;/li&gt;
&lt;li&gt;Data Abstraction&lt;/li&gt;
&lt;li&gt;Encapsulation&lt;/li&gt;
&lt;li&gt;Inheritance&lt;/li&gt;
&lt;li&gt;Polymorphism&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;We can use &lt;a href="https://www.typescriptlang.org/play" rel="nofollow noopener noreferrer"&gt;TypeScript Playground&lt;/a&gt; to run the code. We can also use VS Code directly.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Running TypeScript Code in Visual Studio Code&lt;/h1&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Prerequisites&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://nodejs.org/" rel="nofollow noopener noreferrer"&gt;Node.js&lt;/a&gt; and npm installed on your machine.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Steps&lt;/h2&gt;

&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Install TypeScript&lt;/strong&gt;
Open the terminal in Visual Studio Code and run the following command to install TypeScript globally:&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;npm install -g typescript &lt;/pre&gt;

&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Check TypeScript Installation&lt;/strong&gt;:
Verify that TypeScript is installed by running:&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;tsc --version&lt;/pre&gt;

&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Create a &lt;code&gt;tsconfig.json&lt;/code&gt; File&lt;/strong&gt;
In your project directory, create a &lt;code&gt;tsconfig.json&lt;/code&gt; file to configure the…&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/ShatilKhan/OOP-TS-Study" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;You might see that some of the code is a few months old, as I stated at the beginning I initially planned to publish this blog a while ago but just couldn't find the time. &lt;br&gt;
And I'm also experimenting with writing techniques &amp;amp; how to better present coding topics. &lt;br&gt;
If you like this one, make sure to check out other blogs in this series.&lt;br&gt;
Engineering of Small Things Series is basically written up to share where I explore fundamental topics of how the web works.&lt;br&gt;
More to come soon!&lt;br&gt;
And Happy Coding!&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%2F0t8a2wwzthd3n6lzr5n7.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%2F0t8a2wwzthd3n6lzr5n7.png" alt="Ai-was-definitely-used"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>oop</category>
    </item>
    <item>
      <title>ক্লাউড কম্পিউটিং কি জিনিস ?</title>
      <dc:creator>ShatilKhan</dc:creator>
      <pubDate>Fri, 07 Feb 2025 06:27:30 +0000</pubDate>
      <link>https://dev.to/siren/klaaudd-kmpiuttin-ki-jinis--7pd</link>
      <guid>https://dev.to/siren/klaaudd-kmpiuttin-ki-jinis--7pd</guid>
      <description>&lt;p&gt;&lt;em&gt;Author's Note: This blog is a bit different compared to my other blogs. This blog is specifically meant for student who want to learn a basic idea about cloud computing. This is also part of my work as an AWS Cloud Club Captain at my Campus. So on this blog I try to give students a general idea about cloud. And since my primary audience for this blog is Bangladeshi students I thought I would try to explain things in Bengali to keep it fun!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;এখন আসি আসল কথায়, ক্লাউড কম্পিউটিং জিনিস টা আসলে কি?&lt;/strong&gt;&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%2Fd4bame392gw09mqka6j0.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%2Fd4bame392gw09mqka6j0.png" alt="What is cloud" width="272" height="510"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;আপনার Day-to-day লাইফের সবচেয়ে সহজ আর চেনার মত একটা উদাহরণ দিতে গেলে বলা যায় ড্রাইভ স্টোরেজ(ড্রপবক্স, গুগল ড্রাইভ ইত্যাদি) । এইধরণের সার্ভিস গুলা মোটামুটি সবাই ইউজ করে বা না করলেও ফিচার গুলা সবার ফোনেই এক্টিভ । এই ক্ষেত্রে আসলে কি হচ্ছে? &lt;br&gt;
ধরেন আপনি আপনার কোন ছবি ড্রাইভ স্টোরেজে রাখলেন, এখন সেটা আপনি যেকোন জায়গা থেকে এক্সেস করতে পারবেন।&lt;br&gt;
এই যে আপনার ফাইল/ছবিগুলা রাখলেন, এখন আপনার ফোন থেলে ডিলিট করে দিলেও সেটা পরে আপনি এক্সেস করতে পারবেন, right?&lt;br&gt;
এই ডাটা টা সেভ হচ্ছে কোন এক বান্দার সার্ভারে, আপনি যখন ডাটা চাইবেন তখন বেসিকেলি সার্ভার সেই ডাটা আপনাকে দিবে। এই যে দূরে কোন সার্ভারে ডাটা রাখার যেই ব্যাপার টা, এটাই ক্লাউড কম্পিউটিং এর সবচেয়ে বেসিক অংশ।&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%2Fm5guu64hq31m397ov0pn.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%2Fm5guu64hq31m397ov0pn.png" alt="user server" width="523" height="566"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;আরো কিছু বেসিক উদারণ হচ্ছে ওয়েবসাইট হোস্ট করা। ওয়েবসাইট হোস্ট করলেও সেটা কোন সার্ভারে থাকে, পরে যে কেউ সেখান থেকে এক্সেস করতে পারে একটা পাবলিক ডোমেইন এড্রেস দিয়ে।&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;এখন আসি Amazon Web Services বা AWS নিয়ে&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;"Amazon Web Services, Inc. is a subsidiary of Amazon that provides on-demand cloud computing platforms and APIs to individuals, companies, and governments, on a metered, pay-as-you-go basis. Clients will often use this in combination with autoscaling." - Wikipedia&lt;/p&gt;

&lt;p&gt;এখন এই কথার মানে কি? on-demand, metered, pay-as-you-go, auto-scaling?&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%2F44uq1it0e0mbmup9x2kz.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%2F44uq1it0e0mbmup9x2kz.png" alt="what" width="257" height="346"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;এই ব্লগের উদ্দেশ্য , যে স্টুডেন্ট ক্লাউড নিয়ে কিছুই জানে না তাদের কে জানানো। তাই AWS কে সহজ ভাবে বুঝাচ্ছি।&lt;/p&gt;

&lt;p&gt;AWS  হচ্ছে বিশ্বের সবচেয়ে বড় ক্লাউড প্রোভাইডার। মানে AWS  বিভিন্ন ধরণের ক্লাউড রিলেটেড সার্ভিস দেয় কাস্টমার দের। এর মধ্যে কিছু বেসিক সার্ভিস হলো ওয়েবসাইট হোস্টিং, ডোমেইন সেটাপ , ডাটাবেস ম্যানেজ করা । &lt;br&gt;
এখন কথা হচ্ছে এগুলা দেয়ার কারণ কি?&lt;br&gt;
ধরলাম ক্লাউড কম্পিউটিং নামের কোন জিনিস নাই। এখন আপনই একটা কম্পানি খুলতে চাচ্ছেন, সেক্ষেত্রে আপনার ওয়েবসাইট লাগবেই। এখন আপনাকে সেই সাইট চালাইতে গেলে আগে নিজে একটা সার্ভার কম্পিউটার কেনা লাগবে, যেগুলার দাম লাখ লাখ টাকা। সেই সার্ভার রাখার জন্যে রুম লাগবে, রুমের আবার এসি লাগবে, নাহলে সার্ভারের মাথা গরম হয়ে যাবে।&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%2Fnkxwzmehyrfd4q0z5k5j.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%2Fnkxwzmehyrfd4q0z5k5j.png" alt="server on fire" width="367" height="316"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;তার মানে আপনার বিজনেস শুরু করতে গেলে আপনার বড় একটা এমাউন্টের ইনভেস্টমেন্ট লাগবে।&lt;br&gt;
এখন আসি ক্লাউডে। &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;আপনার সার্ভার লাগবে? ভাড়া নেন!&lt;/strong&gt;&lt;br&gt;
AWS  বেসিকেলি নিজেদের সার্ভার গুলা আপনাকে অল্প মূল্যে ভাড়া দিবে। যার বদলে আপনাকে pay-as-you-go  বা যতটুকু স্টোরেজ আপনার লাগবে সেই অনুযায়ী পেমেন্ট করবেন।&lt;/p&gt;

&lt;p&gt;এখন কিছু বেসিক AWS  সার্ভিস নিয়ে আলোচনা করি।&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%2Fzs4d184dy4ttd3nlo9n1.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%2Fzs4d184dy4ttd3nlo9n1.png" alt="basic aws services" width="459" height="216"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;S3 বা &lt;em&gt;Simple Storage Service&lt;/em&gt; হচ্ছে AWS  র সবচেয়ে বেসিক অফারিং, যেটা আমরা মোটামুটি ডেইলি কোন না কোন ভাবে ইউজ করি। যেমন আপনই গুগল ড্রাইভে কোন ছবি রাখলে সেটার ড্রাইভ লিংক যে কারো সাথে শেয়ার করতে পারেন, S3  সেই সুবিধাটাই দেয়। তবে এক্ষেত্রে আরো অনেক ফিচার আছে, আমি ব্যাপার অনেক বেশি সিমপ্লিফাই করে বলছি।&lt;/p&gt;

&lt;p&gt;এটার সহজ একটা উদারণ দেই, এই যে ব্লগ টা পড়ছেন, যেই ইমেজ গুলা এখানে দেখতে পাচ্ছেন, এগুলা আসলে আমি যখন আপলোড করছি, জিনিস টা আগে S3  তে যায়, তারপর সেখান থেকে একটা লিংক জেনারেট হয়, তারপর সেই লিংক টা এখানে আসে, যেটার মাধ্যমে আপনারা ইমেজ গুলা দেখতে পান।&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%2Fn8vqp0gvb45ok6boapg1.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%2Fn8vqp0gvb45ok6boapg1.png" alt="S3" width="800" height="352"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;এখন আসি &lt;em&gt;Amplify&lt;/em&gt; নিয়ে, এগুলা নিয়ে ওতটা বলবো না কারণ বিগিনার হিসেবে জাস্ট ক্লাউডের আইডিয়া দেয়ার জন্যে বলা।&lt;br&gt;
Amplify দিয়ে বেসিকেলি আমরা আমাদের যেকোন ওয়েবসাইট হোস্টিং আর ডিপ্লয়মেন্টের কাজ করতে পারি। যারা আগে কখনো নিজেদের কোন ওয়েবসাইট হোস্ট করে থাকবেন তাদের জন্যে জিনিস টা বোঝা সহজ হবে।&lt;br&gt;
বেসিকেলি আপনার GitHub রিপো বা কডের ফাইল আপলোড করলে Amplify সেটা হোস্ট করে একটা হোস্টেড ডিপ্লয়মেন্ট লিংক দেবে। ডোমেইন নেম সেটাপের জন্য আমরা AWS Route 53 র মত সার্ভিস ইউজ করতে পারি যেখানে আমরা কোন কাস্টম ডোমেইন নেম কিনে সেটাপ করতে পারবো। তবে সেগুলা এই ব্লগের বিষয় নয়, আগামী কোন ব্লগে এই রিলেটেড প্রসেস নিয়ে আলোচনা করবো।&lt;/p&gt;

&lt;p&gt;এবং সবশেষে EC2 বা &lt;em&gt;Elastic Compute Cloud&lt;/em&gt;, এটাও বিগিনারদের জন্য বোঝা একটু কমপ্লেক্স মনে হতে পারে। তবে আমি চেষ্টা করবো সহজভাবে বোঝানোর। &lt;br&gt;
ধরেন আপনার ল্যাপটপ বা পিসি টা মানধাতার আমলের, ৪ জিবি র‍্যাম , ৪ কোরের প্রসেসর ইত্যাদি। এখন আপনই আপনার পিসিতে কোন একটা রিসোর্স ইন্টেন্সিভ কাজ করতে চাচ্ছেন, যেটার জন্যে অনেক র‍্যাম লাগবে বা আরো বেশি প্রসেসিং পাওয়ার লাগবে।&lt;br&gt;
EC2 আপনার জন্যে একটা &lt;em&gt;ভার্চুয়াল পিসি / মেশিন (VM)&lt;/em&gt; রেডি করে দিবে। মানে ধরেন আপনার ৮ জিবি/১৬ জিবি র‍্যামের পিসি লাগবে। ওই যে আগে বলছিলাম যে সার্ভার ভাড়া নেয়ার ব্যাপার টা। এমাজন বেসিকেলি অনেক গুলা সার্ভার কম্পিউটার শেয়ারে ভাড়া দিচ্ছে। আর একটা সার্ভারের র‍্যাম কয়েকশ জিবি বা তার বেশি হয়, প্রসেসিং পাওয়ারও । তখন ওরা বেসিকেলি আপনাকে নির্দিষ্ট এমাউন্ট ভাড়া দিবে , যতটুকু আপনার দরকার (&lt;em&gt;৮ জিবি র‍্যাম/৪ কোর প্রসেসর, ১৬জিবি র‍্যাম / ৮ কোর প্রসেসর&lt;/em&gt;)। এবং আপনই যতটুকু ইউজ করবেন সেই অনুযায়ী আপনার খরচ আসবে। এখন প্রশ্ন আসতে পারে, তাহলে এই যে এত হাই লেভেলের মেশিন লার্নিং মডেল বা এডভান্স এলগিরদম নিয়ে বড় কম্পানিগুলায় কাজ হয়, এগুলা তাহলে ওরা এভাবে করে?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ঠিক ধরেছেন!&lt;/strong&gt;&lt;br&gt;
হ্যাঁ অনেকেই নিজস্ব সার্ভার কিনে,কিন্তু ছোট কম্পানি বা স্টার্টাপ গুলা ম্যাক্সিমাম এভাবেই কাজ করে। আপনার বেশি লার্নিং মডেল ট্রেইন করাতে যেই জিপিউ রিসোর্স লাগবে সেটাও ক্লাউডের মাধ্যমে এক্সেস নিয়ে করা হয়। তবে এগুলা বিগিনার টপিকের বাইরে পরে তাই অন্যদিন আলোচনা করবো।&lt;/p&gt;

&lt;p&gt;ব্লগ টা মেইনলি এবস্যুলুট বিগিনার দের উদ্দেশ্য করেই বানানো। কারণ অনেক ক্ষেত্রেই বাংলাদেশে বেশিরভাগ ভার্সিটি গুলোতে আলাদাভাবে কোন ক্লাউডের কোর্স বা এধরণের শেখার সুবিধা নাই। কিন্তু AI নিয়ে সবাই লাফায়, ওয়েব ডেভেলপমেন্ট নিয়ে এত মাতামাতি, দিনশেষে কোন না কোন পর্যায়ে যায়ে ক্লাউডের কাজ শিখতেই হবে। তাই এই ব্লগের উদ্দেশ্য ছিল স্টুডেন্ট দের সেই বিষয়ে বেসিক আইডিয়া দেয়া।&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Author's Note: If you want to learn more about the topic's mentioned &amp;amp; would love to see more blogs on this, I'd appreciate if you comment down below to show your interest.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>cloud</category>
      <category>aws</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Engineering of Small Things #4 : WebSockets</title>
      <dc:creator>ShatilKhan</dc:creator>
      <pubDate>Fri, 27 Dec 2024 05:09:07 +0000</pubDate>
      <link>https://dev.to/siren/engineering-of-small-things-4-websockets-4n6</link>
      <guid>https://dev.to/siren/engineering-of-small-things-4-websockets-4n6</guid>
      <description>&lt;p&gt;Hello Again!&lt;/p&gt;

&lt;p&gt;Recently I was working on a website where I needed to pull data from the server periodically, it wasn't really required as the database updated only once a week or so. But still I thought it would be nice to have a way if I could periodically get data from server without having to request it from the client side. SO then I came across socket servers!&lt;br&gt;
It basically allows two-way communication between a client &amp;amp; a server. We can also setup timeout methods so that the server automatically sends data  to the client on  a regular interval.&lt;br&gt;
So I studied a bit on the topic , got some help from chatgpt :)&lt;br&gt;
But also I like to learn from experience engineers rather than regular courses. One of the engineers I admire is &lt;a class="mentioned-user" href="https://dev.to/husseinnasser"&gt;@husseinnasser&lt;/a&gt; . I followed a short crash course from Nasser about WebSockets as well. Because as a non-CSE student I didn't really know how the underlying connections work. So I needed to learn from scratch! &lt;br&gt;
And it was indeed a great experience. I first learned about protocols! HTTP, HTTP 1.1, TCP, UDP &lt;br&gt;
This gave me a good foundation to understand what's going on in a WebSocket server.&lt;br&gt;
Then I made a raw websokcet server using http. I set up certain breakpoints &amp;amp; tested the connection between the server &amp;amp; the client. It was unique way to learn because I didn't write much frontend code for this. Instead I tested the client by directly sending client messages from the browser console!&lt;/p&gt;

&lt;p&gt;First we'll need a basic http server : &lt;/p&gt;

&lt;p&gt;Basic Package Requirements &amp;amp; Connection :&lt;br&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%2Fwbwjl59t4svl4x51qds7.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%2Fwbwjl59t4svl4x51qds7.png" alt=" " width="800" height="313"&gt;&lt;/a&gt;&lt;br&gt;
Now there is a Null connection variable here, we'll get to it later.&lt;/p&gt;

&lt;p&gt;Base http server initiate:&lt;br&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%2Fg6ayjt2zr6ucw93jvjsk.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%2Fg6ayjt2zr6ucw93jvjsk.png" alt=" " width="800" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But this is just a request-response server. Once a response is received, connection is gone. We need a reliable connection. This is where TCP comes in. When I pass in this http server into a WebSocket server it will then send an UPGRADE 1.1 header request to the server from the client side. It will request to switch protocol from http to http 1.1 &amp;amp; establish a TCP connection for full-duplex communication.&lt;br&gt;
Pass in the http server into the websocket server to create a TCP connection:&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%2Fp22g0eqw5sya1jdm9idk.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%2Fp22g0eqw5sya1jdm9idk.png" alt=" " width="800" height="365"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Server Listening:&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%2F337104xvm5bzplhx2kyx.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%2F337104xvm5bzplhx2kyx.png" alt=" " width="800" height="269"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;the websocket server can choose weather to accept the request or not , &lt;br&gt;
accepting sends back swithing protocol 101 response , which opens up the full duplex communication between client &amp;amp; server&lt;br&gt;
1st parameter is a custom protocol , could be for chatting , gaming, null means we'll accept anything, no specific protocol needed&lt;br&gt;
2nd paramter - we can check the origin of the request, generally the url the request was sent from , to checck if it's atrusted source&lt;br&gt;
Below are the events that we can use , open, close, message etc.The main point of WebSockets is having these events.&lt;br&gt;
When each event occurs we can get a certain response from server automatically without the client needing to initiate a request&lt;br&gt;
Socket Events:&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%2Fwfj8i58x1ny4yj68rcpf.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%2Fwfj8i58x1ny4yj68rcpf.png" alt=" " width="800" height="469"&gt;&lt;/a&gt;&lt;br&gt;
Notice we see the null connection here that we initiated in the beginning. This tells the server that we can accept ANYTHING. Any type of data is accepted as we are just testing. &lt;br&gt;
Now we can send &amp;amp; receive connection between the server &amp;amp; client&lt;br&gt;
From the Debug console in VS Code we can send a server message:&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%2F9lg34wod07g0i2ynb0sv.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%2F9lg34wod07g0i2ynb0sv.png" alt=" " width="800" height="356"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then from the browser console, we can send a client response:&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%2Fo1blwuniiabvusrhpfy4.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%2Fo1blwuniiabvusrhpfy4.png" alt=" " width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The connection stays open as long as nobody closes the connection.&lt;br&gt;
If the server shuts down, the connection will close&lt;br&gt;
if the client browser initiates the event &lt;code&gt;ws.close&lt;/code&gt; the connection will close.&lt;br&gt;
But this is just basic connection. Now We will make a function that will keep sending messages from the WebSocket server to the client on a regular  interval. Think of game streaming , twitch, video streaming etc.&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%2F7cyepuufrvltdrqxfbn7.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%2F7cyepuufrvltdrqxfbn7.png" alt=" " width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pass in the function after we open the connection:&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%2Fmts9nfme3sv1sx088obn.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%2Fmts9nfme3sv1sx088obn.png" alt=" " width="800" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can log this stream of messages on the client side using &lt;code&gt;onmessage&lt;/code&gt; event&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%2Fz246i1dyr6prmq5zxev6.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%2Fz246i1dyr6prmq5zxev6.png" alt=" " width="800" height="188"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Voila We just made a full-duplex two-way communication between a server &amp;amp; a client.&lt;/p&gt;

&lt;p&gt;Super fun stuff to learn!&lt;/p&gt;

&lt;p&gt;Codebase:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/ShatilKhan" rel="noopener noreferrer"&gt;
        ShatilKhan
      &lt;/a&gt; / &lt;a href="https://github.com/ShatilKhan/socket-server" rel="noopener noreferrer"&gt;
        socket-server
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      exploring how socket servers work
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;socket-server&lt;/h1&gt;

&lt;/div&gt;
&lt;p&gt;exploring how socket servers work&lt;/p&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/ShatilKhan/socket-server" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;Check out the video to see the code in action:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/7RaDgU1VP-U"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>node</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Engineering of Small Things #3 : Small Language Models</title>
      <dc:creator>ShatilKhan</dc:creator>
      <pubDate>Thu, 19 Dec 2024 10:33:28 +0000</pubDate>
      <link>https://dev.to/siren/engineering-of-small-things-3-small-language-models-37kh</link>
      <guid>https://dev.to/siren/engineering-of-small-things-3-small-language-models-37kh</guid>
      <description>&lt;p&gt;Disclaimer! I am NOT an AI Influencer! This is literally just me learning about how to implement a hugging face model for the first time.&lt;br&gt;
And Boy Was it Hard! :)) &lt;/p&gt;

&lt;h2&gt;
  
  
  What is this even about?
&lt;/h2&gt;

&lt;p&gt;I built a document Question &amp;amp; answering bot for this demonstration. It takes an Image &amp;amp; we can query &amp;amp; ask questions regarding that Image.&lt;br&gt;
I had no idea how to implement language models going into this. So it was a really fun experience. Now this is part of a bigger project. Today I'm just sharing one part of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Going Crazy
&lt;/h2&gt;

&lt;p&gt;This was for a hackathon project where I was trying to use &lt;a class="mentioned-user" href="https://dev.to/streamlit"&gt;@streamlit&lt;/a&gt; &amp;amp; &lt;a href="https://huggingface.co/" rel="noopener noreferrer"&gt;HuggingFace&lt;/a&gt; , I never even had a hugging face account &amp;amp; had only basic tutorial level experience on &lt;a class="mentioned-user" href="https://dev.to/streamlit"&gt;@streamlit&lt;/a&gt; . But I really wanted to learn &amp;amp; implement something on my own. I was tired of following tutorials &amp;amp; it didn't matter if it was a standard solution or not!&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%2Ffsryyoxi35f1cox0whvt.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%2Ffsryyoxi35f1cox0whvt.png" alt=" " width="220" height="307"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But like the heading says, I did go crazy a couple times :)&lt;/p&gt;

&lt;h2&gt;
  
  
  The beginning of Insanity
&lt;/h2&gt;

&lt;p&gt;Now I'm a web developer who had only heard about hugging face, didn't really care about the hype. But then I decided to experiment a little with this tech. I did not have the necessary setup on my local device , so firstly I had to install &lt;code&gt;PyTorch&lt;/code&gt; &amp;amp; &lt;code&gt;TesseractOCR&lt;/code&gt; on my local PC first. I will not be sharing this trauma :)&lt;br&gt;
Those who know...know 😫&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%2Fbuj3042h84lts1ftbhfz.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%2Fbuj3042h84lts1ftbhfz.png" alt=" " width="750" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But I will take you through how I implemented it!&lt;/p&gt;

&lt;p&gt;First we need the basic ingredients! A transformer!&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%2Fykayb3xlqdmgdsp5wg5n.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%2Fykayb3xlqdmgdsp5wg5n.png" alt=" " width="360" height="539"&gt;&lt;/a&gt;&lt;br&gt;
How does it work? - I have no f**king Idea!&lt;br&gt;
What does it do? - Makes language model go "brrrr"&lt;/p&gt;

&lt;p&gt;And a library to read Image files.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Basic Imports:&lt;/strong&gt;&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%2Fywt1sdatss2te53f9vpd.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%2Fywt1sdatss2te53f9vpd.png" alt=" " width="800" height="345"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now to initialize our pipeline.&lt;br&gt;
What does that even mean? Basically we are selecting a language model from huggingface model catalogue. And also setting what type of model that is. Here comes the main point of this blog. Small Language Models. At first I did try to use a popular Large Language Model (Mistral) , but here's the thing, after we've initialized a pipeline, when I run the program for the first time, it needs to download the model onto my local device. But like I've stated before, I have shitty internet &amp;amp; the Mistral-8B was like 2GB+. Every time I would start the project, the model would download halfway &amp;amp; give up.&lt;br&gt;
So I opted to choose a Small Language Model called &lt;a href="https://huggingface.co/impira/layoutlm-document-qa" rel="noopener noreferrer"&gt;impira/layoutlm-document-qa&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a 500 MB model that was a good enough job of answering questions from an uploaded document. But there's some parameters, like the uploaded document needs to be an image, hence the need for a separate library to read image files (PIL).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pipeline Initialization:&lt;/strong&gt;&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%2F4d17isflpd3aic2plxce.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%2F4d17isflpd3aic2plxce.png" alt=" " width="800" height="327"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But here's the hard lesson I learned. I used streamlit cloud to deploy the project. So it was running on a cloud gpu. But after a few minutes of usage it would become WAY TOO resource intensive &amp;amp; the project would shut down due to streamlit cloud's resource limitations. I couldn't figure this out for SOO long. But then streamlit came to the rescue again. Using &lt;a href="https://docs.streamlit.io/develop/api-reference/caching-and-state" rel="noopener noreferrer"&gt;&lt;code&gt;st.cache&lt;/code&gt;&lt;/a&gt; we can cache out data so that they become less resource intensive. But I was using &lt;a href="https://docs.streamlit.io/develop/api-reference/caching-and-state/st.cache_data" rel="noopener noreferrer"&gt;&lt;code&gt;st.cache_data&lt;/code&gt;&lt;/a&gt; at first, now this API only caches Images or other Data, NOT AI MODELS. Because AI Language Models are classified as resources. So later I had to switch to &lt;a href="https://docs.streamlit.io/develop/api-reference/caching-and-state/st.cache_resource" rel="noopener noreferrer"&gt; &lt;code&gt;st.cache_resource&lt;/code&gt;&lt;/a&gt; which finally solved the problem!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Caching Pipeline Initialization:&lt;/strong&gt;&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%2F5oybhksndnxshqk38zwi.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%2F5oybhksndnxshqk38zwi.png" alt=" " width="800" height="321"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The next steps were pretty easy once I solved the main problem.&lt;br&gt;
On the next stage I used an &lt;code&gt;if-statement&lt;/code&gt; to check if image file is uploaded &amp;amp; loaded the pipeline so the SLM could read the file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Verify Image Upload:&lt;/strong&gt;&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%2F13vg4cvm8ln4r1kbl6c1.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%2F13vg4cvm8ln4r1kbl6c1.png" alt=" " width="800" height="271"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that I initialized a form using &lt;a href="https://docs.streamlit.io/develop/api-reference/execution-flow/st.form" rel="noopener noreferrer"&gt;&lt;code&gt;st.form&lt;/code&gt;&lt;/a&gt; to submit a question&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Initialize form:&lt;/strong&gt;&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%2Fit78gj7yhcur7c5wh3sj.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%2Fit78gj7yhcur7c5wh3sj.png" alt=" " width="800" height="321"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If a question is submitted , the image will be opened &amp;amp; the AI Model will query the image.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Open Query:&lt;/strong&gt;&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%2Fi4zwwaduqesijxbrsc0u.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%2Fi4zwwaduqesijxbrsc0u.png" alt=" " width="800" height="411"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now the query performed doesn't just produce one answer. Remember, this is a language model, it doesn't understand human language, but can only predict the next word based on training data. So in this case it will produce multiple answer. &lt;br&gt;
Finally it will choose the most probable answer and show it to the user!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Get the best answer:&lt;/strong&gt;&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%2F1cffkrwn6r6opwkakgr5.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%2F1cffkrwn6r6opwkakgr5.png" alt=" " width="800" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's the main file: &lt;a href="https://github.com/ShatilKhan/Hemo/blob/main/hemo.py" rel="noopener noreferrer"&gt;https://github.com/ShatilKhan/Hemo/blob/main/hemo.py&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There's a lot of other features as it is part of a larger project, I just explained the part where I used a Language Model is all.&lt;br&gt;
Hopefully I'll write more about other features of this project soon!&lt;br&gt;
Happy Coding!&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%2Fl3kzbs69xor01rs7vnnv.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%2Fl3kzbs69xor01rs7vnnv.png" alt=" " width="259" height="194"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>learning</category>
    </item>
    <item>
      <title>Engineering of Small Things #2: Cookies</title>
      <dc:creator>ShatilKhan</dc:creator>
      <pubDate>Wed, 11 Dec 2024 21:35:26 +0000</pubDate>
      <link>https://dev.to/siren/engineering-of-small-things-2-cookies-43b2</link>
      <guid>https://dev.to/siren/engineering-of-small-things-2-cookies-43b2</guid>
      <description>&lt;p&gt;Cookies!&lt;br&gt;
I love it, you love it, Google Loves it, Third Party Companies that steal your data love it as well!&lt;/p&gt;

&lt;p&gt;Although I have worked with session based authentication before, I have always wondered how it works on a fundamental level.&lt;/p&gt;

&lt;p&gt;Recently I came across a task where I had to access &amp;amp; use cookies to login to a site for "research purposes"&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%2Fuc57ogmcv6eupnt22asc.gif" 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%2Fuc57ogmcv6eupnt22asc.gif" alt=" " width="298" height="298"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So Anyway!&lt;/p&gt;

&lt;p&gt;I needed to load &amp;amp; change a website's cookies to sign into another session. That got me wondering how do cookies actually work.&lt;/p&gt;

&lt;p&gt;I first had a cookies file saved from another session. Basically when I (the user) login each time from any device, it creates a session token. Think of session tokens like keys for your website. There's a lot of other stuff that's created like session_id , puid etc. What's important is that all these things function as a unique identifier so that only the specific user can access the website. Now if we want to login to this same session, we would simply need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;scrape the cookies from this session &lt;/li&gt;
&lt;li&gt;go to a different device or browser where another user is logged in. &lt;/li&gt;
&lt;li&gt;Then paste in the cookies from our previous session &lt;/li&gt;
&lt;li&gt;Finally refresh the site&lt;/li&gt;
&lt;li&gt;And Voila! we just logged into someone's account using their cookies! (Do Not Try This at Home and please don't mention my name if you do try)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I used the &lt;a href="https://cookie-editor.com/" rel="noopener noreferrer"&gt;Cookie-Editor&lt;/a&gt; extension for this task.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First I copied the cookie files from my previous session &lt;/li&gt;
&lt;li&gt;then went to the where I need to login&lt;/li&gt;
&lt;li&gt;Opened the cookie-editor &amp;amp; just pasted in the entire text from the cookie file of my previous session&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Another important thing is the added safety of session-expiry. After some time cookies will expire &amp;amp; you will have to login again. This ensures no one else snoops into your account.&lt;/p&gt;

&lt;p&gt;Now this blog isn't meant as a high-level overview, it's just something I found pretty interesting is all. So I made a short diagram for how cookie based authentication works as well!&lt;br&gt;
I used &lt;a href="https://excalidraw.com" rel="noopener noreferrer"&gt;Excalidraw&lt;/a&gt; for the diagramming.&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%2F2j4alkic9s0zas220od2.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%2F2j4alkic9s0zas220od2.png" alt=" " width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Happy Coding!&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%2Fhf8y5x6jhj2z3ykfbluf.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%2Fhf8y5x6jhj2z3ykfbluf.png" alt=" " width="543" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>tutorial</category>
      <category>beginners</category>
      <category>basic</category>
    </item>
    <item>
      <title>Engineering of Small Things #1 : Email Newsletters</title>
      <dc:creator>ShatilKhan</dc:creator>
      <pubDate>Wed, 04 Dec 2024 19:53:53 +0000</pubDate>
      <link>https://dev.to/siren/engineering-of-small-things-1-email-newsletters-18gh</link>
      <guid>https://dev.to/siren/engineering-of-small-things-1-email-newsletters-18gh</guid>
      <description>&lt;p&gt;This is by no means a guide on how to make Email Newsletter, but rather the particular problems I faced while developing my first email newsletter as a jr. dev &amp;amp; how I found the solution the hard way!&lt;/p&gt;

&lt;h2&gt;
  
  
  The Beginning of a Disaster
&lt;/h2&gt;

&lt;p&gt;Recently I had the opportunity to develop an Email newsletter , but also I had to make a backend functionality to send to multiple people at once. I used Mailgun API for email management. But also at the same time, had no idea how one might develop a newsletter subscription system (honestly , I'm still learning :))&lt;/p&gt;

&lt;p&gt;In a Figma File Far Far Away....&lt;br&gt;
There was a design, that I had no idea how to convert to code &amp;amp; send to a bunch of people. So I did what literally everyone does these days.&lt;/p&gt;

&lt;p&gt;AI... I used an AI&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%2Fofo77f84kipw8e5jngca.gif" 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%2Fofo77f84kipw8e5jngca.gif" alt=" " width="600" height="335"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But that is just the beginning of the disaster :)&lt;br&gt;
I thought I could just convert the figma file to html &amp;amp; send it. Well that plan seems solid until I actually tried doing it &amp;amp; figured the plugins convert figma to basic html which don't have images linked. Some plugins do, but most are premium. &lt;/p&gt;

&lt;h2&gt;
  
  
  AWS S3 to the Rescue
&lt;/h2&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%2Fsp2tl4h22b6zmi8wezi6.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%2Fsp2tl4h22b6zmi8wezi6.png" alt=" " width="549" height="303"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So I used good old S3 Bucket to store the images &amp;amp; serve them.&lt;br&gt;
But it wasn't easy. I still iterated through a bunch of AI Figma Plugins &amp;amp; what I realized was that instead of Figma to HTML Plugin, I needed Figma to Email Template Plugin. There's a big difference &amp;amp; we'll discuss why in a moment.&lt;br&gt;
But basically I innocently downloaded the html code, uploaded EACH Photo to S3 .... Multiple Times Too! Because I have shitty Internet :)&lt;/p&gt;

&lt;p&gt;Then the html template for the email was done! Then I ran by Script for sending the Email to a list of recipients. It was pretty basic Script that has a function read a list of emails from an excel sheet &amp;amp; send an html template to those emails.&lt;/p&gt;

&lt;p&gt;So I loaded up everything &amp;amp; sent a test mail to my own mail first (pheew)&lt;/p&gt;

&lt;p&gt;The email looked liked this:&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%2F0eulcoslu3jschlwz6fe.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%2F0eulcoslu3jschlwz6fe.png" alt=" " width="498" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No CSS Loaded, No Structure... Nothing. Just a bunch of text.&lt;/p&gt;

&lt;p&gt;Then I started googling... and I found that google doesn't allow any external CSS to be sent over email. And a lot of other css classed &amp;amp; properties aren't allowed. What fascinated me was WHY they weren't allowed. Because they can be used as a vulnerability to inject malicious scripts. 👀👀👀&lt;/p&gt;

&lt;p&gt;So THEN I looked for Figma to Email Template &amp;amp; Found &lt;a href="https://kombai.com/" rel="noopener noreferrer"&gt;Kombai &lt;/a&gt;!&lt;br&gt;
Kombai proved to be a great tool for email newsletter because it creates html template that directly adhere to gmail css restrictions.&lt;/p&gt;

&lt;p&gt;It also organized the images in the design properly.&lt;br&gt;
And then I had to use AWS S3 again 😢. But finally got it working (Kinda). I mean it worked mostly fine ,except on some devices where it still broke. But Yeah, building a Email Newsletter Template Sender from Scratch is like reinventing the wheel :)&lt;/p&gt;

&lt;p&gt;But I learned some interesting Info. Also While I was checking different figma plugins for html conversion, I found &lt;a href="https://app.brevo.com/" rel="noopener noreferrer"&gt;Brevo&lt;/a&gt; ! Which is like an All in one tool for email marketing.&lt;br&gt;
Mailgun is also good , I used it to track the emails. But it does not have a template designer. In comparison Brevo had a lot of built in features. Then I learned more about Brevo's no-code/low-code email newsletter features. But ultimately I learned a lot stuff while making this newsletter template.&lt;br&gt;
I also made a small diagram &amp;amp; I want to hone my skills in designing architecture components. &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%2F6srt1320hmvwmfhx3uug.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%2F6srt1320hmvwmfhx3uug.png" alt=" " width="771" height="541"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;None of these are perfect or standard, but I wanted to learn how to make these architecture designs as well and I thought the best way would be to get my hands dirty!&lt;br&gt;
Keep on Coding!&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%2F9kxno2mz4dcowvcaelys.gif" 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%2F9kxno2mz4dcowvcaelys.gif" alt=" " width="256" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>webdev</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
