<?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: Gokul Suresh</title>
    <description>The latest articles on DEV Community by Gokul Suresh (@gokul_suresh).</description>
    <link>https://dev.to/gokul_suresh</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1846892%2F2be36c81-a196-4fb1-9e4b-58ef737d5141.png</url>
      <title>DEV Community: Gokul Suresh</title>
      <link>https://dev.to/gokul_suresh</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gokul_suresh"/>
    <language>en</language>
    <item>
      <title>Testing AWS-integrated apps for free: a local setup with Floci and ngrok</title>
      <dc:creator>Gokul Suresh</dc:creator>
      <pubDate>Fri, 17 Jul 2026 07:08:11 +0000</pubDate>
      <link>https://dev.to/gokul_suresh/testing-aws-integrated-apps-for-free-a-local-setup-with-floci-and-ngrok-17c1</link>
      <guid>https://dev.to/gokul_suresh/testing-aws-integrated-apps-for-free-a-local-setup-with-floci-and-ngrok-17c1</guid>
      <description>&lt;p&gt;&lt;em&gt;Build, test, and share AWS-powered applications without an AWS account or deployment.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem I kept running into
&lt;/h2&gt;

&lt;p&gt;If your app talks to AWS — uploading files to S3, queuing jobs through SQS, running functions on Lambda — development normally forces an uncomfortable choice.&lt;/p&gt;

&lt;p&gt;Option one: write separate "fake" code paths just for local development (&lt;code&gt;if (isDev) return fakeData&lt;/code&gt;). This means the code path you're actually testing every day is not the code path that runs in production. Bugs in your real AWS integration logic slip through, because you never actually exercised it locally.&lt;/p&gt;

&lt;p&gt;Option two: use a real AWS account for development too. This works, but it costs money for every test run, requires every teammate to have their own AWS credentials, and means someone has to manage IAM permissions just so people can build features.&lt;/p&gt;

&lt;p&gt;Neither is great. There's a third option that solved this for me completely, and it costs nothing: run a local AWS look-alike on your own laptop, and use a tunneling tool to let others access what's running there. This post walks through exactly how, and why each piece exists.&lt;/p&gt;

&lt;h2&gt;
  
  
  The two tools, and what they actually do
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Floci — a local AWS emulator
&lt;/h3&gt;

&lt;p&gt;Floci is an open-source program that emulates AWS's API surface on your own machine. It listens on &lt;code&gt;localhost:4566&lt;/code&gt; and responds to the same requests real AWS would — create a bucket, upload a file, invoke a function — using the exact same request format Amazon defined.&lt;/p&gt;

&lt;p&gt;The key detail: your application code doesn't know the difference. If you're using the official AWS SDK (&lt;code&gt;@aws-sdk/client-s3&lt;/code&gt;, &lt;code&gt;boto3&lt;/code&gt;, whatever your language's equivalent is), that code has no idea whether it's really talking to Amazon or to a program pretending to be Amazon. It just sends requests to whatever address it's configured with.&lt;/p&gt;

&lt;p&gt;For some services, Floci goes further than a shallow mock — it spins up real backing containers. Point it at "RDS" and it actually runs Postgres. Point it at "ElastiCache" and it actually runs Redis. So you're not just getting plausible-looking fake responses; for the stateful services, you're getting the real thing, just running locally instead of in Amazon's data centers.&lt;/p&gt;

&lt;h3&gt;
  
  
  ngrok — a tunnel to your laptop
&lt;/h3&gt;

&lt;p&gt;Once your app is running locally, it's still only reachable from your own machine — localhost means "this same computer," and your home or office router blocks incoming connections from strangers by default (a security feature, not a bug).&lt;/p&gt;

&lt;p&gt;ngrok solves this with a trick worth understanding, because it explains why no firewall configuration is ever needed: your laptop opens an outbound connection to ngrok's servers (always allowed, since outbound traffic isn't blocked). That connection stays open, like a phone call that never hangs up. ngrok then hands you a public URL. When someone visits it, ngrok's servers receive the request and relay it back down the open connection to your laptop, which replies, and the reply relays back out the same way.&lt;/p&gt;

&lt;p&gt;Nobody ever connects to your laptop directly. They connect to ngrok, and ngrok relays through the tunnel your laptop itself opened.&lt;/p&gt;

&lt;h2&gt;
  
  
  Request flow diagram
&lt;/h2&gt;

&lt;p&gt;Simplified down to just the request/response round trip, here's what happens every time someone opens your ngrok link:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Browser
   │  1. GET https://xyz.ngrok.app
   ▼
ngrok edge server (public IP)
   │  2. forwarded down the open tunnel
   ▼
ngrok agent (your laptop)
   │  3. localhost:3000
   ▼
Your app handles the request
   │  4. response travels back up the same path
   ▼
Browser renders the page
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The full picture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Visitor's browser
        │
ngrok's public server (has a real public IP)
        │
Open tunnel (started BY your laptop, stays open)
        │
ngrok agent running on your laptop
        │
Your app (e.g. localhost:3000)
        │
AWS SDK calls -&amp;gt; Floci (localhost:4566)
        │
Real Docker containers for stateful services
        │
Data persisted to a folder on your own disk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three independent layers: your application code (unchanged), an emulation layer intercepting AWS calls, and an access layer exposing the whole thing publicly if you want to share it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture diagram
&lt;/h2&gt;

&lt;p&gt;A cleaner, boxed view of the same setup — useful as a quick visual reference for the stack running on your machine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                Internet
                    │
                    ▼
          ngrok Public URL
                    │
        Secure Tunnel (HTTPS)
                    │
                    ▼
┌──────────────────────────┐
│      Local Machine        │
│                           │
│  React / Next.js Frontend │
│            │              │
│  Express / Nest Backend   │
│            │              │
│         AWS SDK           │
│            │              │
│          Floci            │
│            │              │
│  S3 • DynamoDB • SQS      │
│  Lambda • Secrets Manager │
└──────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Development workflow
&lt;/h2&gt;

&lt;p&gt;Laid out as a loop, this is the day-to-day cycle the setup is built around:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Write Feature
      │
      ▼
Run Application Locally
      │
      ▼
Floci emulates AWS
      │
      ▼
Test Uploads
      │
      ▼
Share using ngrok
      │
      ▼
Receive Feedback
      │
      ▼
Deploy to Render
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Setting it up, step by step
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Install Docker and ngrok
&lt;/h3&gt;

&lt;p&gt;Floci runs inside a Docker container, so Docker needs to be installed and running first. ngrok is a separate download from ngrok.com.&lt;/p&gt;

&lt;p&gt;Verify Docker is working:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker info
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Register your ngrok account once:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ngrok config add-authtoken &amp;lt;your-token&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Write a docker-compose.yml
&lt;/h3&gt;

&lt;p&gt;This file tells Docker which image to run and how to configure it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;floci&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;floci/floci:1.5.11&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;local_aws_cloud&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;4566:4566"&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;FLOCI_STORAGE_MODE=persistent&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;SERVICES=s3,dynamodb,sqs,lambda,rds,secretsmanager&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./data:/app/data&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/var/run/docker.sock:/var/run/docker.sock&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few details worth explaining rather than just copying:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pin a specific version tag (&lt;code&gt;1.5.11&lt;/code&gt;, not &lt;code&gt;:latest&lt;/code&gt;). If everyone on a team pulls &lt;code&gt;:latest&lt;/code&gt;, people end up on different versions with different env var names, and setups silently drift apart.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;./data:/app/data&lt;/code&gt; is a bind mount — it maps a folder on your real hard disk to a folder inside the container. This is what makes storage survive restarts; without it, everything Floci stores would vanish the moment the container stopped.&lt;/li&gt;
&lt;li&gt;The Docker socket mount (&lt;code&gt;/var/run/docker.sock&lt;/code&gt;) is what lets Floci spin up real containers for services like RDS and Lambda, instead of faking them. It's also a real security boundary worth knowing about — more on that below.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Start it and confirm it's healthy
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
curl http://localhost:4566/_localstack/health
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The health check returns a JSON list of every AWS service Floci is currently emulating and whether each is running. If this doesn't come back, nothing downstream will work, so it's worth checking before moving on.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Point your app's AWS SDK at it
&lt;/h3&gt;

&lt;p&gt;Set these before running your app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;AWS_ENDPOINT_URL&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;http://localhost:4566&lt;/span&gt;
&lt;span class="py"&gt;AWS_ACCESS_KEY_ID&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;111111111111&lt;/span&gt;
&lt;span class="py"&gt;AWS_SECRET_ACCESS_KEY&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;test&lt;/span&gt;
&lt;span class="py"&gt;AWS_DEFAULT_REGION&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;us-east-1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Floci accepts any credential value — it doesn't validate them the way real AWS does. The one exception: a 12-digit numeric access key gets treated as an account identifier, useful if multiple people share one Floci instance and want isolated resources. Anything else falls into a shared default account.&lt;/p&gt;

&lt;p&gt;If your code constructs its own S3Client (or equivalent), it needs to actually read this endpoint variable — the SDK doesn't automatically know to redirect just because the variable exists, unless your code passes it through explicitly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;s3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;S3Client&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;accessKeyId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AWS_ACCESS_KEY_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;secretAccessKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AWS_SECRET_ACCESS_KEY&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;region&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AWS_REGION&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;us-east-1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AWS_ENDPOINT_URL&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;forcePathStyle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AWS_ENDPOINT_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;forcePathStyle&lt;/code&gt; flag matters and is easy to miss. Real AWS S3 prefers requests shaped like &lt;code&gt;bucket-name.s3.amazonaws.com&lt;/code&gt;. Local emulators like Floci expect the older path style instead: &lt;code&gt;localhost:4566/bucket-name&lt;/code&gt;. Without this flag, requests can fail even with the endpoint correctly configured — a genuinely confusing failure mode if you don't know to look for it.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Create a bucket
&lt;/h3&gt;

&lt;p&gt;S3 requires a bucket to exist before anything can be uploaded into it — this rule holds on Floci exactly as it does on real AWS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws &lt;span class="nt"&gt;--endpoint-url&lt;/span&gt; http://localhost:4566 s3 mb s3://your-app-files
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The name has to match whatever your app's config expects, or uploads will fail with a "bucket does not exist" error that has nothing to do with your actual code.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Prove it end to end
&lt;/h3&gt;

&lt;p&gt;Run your app, trigger a real upload through the actual UI, then check that the file landed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws &lt;span class="nt"&gt;--endpoint-url&lt;/span&gt; http://localhost:4566 s3 &lt;span class="nb"&gt;ls &lt;/span&gt;s3://your-app-files/ &lt;span class="nt"&gt;--recursive&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When I did this on a real project, a genuine uploaded file showed up immediately — same upload code path production will use, running entirely for free on a laptop. Worth noting: only the raw file bytes live here. Structured data — filenames, uploader, timestamps — typically stays in your actual database (Mongo, Postgres, whatever you're using), completely separate from Floci. Databases hold records and pointers; S3-style storage holds the heavy binary data. That split doesn't change for local dev — you've just relocated where the storage physically lives.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Share it, if you want to
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ngrok http 3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tunnel only your app's port. Never tunnel the Floci port (4566) directly. If someone reaches that port — through a second tunnel, a misconfigured proxy, or a CORS mistake — they get unauthenticated access to every emulated AWS service on your laptop, including the ones backed by real Docker containers with real host access.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security considerations worth actually reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Docker socket mount is a real trust boundary.&lt;/strong&gt; Floci having access to &lt;code&gt;/var/run/docker.sock&lt;/code&gt; means a compromised emulator has host Docker control. Don't run this setup with that mount on a machine you'd consider sensitive.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Treat anything uploaded through the tunnel as landing in plaintext on your disk.&lt;/strong&gt; Don't use this setup for real customer data — it's a development and testing tool by design, not a secure storage system.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;For anything beyond a same-day test&lt;/strong&gt;, use ngrok's access controls (basic auth or an IP allowlist) in front of the tunnel. Free tier doesn't include this, so a bare link should be treated as something anyone with it can open.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your app's own authentication still applies.&lt;/strong&gt; A tunnel just gets someone to your login screen — it doesn't bypass whatever session/auth logic your app already enforces.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ngrok's free tier, in actual numbers
&lt;/h2&gt;

&lt;p&gt;As of ngrok's 2026 pricing, the free plan gives you: up to 3 concurrent endpoints, 1GB of data transfer per month, and 20,000 HTTP requests per month — not per day, per month, shared across everyone who visits. There's no hard session timeout — an endpoint can stay online continuously as a background service. First-time visitors do see an interstitial warning page before reaching your app (a 7-day cookie skips it after their first visit), and the public URL rotates on every restart unless you're on a paid plan with a reserved domain.&lt;/p&gt;

&lt;p&gt;One clarification worth making: "3 concurrent endpoints" means 3 separate tunnels you can run at once — it has nothing to do with how many people can visit one tunnel's link simultaneously. Any number of people can open the same shared link at the same time; the actual ceiling is the monthly bandwidth and request totals, not concurrent visitor count.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this fits, and where it doesn't
&lt;/h2&gt;

&lt;p&gt;This setup is not a replacement for real hosting. It's genuinely good for exactly two things: catching integration bugs against AWS-shaped services before they ever reach a real AWS bill, and sharing a live, working demo with someone in under a minute without deploying anything.&lt;/p&gt;

&lt;p&gt;It's genuinely not good for anything resembling production traffic. Your laptop has to stay on, the free tier caps are real, and there's no uptime guarantee if your machine sleeps or your network drops.&lt;/p&gt;

&lt;p&gt;For actual hosting — real users, real uptime — platforms like Vercel or Render are the right tool, and they solve a different problem entirely. One detail worth knowing if your app uses WebSockets (Socket.io, for example): Vercel's serverless functions don't support long-lived persistent connections, so a platform like Render, which runs actual persistent servers, is often the better fit for anything beyond simple HTTP APIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Floci + ngrok vs. Render / Vercel
&lt;/h2&gt;

&lt;p&gt;Side by side, the two solve different problems — here's the quick version:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Floci + ngrok&lt;/th&gt;
&lt;th&gt;Render / Vercel&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Purpose&lt;/td&gt;
&lt;td&gt;Development&lt;/td&gt;
&lt;td&gt;Production&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AWS Cost&lt;/td&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;td&gt;Real AWS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deploy Required&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Share Demo&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Always Online&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Laptop Required&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The realistic workflow is to use both, at different stages: local Floci + ngrok while actively building and testing, and a real host once a feature is stable enough for real users to depend on it.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>docker</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Technical Documentation: Integrating Eraser.io via Model Context Protocol (MCP)</title>
      <dc:creator>Gokul Suresh</dc:creator>
      <pubDate>Mon, 13 Jul 2026 18:48:13 +0000</pubDate>
      <link>https://dev.to/gokul_suresh/technical-documentation-integrating-eraserio-via-model-context-protocol-mcp-53fk</link>
      <guid>https://dev.to/gokul_suresh/technical-documentation-integrating-eraserio-via-model-context-protocol-mcp-53fk</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This document provides a comprehensive overview of configuring and utilizing the Eraser.io Model Context Protocol (MCP) server across various AI clients. Integrating Eraser via MCP transforms your static system architecture diagrams and markdown files from standard developer documentation into active context for your AI workflows.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  1. Architectural Overview: How Eraser MCP Works
&lt;/h2&gt;

&lt;p&gt;The Model Context Protocol (MCP) is an open standard designed to securely bridge the gap between LLMs (Large Language Models) and external data sources. Instead of forcing developers to constantly copy-paste snippets or feed heavy text files into context windows, Eraser acts as an MCP Host/Server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────┐        MCP Request        ┌───────────────────┐
│  AI Client /    │ ────────────────────────&amp;gt; │ Eraser MCP Server │
│  Coding Agent   │ &amp;lt;──────────────────────── │ (app.eraser.io)   │
└─────────────────┘       Context JSON        └───────────────────┘
         │                                              │
         ▼                                              ▼
 Reads Local Codebase                         Fetches Architecture,
 &amp;amp; Project Files                              Flowcharts &amp;amp; Tech Docs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When connected, your AI assistant can run native tools exposed by Eraser to programmatically query, read, and understand systemic engineering logic, creating an environment where code generation aligns perfectly with pre-defined architecture boundaries.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Problem of Context Rot
&lt;/h3&gt;

&lt;p&gt;Traditional engineering workflows suffer from documentation decay. Developers update code, but visual diagrams in external tools become outdated. By exposing live canvas objects as machine-readable state via an MCP server, your AI assistants gain visibility into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Current boundary definitions and microservice scopes.&lt;/li&gt;
&lt;li&gt;Up-to-date data schemas and entity relationships.&lt;/li&gt;
&lt;li&gt;Active security rules, encryption boundaries, and compliance mandates.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Configuration Settings Breakdown
&lt;/h2&gt;

&lt;p&gt;Based on the interface shown below, the core connection engine relies on a standardized HTTP transport protocol. Below is the primary endpoint layer used across integrations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MCP Settings Path:&lt;/strong&gt; Accessible via Personal Settings → MCP in the Eraser dashboard.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Base Connection URL:&lt;/strong&gt; &lt;code&gt;https://app.eraser.io/api/mcp&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transport Mechanism:&lt;/strong&gt; HTTP&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authentication Mechanism:&lt;/strong&gt; Managed via Bearer tokens generated natively by the specific integration flow, or through the API Tokens tab under Team Settings.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Client-Specific Integration Playbook
&lt;/h2&gt;

&lt;p&gt;Eraser natively exposes integration vectors for six core AI developer tools. Here is how to configure and utilize each interface.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Claude Code (Anthropic's Agentic CLI)
&lt;/h3&gt;

&lt;p&gt;Claude Code executes directly within your terminal, acting as an interactive engineering agent capable of executing local commands, managing state, and writing software.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setup Implementation:&lt;/strong&gt; Run the following command directly in your project terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude mcp add &lt;span class="nt"&gt;--transport&lt;/span&gt; http eraser https://app.eraser.io/api/mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Operational Capability:&lt;/strong&gt; Once initialized, Claude Code queries the endpoint on demand. If you ask it to build a new microservice route, it checks your active canvas first to preserve compliance, isolation, and formatting criteria.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Primary Use Case:&lt;/strong&gt; Agentic terminal operations where the model creates files, runs build scripts, and refactors large directory structures while referencing systemic documentation.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Claude.ai (Web Interface)
&lt;/h3&gt;

&lt;p&gt;For high-level system architectural debates, product feature scoping, and design review processes conducted outside the terminal environment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setup Implementation:&lt;/strong&gt; Select the Claude.ai client block in Eraser and follow the OAuth authorization prompt to allow the official connector access to your workspace.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Operational Capability:&lt;/strong&gt; Allows you to query the web model directly using conversational requests like: "Review this database schema from my Eraser workspace against our tenant isolation policy."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Primary Use Case:&lt;/strong&gt; Early-stage planning, architectural decision records (ADRs), and non-developer technical strategy reviews.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. OpenAI Codex
&lt;/h3&gt;

&lt;p&gt;Ideal for legacy orchestration setups and developers using custom workflows built around OpenAI's foundational code models.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setup Implementation:&lt;/strong&gt; Point your environment's manual MCP JSON configuration block to target the Eraser API transport layer using your secure API token header.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Operational Capability:&lt;/strong&gt; Supplies raw code completion setups with explicit definitions of complex dependencies, network edges, and microservice topologies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Primary Use Case:&lt;/strong&gt; Automated CI/CD pipeline script generation and custom internal AI tooling configurations.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. VS Code (Visual Studio Code)
&lt;/h3&gt;

&lt;p&gt;Integrates deep architectural context inside the industry's standard code editor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setup Implementation:&lt;/strong&gt; Configured via the workspace or global settings file. You append the Eraser server path directly into the JSON configuration under the server list.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Operational Capability:&lt;/strong&gt; Empowers inline chat mechanisms, prompt sidebars, and local inline edits to respect data flow diagrams and existing module logic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Primary Use Case:&lt;/strong&gt; Day-to-day feature development where developers need immediate, inline feedback based on established architectural patterns.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Cursor
&lt;/h3&gt;

&lt;p&gt;Cursor is designed from the ground up for deep indexing of local repositories. By pairing it with Eraser, it indexes the architectural mapping alongside the codebase.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setup Implementation:&lt;/strong&gt; Navigate to Cursor Settings → Features → MCP. Click Add New MCP Server, choose &lt;code&gt;http&lt;/code&gt; as the type, and input &lt;code&gt;https://app.eraser.io/api/mcp&lt;/code&gt; along with your validation token.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Operational Capability:&lt;/strong&gt; Enables deep contextual symbol lookups and multi-file editing that respects visual boundaries, sequence diagrams, and module interactions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Primary Use Case:&lt;/strong&gt; Complex code generation tasks spanning multiple files and services where strict architectural adherence is required.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. GitHub Copilot
&lt;/h3&gt;

&lt;p&gt;Brings systemic awareness to the default AI pair-programmer natively integrated into the GitHub ecosystem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setup Implementation:&lt;/strong&gt; Configured via the Copilot Chat extensions hub or custom JSON manifests inside enterprise development environments using the HTTP endpoint.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Operational Capability:&lt;/strong&gt; Cuts down on generic boilerplate code suggestions by forcing Copilot's autocompletion logic to operate within the specific guidelines defined inside your team's technical documentation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Primary Use Case:&lt;/strong&gt; Auto-completing daily function bodies and boilerplate with exact type definitions and error-handling routines specified in project documents.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Operational Comparison Matrix
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;AI Client&lt;/th&gt;
&lt;th&gt;Interface&lt;/th&gt;
&lt;th&gt;Primary Connection Method&lt;/th&gt;
&lt;th&gt;Key Architectural Benefit&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Claude Code&lt;/td&gt;
&lt;td&gt;Terminal CLI&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;claude mcp add&lt;/code&gt; CLI command&lt;/td&gt;
&lt;td&gt;Full agentic filesystem access guided by system design.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude.ai&lt;/td&gt;
&lt;td&gt;Web UI&lt;/td&gt;
&lt;td&gt;Direct OAuth / Connector&lt;/td&gt;
&lt;td&gt;High-level system design debates and ADR formulation.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenAI Codex&lt;/td&gt;
&lt;td&gt;Custom / API&lt;/td&gt;
&lt;td&gt;Endpoint Configuration JSON&lt;/td&gt;
&lt;td&gt;Automated pipeline tooling and script generation.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;VS Code&lt;/td&gt;
&lt;td&gt;IDE&lt;/td&gt;
&lt;td&gt;Extension / JSON Settings&lt;/td&gt;
&lt;td&gt;Direct IDE context for standard development loops.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cursor&lt;/td&gt;
&lt;td&gt;Native AI IDE&lt;/td&gt;
&lt;td&gt;MCP Settings UI Panel&lt;/td&gt;
&lt;td&gt;Multi-file generation adhering to visual flowcharts.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GitHub Copilot&lt;/td&gt;
&lt;td&gt;IDE Plugin&lt;/td&gt;
&lt;td&gt;Copilot Extension Manifest&lt;/td&gt;
&lt;td&gt;In-line completions aligned with documented schema specs.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  5. Engineering Best Practices for MCP-First Documentation
&lt;/h2&gt;

&lt;p&gt;To get the most out of Eraser's MCP server, documentation should be structured with the AI's perspective in mind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Keep Text and Diagrams Together:&lt;/strong&gt; Eraser allows anchoring raw Markdown notes directly beneath a visual diagram. Use this to describe architectural decisions, edge cases, or security parameters that a diagram alone cannot convey.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Establish a Single Source of Truth:&lt;/strong&gt; Replace disconnected external files with active workspace canvases. Keep the architecture dynamic and centralized so the AI model never pulls from an outdated specification.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Semantic Naming Conventions:&lt;/strong&gt; Give clear, explicit names to your files, objects, and modules (for example, &lt;em&gt;Level 1 – System Overview&lt;/em&gt; or &lt;em&gt;Authentication Flow&lt;/em&gt;). Clean naming conventions make it easier for the AI to locate, parse, and inject context during code generation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Define Clear Boundaries in Markdown:&lt;/strong&gt; Annotate diagrams with clear text headings specifying module boundaries, supported protocol versions, database constraints, and network ports. AI models read these explicit directives to generate accurate API signatures.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>architecture</category>
      <category>llm</category>
      <category>mcp</category>
    </item>
    <item>
      <title>The Silent RAG Killer: How Noisy Document Layouts Can Burn 70,000 Tokens Before Your First Prompt</title>
      <dc:creator>Gokul Suresh</dc:creator>
      <pubDate>Tue, 07 Jul 2026 06:00:51 +0000</pubDate>
      <link>https://dev.to/gokul_suresh/the-silent-rag-killer-how-noisy-document-layouts-can-burn-70000-tokens-before-your-first-prompt-21dn</link>
      <guid>https://dev.to/gokul_suresh/the-silent-rag-killer-how-noisy-document-layouts-can-burn-70000-tokens-before-your-first-prompt-21dn</guid>
      <description>&lt;p&gt;Hey Dev Community! I originally published a version of this breakdown over on my Medium, but I wanted to share the full technical breakdown directly with the engineers here. If you're building custom AI pipelines, this one is for you.&lt;/p&gt;

&lt;p&gt;Every engineer building with Large Language Models (LLMs) eventually hits a hidden wall. You write a pristine system prompt, optimize your retrieval-augmented generation (RAG) code, pipeline your vector database, and push to staging. Everything looks brilliant.&lt;/p&gt;

&lt;p&gt;Then you open your usage dashboard and look at the actual token count.&lt;/p&gt;

&lt;p&gt;I recently hit this wall while researching how to integrate a geolocation service into our company’s core project. Like anyone trying to parse mountains of engineering guidelines, API references, and spatial data manuals, I started gathering raw documents — PDFs, Word docs, and web pages — and feeding them into Claude to fast-track my implementation research.&lt;/p&gt;

&lt;p&gt;Out of curiosity, I paused to look closely at the underlying token consumption. What I discovered was a massive wake-up call for anyone building real-world AI applications.&lt;/p&gt;

&lt;p&gt;The Math Behind Token Bloat&lt;br&gt;
When we interact with text via an LLM’s user interface, we don’t think about the invisible baggage tucked inside our documents. But behind the scenes, raw files are packed with semantic noise: XML tags inside .docx architectures, absolute coordinates and layout elements inside PDFs, CSS styling from web scrapes, and dense formatting metadata.&lt;/p&gt;

&lt;p&gt;When I checked the numbers for my unstructured research files, the breakdown was brutal:&lt;/p&gt;

&lt;p&gt;Average Per-Page Cost: ~3,000 tokens per page of raw, unstructured layout text.&lt;br&gt;
The Accumulation: A humble bundle of 20 reference pages consumed 70,000+ tokens.&lt;br&gt;
[20 Pages of Raw Document] ──► Includes layout tags, margins, XML, and styling ──► 70,000+ Tokens Ingested&lt;br&gt;
                                                                                    │&lt;br&gt;
                                                      Cost incurred BEFORE ◄────────┘&lt;br&gt;
                                                      your first question!&lt;br&gt;
This isn’t just a financial drain; it’s an application-performance killer. Dropping a massive chunk of metadata noise into an LLM’s context window forces the attention mechanism to dilute its processing power. It has to look through thousands of tokens of styling code just to find the actual paragraph it needs to answer your question. The result? Higher latency, hallucinated references, and degraded reasoning quality.&lt;/p&gt;

&lt;p&gt;Enter MarkItDown: Upstream Data Cleansing&lt;br&gt;
To fix this, I needed a solution that would clean the data layer before it reached the model. I found exactly that in a highly trending open-source tool from Microsoft: MarkItDown (which recently crossed an impressive 163,000+ stars on GitHub).&lt;/p&gt;

&lt;p&gt;Download the Medium app&lt;br&gt;
MarkItDown is a lightweight Python utility designed to solve one specific problem: take messy file formats — including PDFs, Word, Excel, PowerPoint, ZIP files, and even YouTube video transcriptions — and convert them into pure, clean Markdown.&lt;/p&gt;

&lt;p&gt;📁 Raw Files (.pdf, .docx, .xlsx, .pptx)&lt;br&gt;
              │&lt;br&gt;
              ▼&lt;br&gt;
   ⚡ [ Microsoft MarkItDown ] &lt;br&gt;
              │&lt;br&gt;
              ▼&lt;br&gt;
📝 Structured, Stripped Markdown Text (Ready for LLM)&lt;br&gt;
Why Markdown is the Ultimate AI Ingestion Format&lt;br&gt;
Token Minimalism: Markdown strips out layout structures, hidden XML trees, and presentation metadata, leaving only the essential content. It slashes your context window footprint dramatically.&lt;br&gt;
Native Model Alignment: Frontier models like Claude and GPT-4o don’t just understand Markdown — they natively output it without being asked. They were trained on vast oceans of pure Markdown code. When you pass an LLM data in its “native tongue,” its retrieval and synthesis logic perform significantly better.&lt;br&gt;
Preserved Semantics: Unlike raw text-stripping tools that smash everything into an unreadable block of text, MarkItDown keeps headings as #, lists as *, and complex Excel spreadsheets as perfectly aligned Markdown tables. The structural meaning remains completely intact.&lt;br&gt;
The Ultimate Power-Up: Model Context Protocol (MCP)&lt;br&gt;
What makes MarkItDown uniquely built for modern AI workflows is its native support for the Model Context Protocol (MCP).&lt;/p&gt;

&lt;p&gt;Using an implementation like markitdown-mcp, you don't even need to write script pipelines to handle your local files. You can plug the server straight into your Claude Desktop application configuration file:&lt;/p&gt;

&lt;p&gt;JSON&lt;/p&gt;

&lt;p&gt;{&lt;br&gt;
  "mcpServers": {&lt;br&gt;
    "markitdown": {&lt;br&gt;
      "command": "markitdown-mcp",&lt;br&gt;
      "args": []&lt;br&gt;
    }&lt;br&gt;
  }&lt;br&gt;
}&lt;br&gt;
Once configured, your AI assistant can directly call the file converter utility on demand, transforming documents on your machine into token-efficient Markdown right inside your chat session.&lt;/p&gt;

&lt;p&gt;Where Does Google’s NotebookLM Fit In?&lt;br&gt;
While mapping out this approach, another tool naturally crossed my mind: Google’s NotebookLM. It’s an incredible app, and it’s worth distinguishing when to use which.&lt;/p&gt;

&lt;p&gt;Use NotebookLM if: You need an out-of-the-box, consumer-facing research environment. It excels at auto-ingesting documents, synthesizing complex notebooks, and generating audio overviews seamlessly.&lt;br&gt;
Use MarkItDown if: You are an engineer building a custom production pipeline. If you need granular programmatic control, data pipeline automation via Python, or a local utility that fits directly into your proprietary codebase, cleaning your data upstream with MarkItDown is the professional choice.&lt;br&gt;
Takeaway for AI Developers&lt;br&gt;
Garbage in, garbage out. Half the challenge of building dependable RAG pipelines or engineering workflows isn’t selecting the flashiest model; it’s mastering your data ingestion layer.&lt;/p&gt;

&lt;p&gt;Before you drop another unoptimized PDF or Word doc into your context window, think about the 70,000 tokens you are burning on layout noise. Clean your text, leverage Markdown, and optimize upstream. Your budget — and your model’s accuracy — will thank you.&lt;/p&gt;

&lt;p&gt;Have you experimented with document pre-processing tools for LLM workflows? Let’s talk about your data ingestion strategies in the comments below!&lt;/p&gt;

&lt;p&gt;🛠️ Open Source Project: &lt;a href="https://github.com/microsoft/markitdown" rel="noopener noreferrer"&gt;https://github.com/microsoft/markitdown&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's Connect! 🚀&lt;br&gt;
I am an engineer heavily focused on optimizing AI pipelines, data ingestion frameworks, and RAG systems. If your team is building something in the Generative AI space or if you're looking for an engineer who treats token optimization as a core metric, let's chat!&lt;/p&gt;

&lt;p&gt;🔗 Connect with me on LinkedIn = &lt;a href="https://www.linkedin.com/in/gokul-dev1/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/gokul-dev1/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📁 Check out my open-source work on GitHub = &lt;a href="https://github.com/Gokulsuresh1918" rel="noopener noreferrer"&gt;https://github.com/Gokulsuresh1918&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
