<?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: Tarunya Kesharwani</title>
    <description>The latest articles on DEV Community by Tarunya Kesharwani (@tarunya).</description>
    <link>https://dev.to/tarunya</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%2F3918455%2Fac55c709-b748-46bf-b9f4-adce2a7eea64.png</url>
      <title>DEV Community: Tarunya Kesharwani</title>
      <link>https://dev.to/tarunya</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tarunya"/>
    <language>en</language>
    <item>
      <title>The Security Problems Hiding Inside ‘Normal’ Frontend Code</title>
      <dc:creator>Tarunya Kesharwani</dc:creator>
      <pubDate>Sun, 02 Aug 2026 06:20:34 +0000</pubDate>
      <link>https://dev.to/tarunya/the-security-problems-hiding-inside-normal-frontend-code-1oag</link>
      <guid>https://dev.to/tarunya/the-security-problems-hiding-inside-normal-frontend-code-1oag</guid>
      <description>&lt;p&gt;For a long time, my understanding of frontend security was basically:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Don't expose API keys.&lt;/p&gt;

&lt;p&gt;Don't do something stupid with passwords.&lt;/p&gt;

&lt;p&gt;Use HTTPS.&lt;/p&gt;

&lt;p&gt;Done :))&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Turns out...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;absolutely not XD&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;While working on production code, I started noticing something uncomfortable.&lt;/p&gt;

&lt;p&gt;A lot of security vulnerabilities don't look like security vulnerabilities.&lt;/p&gt;

&lt;p&gt;They look like completely normal code.&lt;/p&gt;

&lt;p&gt;A line displaying HTML.&lt;/p&gt;

&lt;p&gt;A hidden admin button.&lt;/p&gt;

&lt;p&gt;A form validator.&lt;/p&gt;

&lt;p&gt;A token stored in the browser.&lt;/p&gt;

&lt;p&gt;An environment variable.&lt;/p&gt;

&lt;p&gt;An API request.&lt;/p&gt;

&lt;p&gt;Nothing is flashing red.&lt;/p&gt;

&lt;p&gt;VS Code isn't screaming.&lt;/p&gt;

&lt;p&gt;The application works perfectly.&lt;/p&gt;

&lt;p&gt;And that's exactly what makes some of these problems dangerous ._.&lt;/p&gt;

&lt;p&gt;So this isn't going to be another:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Here are 10 OWASP vulnerabilities you should memorize."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I want to show you something more useful:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;how security changes the way you read ordinary frontend code.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And more importantly, for every problem we'll answer three questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Why is this actually dangerous?&lt;/li&gt;
&lt;li&gt;What should we do instead?&lt;/li&gt;
&lt;li&gt;What should you learn so you can recognize it yourself?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Because telling someone:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"YOUR APPLICATION IS VULNERABLE!!!"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and then disappearing is not particularly helpful XD&lt;/p&gt;

&lt;p&gt;Let's break some things.&lt;/p&gt;

&lt;p&gt;Preferably theoretically.&lt;/p&gt;




&lt;h1&gt;
  
  
  1. The Browser Is Not Your Trusted Environment
&lt;/h1&gt;

&lt;p&gt;This is probably the most important rule in this entire article.&lt;/p&gt;

&lt;p&gt;If code reaches someone's browser...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;they control that environment.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;They can open DevTools.&lt;/p&gt;

&lt;p&gt;Modify JavaScript.&lt;/p&gt;

&lt;p&gt;Change HTML.&lt;/p&gt;

&lt;p&gt;Modify requests.&lt;/p&gt;

&lt;p&gt;Call your API directly.&lt;/p&gt;

&lt;p&gt;Change values in browser storage.&lt;/p&gt;

&lt;p&gt;Disable your frontend validation.&lt;/p&gt;

&lt;p&gt;Send requests your UI never allows.&lt;/p&gt;

&lt;p&gt;Your beautiful Angular interface is not a security boundary :')&lt;/p&gt;

&lt;p&gt;This sounds obvious after someone says it.&lt;/p&gt;

&lt;p&gt;But it has consequences everywhere.&lt;/p&gt;

&lt;p&gt;Consider:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;showAdminPanel&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;Perfectly reasonable frontend code.&lt;/p&gt;

&lt;p&gt;But if your backend assumes:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Well... only admins can see the button."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;we have a problem.&lt;/p&gt;

&lt;p&gt;An attacker doesn't need your button.&lt;/p&gt;

&lt;p&gt;They need your endpoint.&lt;/p&gt;

&lt;p&gt;If this exists:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DELETE /api/admin/repositories/123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;they can attempt to call it directly.&lt;/p&gt;

&lt;p&gt;Your carefully hidden button is sitting there feeling extremely secure while the attacker completely ignores it XD&lt;/p&gt;

&lt;h2&gt;
  
  
  So what should you do?
&lt;/h2&gt;

&lt;p&gt;Use frontend authorization for &lt;strong&gt;user experience&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Use backend authorization for &lt;strong&gt;security&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The frontend can decide:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Should I display this action?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The backend must independently decide:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Is this authenticated user actually allowed to perform this action?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Every sensitive endpoint should verify authorization server-side.&lt;/p&gt;

&lt;h3&gt;
  
  
  Learn next
&lt;/h3&gt;

&lt;p&gt;Study:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authentication vs authorization&lt;/li&gt;
&lt;li&gt;Role-Based Access Control (RBAC)&lt;/li&gt;
&lt;li&gt;Permission-based authorization&lt;/li&gt;
&lt;li&gt;HTTP status codes &lt;code&gt;401&lt;/code&gt; vs &lt;code&gt;403&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Server-side authorization guards/middleware&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're using NestJS, specifically learn &lt;strong&gt;Guards&lt;/strong&gt; and authorization patterns.&lt;/p&gt;




&lt;h1&gt;
  
  
  2. Disabled Buttons Are Also Not Security XD
&lt;/h1&gt;

&lt;p&gt;Suppose we have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;disabled&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Delete Everything
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Attacker:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;oh no :(&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Anyway...&lt;/p&gt;

&lt;p&gt;Open DevTools.&lt;/p&gt;

&lt;p&gt;Remove &lt;code&gt;disabled&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Or skip the interface completely.&lt;/p&gt;

&lt;p&gt;Send the HTTP request manually.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg4tduozxceqiluzcz0uy.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg4tduozxceqiluzcz0uy.jpg" alt=" " width="666" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The same applies to logic like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isAdmin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&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;Again:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Good UX.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not sufficient security.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The browser belongs to the user.&lt;/p&gt;

&lt;p&gt;Anything enforced exclusively there can potentially be modified or bypassed.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rule
&lt;/h2&gt;

&lt;p&gt;Whenever you write a frontend restriction, ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What happens if someone completely ignores this frontend?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If the answer is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"They can delete the database."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;we may have discovered a slight architectural issue :')&lt;/p&gt;




&lt;h1&gt;
  
  
  3. “But The Data Came From Our API!”
&lt;/h1&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fokz869rl6cbu4sf63op7.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fokz869rl6cbu4sf63op7.png" alt=" " width="512" height="288"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This one changed how I think about data.&lt;/p&gt;

&lt;p&gt;Imagine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/profile&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bio&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;Then somewhere:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;[innerHTML]=&lt;/span&gt;&lt;span class="s"&gt;"bio"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At first glance:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The backend sent it.&lt;/p&gt;

&lt;p&gt;Therefore it's trusted.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Right?&lt;/p&gt;

&lt;p&gt;Not necessarily.&lt;/p&gt;

&lt;p&gt;Where did the backend get &lt;code&gt;bio&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;Maybe:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User
  ↓
Database
  ↓
API
  ↓
Frontend
  ↓
HTML
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The data took a lovely vacation through your entire technology stack...&lt;/p&gt;

&lt;p&gt;but nobody actually made it trustworthy XD&lt;/p&gt;

&lt;p&gt;The database storing malicious input doesn't sanitize it.&lt;/p&gt;

&lt;p&gt;JSON serialization doesn't sanitize it.&lt;/p&gt;

&lt;p&gt;HTTPS doesn't sanitize it.&lt;/p&gt;

&lt;p&gt;Your API returning it doesn't sanitize it.&lt;/p&gt;

&lt;p&gt;This leads to a security concept worth remembering:&lt;/p&gt;

&lt;h2&gt;
  
  
  Trust the provenance, not the transport.
&lt;/h2&gt;

&lt;p&gt;Ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Where did this data originally come from?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Which API returned it?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If users, third-party APIs, URL parameters, imported files, GitHub data, CMS content, or another untrusted source can influence the value, treat it accordingly.&lt;/p&gt;




&lt;h1&gt;
  
  
  4. XSS Is Much More Interesting Than &lt;code&gt;alert("hacked")&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;Most beginner explanations of Cross-Site Scripting show:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hacked&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And honestly...&lt;/p&gt;

&lt;p&gt;that makes XSS look almost adorable XD&lt;/p&gt;

&lt;p&gt;Nobody cares if an attacker can display a popup saying "hacked."&lt;/p&gt;

&lt;p&gt;The real problem is that malicious JavaScript may execute &lt;strong&gt;inside your application's origin and user context&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Depending on the application and its defenses, that can potentially allow an attacker to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read data accessible to JavaScript&lt;/li&gt;
&lt;li&gt;Manipulate the interface&lt;/li&gt;
&lt;li&gt;Make authenticated actions as the victim&lt;/li&gt;
&lt;li&gt;Read browser storage accessible to JavaScript&lt;/li&gt;
&lt;li&gt;Exfiltrate accessible information&lt;/li&gt;
&lt;li&gt;Display phishing interfaces inside your legitimate application&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Imagine logging into a trusted website...&lt;/p&gt;

&lt;p&gt;and the website itself shows you a fake:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Session expired. Please enter your password again.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Except that UI was injected by an attacker.&lt;/p&gt;

&lt;p&gt;Suddenly &lt;code&gt;alert("hacked")&lt;/code&gt; doesn't seem like a particularly useful demonstration :')&lt;/p&gt;




&lt;h1&gt;
  
  
  5. Learn to Think in Sources and Sinks
&lt;/h1&gt;

&lt;p&gt;Here's a security concept I wish frontend tutorials introduced much earlier.&lt;/p&gt;

&lt;h3&gt;
  
  
  Source
&lt;/h3&gt;

&lt;p&gt;Where potentially untrusted data enters.&lt;/p&gt;

&lt;p&gt;Examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;URL parameters
Form inputs
Third-party APIs
Database content originally supplied by users
GitHub/API responses
localStorage
postMessage
CMS content
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Sink
&lt;/h3&gt;

&lt;p&gt;Somewhere that data becomes dangerous depending on how it's used.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;[innerHTML]=&lt;/span&gt;&lt;span class="s"&gt;"content"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important question becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SOURCE
   ↓
transformations
   ↓
more transformations
   ↓
SINK
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Can an attacker control the source?&lt;/p&gt;

&lt;p&gt;If yes:&lt;/p&gt;

&lt;p&gt;What happens when their input reaches the sink?&lt;/p&gt;

&lt;p&gt;That way of thinking is far more useful than memorizing a list of dangerous functions.&lt;/p&gt;




&lt;h1&gt;
  
  
  6. Your Framework Is Probably Protecting You More Than You Realize
&lt;/h1&gt;

&lt;p&gt;Modern frameworks provide useful security defaults.&lt;/p&gt;

&lt;p&gt;For example, Angular escapes/interprets interpolated values safely in normal templates.&lt;/p&gt;

&lt;p&gt;Something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;{{ username }}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is fundamentally different from deliberately injecting arbitrary HTML.&lt;/p&gt;

&lt;p&gt;Frameworks are trying to help.&lt;/p&gt;

&lt;p&gt;Then sometimes developers do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;bypassSecurityTrustHtml&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Angular:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I don't trust this HTML.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Developer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Don't worry bro.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Angular:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;...okay ._.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;XD&lt;/p&gt;

&lt;p&gt;The name &lt;strong&gt;bypassSecurityTrustHtml&lt;/strong&gt; is practically Angular asking you to sign a waiver.&lt;/p&gt;

&lt;p&gt;There are legitimate situations where trusted HTML needs special handling.&lt;/p&gt;

&lt;p&gt;But bypassing framework security means &lt;strong&gt;you have accepted responsibility for establishing that the value is actually safe&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prevention
&lt;/h2&gt;

&lt;p&gt;Prefer normal framework rendering whenever possible.&lt;/p&gt;

&lt;p&gt;If you genuinely need user-controlled rich HTML, use a well-maintained sanitizer designed for that purpose and configure it for your threat model rather than trying to remove suspicious strings yourself.&lt;/p&gt;

&lt;p&gt;Do NOT invent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and declare victory XD&lt;/p&gt;

&lt;p&gt;Attack payloads have considerably more creativity than that.&lt;/p&gt;

&lt;h3&gt;
  
  
  Learn next
&lt;/h3&gt;

&lt;p&gt;Study:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cross-Site Scripting (XSS)&lt;/li&gt;
&lt;li&gt;DOM-based XSS&lt;/li&gt;
&lt;li&gt;Output encoding&lt;/li&gt;
&lt;li&gt;HTML sanitization&lt;/li&gt;
&lt;li&gt;Angular security model / React escaping behavior&lt;/li&gt;
&lt;li&gt;OWASP XSS Prevention Cheat Sheet&lt;/li&gt;
&lt;li&gt;DOMPurify or an equivalent maintained sanitizer when arbitrary HTML must be rendered&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  7. Frontend Validation Is Not Security Validation
&lt;/h1&gt;

&lt;p&gt;You build a beautiful Angular form:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FormControl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="nx"&gt;Validators&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;required&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Validators&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;maxLength&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&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;Fantastic.&lt;/p&gt;

&lt;p&gt;Users cannot submit names longer than 100 characters.&lt;/p&gt;

&lt;p&gt;Except...&lt;/p&gt;

&lt;p&gt;attackers are under no contractual obligation to use your Angular form XD&lt;/p&gt;

&lt;p&gt;They can directly send:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /api/users
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with whatever payload they want.&lt;/p&gt;

&lt;p&gt;Frontend validation is still important.&lt;/p&gt;

&lt;p&gt;It gives immediate feedback.&lt;/p&gt;

&lt;p&gt;Reduces accidental invalid requests.&lt;/p&gt;

&lt;p&gt;Makes forms pleasant to use.&lt;/p&gt;

&lt;p&gt;But:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Client validation improves user experience. Server validation establishes trust.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Your backend must validate the request again.&lt;/p&gt;

&lt;p&gt;Types.&lt;/p&gt;

&lt;p&gt;Lengths.&lt;/p&gt;

&lt;p&gt;Formats.&lt;/p&gt;

&lt;p&gt;Allowed values.&lt;/p&gt;

&lt;p&gt;Required properties.&lt;/p&gt;

&lt;p&gt;Unexpected properties where relevant.&lt;/p&gt;

&lt;p&gt;Business constraints.&lt;/p&gt;

&lt;p&gt;And validation should happen before untrusted data reaches sensitive operations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Learn next
&lt;/h3&gt;

&lt;p&gt;Study:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DTO validation&lt;/li&gt;
&lt;li&gt;Schema validation&lt;/li&gt;
&lt;li&gt;Input validation&lt;/li&gt;
&lt;li&gt;Allowlisting vs blocklisting&lt;/li&gt;
&lt;li&gt;NestJS &lt;code&gt;ValidationPipe&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;class-validator&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;OWASP Input Validation Cheat Sheet&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  8. Let's Talk About &lt;code&gt;localStorage&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;Ah yes.&lt;/p&gt;

&lt;p&gt;The internet's favourite security debate :')&lt;/p&gt;

&lt;p&gt;You'll often hear:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;NEVER STORE TOKENS IN LOCALSTORAGE!!!!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And then:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;COOKIES ARE SECURE!!!!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Security is rarely that simple.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;localStorage&lt;/code&gt; is accessible to JavaScript running on the same origin.&lt;/p&gt;

&lt;p&gt;Therefore, if malicious JavaScript successfully executes through an XSS vulnerability, values accessible through &lt;code&gt;localStorage&lt;/code&gt; may also become accessible to that script.&lt;/p&gt;

&lt;p&gt;An &lt;code&gt;HttpOnly&lt;/code&gt; cookie, by contrast, cannot be directly read through JavaScript.&lt;/p&gt;

&lt;p&gt;That's useful protection against token theft through JavaScript.&lt;/p&gt;

&lt;p&gt;But cookies introduce considerations of their own.&lt;/p&gt;

&lt;p&gt;For authentication cookies, you need to understand things such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;HttpOnly&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Secure&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SameSite&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;CSRF&lt;/li&gt;
&lt;li&gt;Cookie scope&lt;/li&gt;
&lt;li&gt;Session expiration&lt;/li&gt;
&lt;li&gt;Session invalidation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The lesson isn't:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;localStorage bad.&lt;/p&gt;

&lt;p&gt;cookies good.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The lesson is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Understand what you're protecting against.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's threat modeling.&lt;/p&gt;

&lt;h2&gt;
  
  
  Questions worth asking
&lt;/h2&gt;

&lt;p&gt;If authentication credentials are stored here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can JavaScript access them?&lt;/li&gt;
&lt;li&gt;What happens during an XSS attack?&lt;/li&gt;
&lt;li&gt;Can another origin cause authenticated requests?&lt;/li&gt;
&lt;li&gt;How does logout invalidate the session?&lt;/li&gt;
&lt;li&gt;What happens when credentials expire?&lt;/li&gt;
&lt;li&gt;Can compromised credentials be revoked?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those questions lead to better architecture than memorizing Twitter security advice XD&lt;/p&gt;

&lt;h3&gt;
  
  
  Learn next
&lt;/h3&gt;

&lt;p&gt;Study:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cookie-based authentication&lt;/li&gt;
&lt;li&gt;Session authentication&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;HttpOnly&lt;/code&gt;, &lt;code&gt;Secure&lt;/code&gt;, and &lt;code&gt;SameSite&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;CSRF&lt;/li&gt;
&lt;li&gt;XSS&lt;/li&gt;
&lt;li&gt;Token rotation&lt;/li&gt;
&lt;li&gt;Session invalidation&lt;/li&gt;
&lt;li&gt;OWASP Session Management Cheat Sheet&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  9. Your &lt;code&gt;.env&lt;/code&gt; File Does Not Make Frontend Secrets Secret
&lt;/h1&gt;

&lt;p&gt;This one hurts because &lt;code&gt;.env&lt;/code&gt; feels extremely secure.&lt;/p&gt;

&lt;p&gt;Look at it.&lt;/p&gt;

&lt;p&gt;It even has a dot at the beginning.&lt;/p&gt;

&lt;p&gt;Very mysterious :0&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdxmxv7n5wy5d7phm2rte.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdxmxv7n5wy5d7phm2rte.jpg" alt=" " width="700" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Suppose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SUPER_SECRET_API_KEY=abc123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then your frontend build includes that value.&lt;/p&gt;

&lt;p&gt;Congratulations.&lt;/p&gt;

&lt;p&gt;Your secret is now...&lt;/p&gt;

&lt;p&gt;public :')&lt;/p&gt;

&lt;p&gt;If the browser needs a value to execute your application, assume the user can obtain that value.&lt;/p&gt;

&lt;p&gt;Minification doesn't change that.&lt;/p&gt;

&lt;p&gt;Obfuscation doesn't create a security boundary.&lt;/p&gt;

&lt;p&gt;Renaming:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SECRET_API_KEY
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;x7Q_a19
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;does not defeat someone determined to inspect your application XD&lt;/p&gt;

&lt;h2&gt;
  
  
  Important distinction
&lt;/h2&gt;

&lt;p&gt;Not every API key is necessarily secret.&lt;/p&gt;

&lt;p&gt;Some services intentionally provide &lt;strong&gt;publishable client keys&lt;/strong&gt; designed to exist in browser applications.&lt;/p&gt;

&lt;p&gt;The important question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What authority does possession of this value provide?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If the key grants privileged server-side access, signs trusted requests, bypasses authorization, or gives access to private infrastructure...&lt;/p&gt;

&lt;p&gt;it does not belong in frontend code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prevention
&lt;/h2&gt;

&lt;p&gt;Keep actual secrets server-side.&lt;/p&gt;

&lt;p&gt;Frontend:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Browser
   ↓
Your Backend
   ↓
Privileged External Service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The backend keeps the secret and performs authorization before accessing privileged services.&lt;/p&gt;

&lt;h3&gt;
  
  
  Learn next
&lt;/h3&gt;

&lt;p&gt;Study:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Public vs secret API keys&lt;/li&gt;
&lt;li&gt;Environment variables in frontend build systems&lt;/li&gt;
&lt;li&gt;Backend-for-Frontend patterns&lt;/li&gt;
&lt;li&gt;Secret management&lt;/li&gt;
&lt;li&gt;API key restrictions&lt;/li&gt;
&lt;li&gt;Least privilege&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And remember:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Anything shipped to the browser should be treated as observable by the user.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  10. Rate Limiting Is Not Disabling a Button for Five Seconds
&lt;/h1&gt;

&lt;p&gt;Suppose your frontend does:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;requestInProgress&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&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;Useful.&lt;/p&gt;

&lt;p&gt;But that's UI throttling.&lt;/p&gt;

&lt;p&gt;Not security rate limiting.&lt;/p&gt;

&lt;p&gt;Again...&lt;/p&gt;

&lt;p&gt;the attacker doesn't need your UI :')&lt;/p&gt;

&lt;p&gt;They can directly automate requests against the endpoint.&lt;/p&gt;

&lt;p&gt;This matters particularly for operations like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Login attempts&lt;/li&gt;
&lt;li&gt;Password resets&lt;/li&gt;
&lt;li&gt;Expensive searches&lt;/li&gt;
&lt;li&gt;Email sending&lt;/li&gt;
&lt;li&gt;File processing&lt;/li&gt;
&lt;li&gt;Administrative actions&lt;/li&gt;
&lt;li&gt;Expensive third-party API calls&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without rate limiting, one endpoint can potentially become a resource exhaustion or abuse mechanism.&lt;/p&gt;

&lt;p&gt;And authentication alone doesn't magically solve this.&lt;/p&gt;

&lt;p&gt;Authenticated accounts can be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Compromised&lt;/li&gt;
&lt;li&gt;Automated&lt;/li&gt;
&lt;li&gt;Buggy&lt;/li&gt;
&lt;li&gt;Malicious&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prevention
&lt;/h2&gt;

&lt;p&gt;Rate limiting belongs at a trusted server or infrastructure boundary.&lt;/p&gt;

&lt;p&gt;Depending on the architecture, that could mean:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Application middleware/guards&lt;/li&gt;
&lt;li&gt;API gateway&lt;/li&gt;
&lt;li&gt;Reverse proxy&lt;/li&gt;
&lt;li&gt;CDN/WAF&lt;/li&gt;
&lt;li&gt;Distributed rate limiter&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For distributed systems, you also need to think about whether counters are shared across instances.&lt;/p&gt;

&lt;h3&gt;
  
  
  Learn next
&lt;/h3&gt;

&lt;p&gt;Study:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rate limiting&lt;/li&gt;
&lt;li&gt;Token bucket&lt;/li&gt;
&lt;li&gt;Sliding-window algorithms&lt;/li&gt;
&lt;li&gt;HTTP &lt;code&gt;429 Too Many Requests&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;NestJS throttling&lt;/li&gt;
&lt;li&gt;Reverse proxies&lt;/li&gt;
&lt;li&gt;Distributed rate limiting&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  11. Third-Party JavaScript Is Part of Your Security Boundary
&lt;/h1&gt;

&lt;p&gt;Analytics.&lt;/p&gt;

&lt;p&gt;Chat widgets.&lt;/p&gt;

&lt;p&gt;A/B testing.&lt;/p&gt;

&lt;p&gt;Payment SDKs.&lt;/p&gt;

&lt;p&gt;Random npm packages.&lt;/p&gt;

&lt;p&gt;Convenient scripts copied from somewhere at 2 AM because Stack Overflow said it works XD&lt;/p&gt;

&lt;p&gt;Every script executing in your page deserves scrutiny.&lt;/p&gt;

&lt;p&gt;If third-party JavaScript executes with access to your application's origin, you're trusting more than your own code.&lt;/p&gt;

&lt;p&gt;That doesn't mean:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;NEVER USE THIRD-PARTY JAVASCRIPT.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;blockquote&gt;
&lt;p&gt;Know who you're trusting.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is also why dependency security matters.&lt;/p&gt;

&lt;p&gt;Your application can contain perfectly secure code...&lt;/p&gt;

&lt;p&gt;and still inherit vulnerabilities through its software supply chain.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prevention
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Minimize unnecessary dependencies.&lt;/li&gt;
&lt;li&gt;Keep dependencies updated deliberately.&lt;/li&gt;
&lt;li&gt;Review high-risk dependencies.&lt;/li&gt;
&lt;li&gt;Avoid casually loading remote scripts.&lt;/li&gt;
&lt;li&gt;Use integrity/security mechanisms where appropriate.&lt;/li&gt;
&lt;li&gt;Monitor dependency advisories.&lt;/li&gt;
&lt;li&gt;Remove abandoned packages when feasible.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Learn next
&lt;/h3&gt;

&lt;p&gt;Study:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Software supply-chain security&lt;/li&gt;
&lt;li&gt;Dependency auditing&lt;/li&gt;
&lt;li&gt;npm audit and its limitations&lt;/li&gt;
&lt;li&gt;Subresource Integrity (SRI)&lt;/li&gt;
&lt;li&gt;Content Security Policy&lt;/li&gt;
&lt;li&gt;Lockfiles&lt;/li&gt;
&lt;li&gt;OWASP Software Supply Chain guidance&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  12. Content Security Policy: Assume Something Eventually Goes Wrong
&lt;/h1&gt;

&lt;p&gt;Imagine you've done everything correctly.&lt;/p&gt;

&lt;p&gt;Then six months later someone introduces an XSS vulnerability.&lt;/p&gt;

&lt;p&gt;Defense-in-depth asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Can we make exploitation harder even after the first defense fails?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's where browser security mechanisms such as &lt;strong&gt;Content Security Policy (CSP)&lt;/strong&gt; become interesting.&lt;/p&gt;

&lt;p&gt;A well-designed CSP can restrict which scripts, styles, frames, and other resources the browser is allowed to execute or load.&lt;/p&gt;

&lt;p&gt;It isn't:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;CSP = true&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;XD&lt;/p&gt;

&lt;p&gt;A weak policy can provide little protection.&lt;/p&gt;

&lt;p&gt;A badly configured policy can break your application.&lt;/p&gt;

&lt;p&gt;And CSP should not replace proper output handling or sanitization.&lt;/p&gt;

&lt;p&gt;It's another layer.&lt;/p&gt;

&lt;p&gt;Other important browser-side defenses include appropriate security headers and policies around framing, MIME handling, referrers, permissions, and transport.&lt;/p&gt;

&lt;h3&gt;
  
  
  Learn next
&lt;/h3&gt;

&lt;p&gt;Study:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Content Security Policy&lt;/li&gt;
&lt;li&gt;CSP nonces and hashes&lt;/li&gt;
&lt;li&gt;Security headers&lt;/li&gt;
&lt;li&gt;Clickjacking&lt;/li&gt;
&lt;li&gt;&lt;code&gt;frame-ancestors&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;HSTS&lt;/li&gt;
&lt;li&gt;Referrer Policy&lt;/li&gt;
&lt;li&gt;Permissions Policy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;MDN and OWASP are excellent places to learn these properly.&lt;/p&gt;




&lt;h1&gt;
  
  
  So... How Do I Actually Think About Frontend Security?
&lt;/h1&gt;

&lt;p&gt;After discovering all of this, it can become tempting to look at every line like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;IS THIS A VULNERABILITY??? :0&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's not particularly productive either XD&lt;/p&gt;

&lt;p&gt;Instead, I've started using a simpler mental model.&lt;/p&gt;

&lt;h2&gt;
  
  
  Follow the data.
&lt;/h2&gt;

&lt;p&gt;Whenever important data enters the system, ask:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Where did it originate?
&lt;/h3&gt;

&lt;p&gt;User?&lt;/p&gt;

&lt;p&gt;URL?&lt;/p&gt;

&lt;p&gt;Database?&lt;/p&gt;

&lt;p&gt;GitHub?&lt;/p&gt;

&lt;p&gt;Third-party API?&lt;/p&gt;

&lt;p&gt;Browser storage?&lt;/p&gt;

&lt;p&gt;CMS?&lt;/p&gt;




&lt;h3&gt;
  
  
  2. Who controls it?
&lt;/h3&gt;

&lt;p&gt;Us?&lt;/p&gt;

&lt;p&gt;An administrator?&lt;/p&gt;

&lt;p&gt;Any authenticated user?&lt;/p&gt;

&lt;p&gt;Anyone on the internet?&lt;/p&gt;

&lt;p&gt;Another service?&lt;/p&gt;




&lt;h3&gt;
  
  
  3. Where do we start trusting it?
&lt;/h3&gt;

&lt;p&gt;Did the backend validate it?&lt;/p&gt;

&lt;p&gt;Did we verify authorization?&lt;/p&gt;

&lt;p&gt;Was HTML sanitized?&lt;/p&gt;

&lt;p&gt;Are we merely assuming it's trustworthy because it came from our own API?&lt;/p&gt;




&lt;h3&gt;
  
  
  4. Where does it go?
&lt;/h3&gt;

&lt;p&gt;HTML?&lt;/p&gt;

&lt;p&gt;Database?&lt;/p&gt;

&lt;p&gt;URL?&lt;/p&gt;

&lt;p&gt;DOM?&lt;/p&gt;

&lt;p&gt;Logs?&lt;/p&gt;

&lt;p&gt;External API?&lt;/p&gt;

&lt;p&gt;Another user?&lt;/p&gt;




&lt;h3&gt;
  
  
  5. What happens if an attacker controls it?
&lt;/h3&gt;

&lt;p&gt;This is the fun question :')&lt;/p&gt;

&lt;p&gt;Could they:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Execute JavaScript?&lt;/li&gt;
&lt;li&gt;Modify another user's data?&lt;/li&gt;
&lt;li&gt;Perform an admin operation?&lt;/li&gt;
&lt;li&gt;Leak credentials?&lt;/li&gt;
&lt;li&gt;Exhaust resources?&lt;/li&gt;
&lt;li&gt;Inject misleading content?&lt;/li&gt;
&lt;li&gt;Access something outside their permissions?&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  6. Where is the actual security boundary?
&lt;/h3&gt;

&lt;p&gt;If your answer is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The button is hidden."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;we need to talk XD&lt;/p&gt;




&lt;h1&gt;
  
  
  My Frontend Security Checklist
&lt;/h1&gt;

&lt;p&gt;When reviewing frontend-heavy applications now, these are some of the questions I'd ask.&lt;/p&gt;

&lt;h3&gt;
  
  
  Authentication &amp;amp; Authorization
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Are sensitive operations authorized on the backend?&lt;/li&gt;
&lt;li&gt;Are sessions invalidated correctly?&lt;/li&gt;
&lt;li&gt;Are credentials stored according to an explicit threat model?&lt;/li&gt;
&lt;li&gt;Are admin endpoints independently protected?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Input &amp;amp; Output
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Is untrusted input validated server-side?&lt;/li&gt;
&lt;li&gt;Is dynamic HTML actually necessary?&lt;/li&gt;
&lt;li&gt;Are framework security protections being bypassed?&lt;/li&gt;
&lt;li&gt;Is dangerous output encoded or sanitized appropriately?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Browser
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Are authentication cookies configured correctly?&lt;/li&gt;
&lt;li&gt;Is there a sensible CSP?&lt;/li&gt;
&lt;li&gt;Are sensitive values unnecessarily exposed to JavaScript?&lt;/li&gt;
&lt;li&gt;Can the application be embedded where it shouldn't be?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  API
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Are expensive/sensitive endpoints rate-limited?&lt;/li&gt;
&lt;li&gt;Does the backend assume the frontend already validated something?&lt;/li&gt;
&lt;li&gt;Can users modify IDs or parameters to access resources belonging to someone else?&lt;/li&gt;
&lt;li&gt;Are authorization checks performed against the requested resource?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Secrets
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Does any real secret reach the frontend bundle?&lt;/li&gt;
&lt;li&gt;Are external service credentials scoped to minimum required privileges?&lt;/li&gt;
&lt;li&gt;Can exposed client keys be restricted by origin, API, quota, or permissions?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Dependencies
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Do we actually need every dependency?&lt;/li&gt;
&lt;li&gt;Are critical packages maintained?&lt;/li&gt;
&lt;li&gt;Are third-party scripts necessary?&lt;/li&gt;
&lt;li&gt;Are security advisories being monitored?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You don't need to memorize every vulnerability ever discovered.&lt;/p&gt;

&lt;p&gt;You need to develop the habit of asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What assumption am I making about trust here?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  What Should a Beginner Actually Study?
&lt;/h1&gt;

&lt;p&gt;If you're reading this thinking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Cool.&lt;/p&gt;

&lt;p&gt;Everything is dangerous now.&lt;/p&gt;

&lt;p&gt;Thanks :')&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Don't randomly consume cybersecurity content for six months.&lt;/p&gt;

&lt;p&gt;Start with web security fundamentals.&lt;/p&gt;

&lt;p&gt;I'd learn roughly in this order:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. HTTP fundamentals
&lt;/h3&gt;

&lt;p&gt;Understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Requests and responses&lt;/li&gt;
&lt;li&gt;Headers&lt;/li&gt;
&lt;li&gt;Cookies&lt;/li&gt;
&lt;li&gt;Origins&lt;/li&gt;
&lt;li&gt;CORS&lt;/li&gt;
&lt;li&gt;HTTPS&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Authentication &amp;amp; authorization
&lt;/h3&gt;

&lt;p&gt;Understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sessions&lt;/li&gt;
&lt;li&gt;Cookies&lt;/li&gt;
&lt;li&gt;Tokens&lt;/li&gt;
&lt;li&gt;RBAC&lt;/li&gt;
&lt;li&gt;Server-side authorization&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. XSS
&lt;/h3&gt;

&lt;p&gt;Learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stored XSS&lt;/li&gt;
&lt;li&gt;Reflected XSS&lt;/li&gt;
&lt;li&gt;DOM-based XSS&lt;/li&gt;
&lt;li&gt;Sources and sinks&lt;/li&gt;
&lt;li&gt;Encoding vs sanitization&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. CSRF
&lt;/h3&gt;

&lt;p&gt;Especially if you're using cookie-based authentication.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Input validation
&lt;/h3&gt;

&lt;p&gt;Understand why both frontend and backend validation exist.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Browser security
&lt;/h3&gt;

&lt;p&gt;Learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Same-Origin Policy&lt;/li&gt;
&lt;li&gt;CORS&lt;/li&gt;
&lt;li&gt;CSP&lt;/li&gt;
&lt;li&gt;Secure cookies&lt;/li&gt;
&lt;li&gt;Browser storage&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  7. API security
&lt;/h3&gt;

&lt;p&gt;Learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authorization&lt;/li&gt;
&lt;li&gt;Rate limiting&lt;/li&gt;
&lt;li&gt;Object-level access control&lt;/li&gt;
&lt;li&gt;Validation&lt;/li&gt;
&lt;li&gt;Abuse prevention&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  8. OWASP
&lt;/h3&gt;

&lt;p&gt;Don't just memorize the OWASP Top 10.&lt;/p&gt;

&lt;p&gt;Use it as a map of categories you should understand.&lt;/p&gt;

&lt;p&gt;Two resources I'd keep returning to are:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OWASP Cheat Sheet Series&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cheatsheetseries.owasp.org/" rel="noopener noreferrer"&gt;https://cheatsheetseries.owasp.org/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MDN Web Security&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/Security" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/Security&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For practical exercises, PortSwigger's &lt;strong&gt;Web Security Academy&lt;/strong&gt; is also extremely useful:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://portswigger.net/web-security" rel="noopener noreferrer"&gt;https://portswigger.net/web-security&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Read something.&lt;/p&gt;

&lt;p&gt;Break something in a legal training environment.&lt;/p&gt;

&lt;p&gt;Understand why it broke.&lt;/p&gt;

&lt;p&gt;Fix it.&lt;/p&gt;

&lt;p&gt;That's much more effective than memorizing vulnerability names.&lt;/p&gt;




&lt;h1&gt;
  
  
  The Biggest Thing That Changed for Me
&lt;/h1&gt;

&lt;p&gt;A while ago, when reviewing frontend code, I'd mostly ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Does this work?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Is this clean?&lt;/p&gt;

&lt;p&gt;Is this maintainable?&lt;/p&gt;

&lt;p&gt;Is this performant?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I'm slowly learning that there's another question that needs to exist alongside all of them:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What happens if somebody intentionally uses this in a way we didn't expect?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's security thinking.&lt;/p&gt;

&lt;p&gt;A form isn't only something a user fills out.&lt;/p&gt;

&lt;p&gt;It's an input boundary.&lt;/p&gt;

&lt;p&gt;An API response isn't automatically trusted data.&lt;/p&gt;

&lt;p&gt;A hidden button isn't authorization.&lt;/p&gt;

&lt;p&gt;A disabled button isn't protection.&lt;/p&gt;

&lt;p&gt;An environment variable isn't automatically a secret.&lt;/p&gt;

&lt;p&gt;A framework security escape hatch isn't something to casually bypass.&lt;/p&gt;

&lt;p&gt;A successful request doesn't mean the request should have been allowed.&lt;/p&gt;

&lt;p&gt;And a feature working exactly as intended doesn't mean it's safe.&lt;/p&gt;

&lt;p&gt;That's probably the uncomfortable part of learning security.&lt;/p&gt;

&lt;p&gt;Your code can be:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;✓ Working&lt;/p&gt;

&lt;p&gt;✓ Clean&lt;/p&gt;

&lt;p&gt;✓ Tested&lt;/p&gt;

&lt;p&gt;✓ Fast&lt;/p&gt;

&lt;p&gt;✓ Beautiful&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and still be:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;✗ Please don't deploy this XD&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  Final Thought
&lt;/h1&gt;

&lt;p&gt;I don't think becoming better at application security means memorizing every attack payload.&lt;/p&gt;

&lt;p&gt;And I definitely don't think every frontend developer needs to become a penetration tester.&lt;/p&gt;

&lt;p&gt;But if you're building applications that handle real users, real accounts, real data, or real permissions...&lt;/p&gt;

&lt;p&gt;you need to understand &lt;strong&gt;trust&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Where it begins.&lt;/p&gt;

&lt;p&gt;Where it ends.&lt;/p&gt;

&lt;p&gt;And where you're accidentally creating it.&lt;/p&gt;

&lt;p&gt;Because many security vulnerabilities aren't created by developers writing obviously dangerous code.&lt;/p&gt;

&lt;p&gt;They're created by completely reasonable assumptions:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The frontend already checked it."&lt;/p&gt;

&lt;p&gt;"Only admins can see this button."&lt;/p&gt;

&lt;p&gt;"It came from our API."&lt;/p&gt;

&lt;p&gt;"It's inside &lt;code&gt;.env&lt;/code&gt;."&lt;/p&gt;

&lt;p&gt;"The framework handles security."&lt;/p&gt;

&lt;p&gt;"The user can't send that value."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Individually, each sentence sounds harmless.&lt;/p&gt;

&lt;p&gt;Until someone asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"...but what if that's not true?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;._.&lt;/p&gt;

&lt;p&gt;That's the question I'm trying to get better at asking.&lt;/p&gt;

&lt;p&gt;I'm still learning security.&lt;/p&gt;

&lt;p&gt;Still finding assumptions in my own code.&lt;/p&gt;

&lt;p&gt;Still reading documentation.&lt;/p&gt;

&lt;p&gt;Still discovering browser behavior that makes me go:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"WAIT... it can do WHAT?!" :0&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And probably still going to write something someday that a security engineer looks at and quietly closes their laptop XD&lt;/p&gt;

&lt;p&gt;But now, when I read frontend code, I don't only see components, requests, forms, and state.&lt;/p&gt;

&lt;p&gt;I see &lt;strong&gt;trust boundaries&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And once you start seeing those...&lt;/p&gt;

&lt;p&gt;normal frontend code starts looking very different :))&lt;/p&gt;

</description>
      <category>security</category>
      <category>googlesummerofcode</category>
      <category>frontend</category>
      <category>web</category>
    </item>
    <item>
      <title>Webhooks Aren't Enough: How We Designed Reliable GitHub Data Synchronization</title>
      <dc:creator>Tarunya Kesharwani</dc:creator>
      <pubDate>Fri, 17 Jul 2026 08:29:00 +0000</pubDate>
      <link>https://dev.to/tarunya/webhooks-arent-enough-how-we-designed-reliable-github-data-synchronization-3g2k</link>
      <guid>https://dev.to/tarunya/webhooks-arent-enough-how-we-designed-reliable-github-data-synchronization-3g2k</guid>
      <description>&lt;p&gt;When we started thinking about keeping repository data updated in WebiU, the first solution seemed pretty obvious:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;GitHub has webhooks.&lt;/p&gt;

&lt;p&gt;Repository changes.&lt;/p&gt;

&lt;p&gt;GitHub sends an event.&lt;/p&gt;

&lt;p&gt;We update our database.&lt;/p&gt;

&lt;p&gt;Done :))&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Simple.&lt;/p&gt;

&lt;p&gt;Clean.&lt;/p&gt;

&lt;p&gt;Real-time.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvt34arcg7sldyz2pk226.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvt34arcg7sldyz2pk226.png" alt="go wrong?" width="220" height="163"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What could possibly go wrong?&lt;/p&gt;

&lt;p&gt;Well...&lt;/p&gt;

&lt;p&gt;Apparently, quite a lot XD&lt;/p&gt;

&lt;p&gt;Because somewhere between:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Let's add GitHub webhooks."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Let's make sure our database actually represents what exists on GitHub."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I learned something important:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Real-time synchronization and reliable synchronization are two completely different problems.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And that realization changed how we designed the entire synchronization system behind WebiU.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Original Problem: GitHub Was Becoming Our Data Source
&lt;/h2&gt;

&lt;p&gt;WebiU started with a much simpler architecture.&lt;/p&gt;

&lt;p&gt;A lot of project information could live inside static files.&lt;/p&gt;

&lt;p&gt;That works perfectly well when your data changes occasionally.&lt;/p&gt;

&lt;p&gt;But GitHub repositories definitely don't behave like that :')&lt;/p&gt;

&lt;p&gt;Repositories are created.&lt;/p&gt;

&lt;p&gt;Repositories are renamed.&lt;/p&gt;

&lt;p&gt;Descriptions change.&lt;/p&gt;

&lt;p&gt;Topics change.&lt;/p&gt;

&lt;p&gt;Contributors join.&lt;/p&gt;

&lt;p&gt;Repositories get archived.&lt;/p&gt;

&lt;p&gt;Metadata evolves constantly.&lt;/p&gt;

&lt;p&gt;Once WebiU started moving toward becoming an Open Source Intelligence Platform, keeping that information manually synchronized stopped making sense.&lt;/p&gt;

&lt;p&gt;So we needed a system where GitHub remained the source of truth...&lt;/p&gt;

&lt;p&gt;while WebiU maintained its own persistent representation of that data.&lt;/p&gt;

&lt;p&gt;And that creates a surprisingly interesting problem:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How do you keep two systems synchronized when only one of them is actually authoritative?&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  The Obvious Solution: Just Use Webhooks
&lt;/h1&gt;

&lt;p&gt;GitHub webhooks are almost perfect for this.&lt;/p&gt;

&lt;p&gt;Something changes on GitHub.&lt;/p&gt;

&lt;p&gt;GitHub sends an HTTP request to your backend.&lt;/p&gt;

&lt;p&gt;Your backend processes the event.&lt;/p&gt;

&lt;p&gt;Your database gets updated.&lt;/p&gt;

&lt;p&gt;Instead of constantly asking GitHub:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Anything changed?"&lt;/p&gt;

&lt;p&gt;"Anything changed now?"&lt;/p&gt;

&lt;p&gt;"How about now?"&lt;/p&gt;

&lt;p&gt;"...now?" ._.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;GitHub simply tells you when something happens.&lt;/p&gt;

&lt;p&gt;This is event-driven architecture in its simplest form.&lt;/p&gt;

&lt;p&gt;And compared to repeatedly polling hundreds of repositories, it has some obvious advantages.&lt;/p&gt;

&lt;p&gt;Fewer unnecessary API requests.&lt;/p&gt;

&lt;p&gt;Lower latency.&lt;/p&gt;

&lt;p&gt;Near real-time updates.&lt;/p&gt;

&lt;p&gt;Better use of GitHub API rate limits.&lt;/p&gt;

&lt;p&gt;Everything looks great.&lt;/p&gt;

&lt;p&gt;Until you ask one slightly uncomfortable question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What happens if we miss an event?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;:0&lt;/p&gt;




&lt;h1&gt;
  
  
  Webhooks Tell You What Happened.
&lt;/h1&gt;

&lt;h2&gt;
  
  
  They Don't Prove Your Current State Is Correct.
&lt;/h2&gt;

&lt;p&gt;Imagine GitHub sends a webhook.&lt;/p&gt;

&lt;p&gt;Your server is temporarily unavailable.&lt;/p&gt;

&lt;p&gt;The request fails.&lt;/p&gt;

&lt;p&gt;Or your application receives the webhook but crashes while processing it.&lt;/p&gt;

&lt;p&gt;Or the database transaction fails.&lt;/p&gt;

&lt;p&gt;Or someone accidentally removes a webhook configuration.&lt;/p&gt;

&lt;p&gt;Or a repository existed before your webhook system was even deployed.&lt;/p&gt;

&lt;p&gt;Now GitHub knows one thing.&lt;/p&gt;

&lt;p&gt;Your database knows another.&lt;/p&gt;

&lt;p&gt;And neither system is going to magically fix that difference for you :')&lt;/p&gt;

&lt;p&gt;This is called &lt;strong&gt;data drift&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F92tqjxzy56pz320946j5.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F92tqjxzy56pz320946j5.png" alt="All if fine" width="800" height="564"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Your local representation slowly starts becoming different from the actual source of truth.&lt;/p&gt;

&lt;p&gt;And the dangerous part is that your application might continue working perfectly.&lt;/p&gt;

&lt;p&gt;No errors.&lt;/p&gt;

&lt;p&gt;No crashes.&lt;/p&gt;

&lt;p&gt;No giant red warning saying:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;HELLO. YOUR DATABASE IS WRONG NOW. XD&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It simply serves outdated information.&lt;/p&gt;

&lt;p&gt;That's much harder to notice.&lt;/p&gt;




&lt;h1&gt;
  
  
  Real-Time Does Not Mean Correct
&lt;/h1&gt;

&lt;p&gt;This was probably the biggest mental shift for me while working on synchronization.&lt;/p&gt;

&lt;p&gt;Webhooks optimize for &lt;strong&gt;freshness&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;They tell us about changes quickly.&lt;/p&gt;

&lt;p&gt;But freshness and correctness aren't the same thing.&lt;/p&gt;

&lt;p&gt;You can have a system receiving updates within milliseconds...&lt;/p&gt;

&lt;p&gt;and still have incorrect data because of one event you missed three weeks ago.&lt;/p&gt;

&lt;p&gt;That means relying entirely on webhooks creates an architectural assumption:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Every important event will always be delivered and successfully processed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's a very strong assumption.&lt;/p&gt;

&lt;p&gt;And distributed systems generally have a habit of destroying strong assumptions XD&lt;/p&gt;

&lt;p&gt;So instead of asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How do we receive updates quickly?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We started asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How do we guarantee that our system eventually returns to the correct state?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That question led us to reconciliation.&lt;/p&gt;




&lt;h1&gt;
  
  
  Enter Scheduled Reconciliation
&lt;/h1&gt;

&lt;p&gt;The idea behind reconciliation is surprisingly simple.&lt;/p&gt;

&lt;p&gt;Every once in a while, don't trust your own database.&lt;/p&gt;

&lt;p&gt;Go back to the source of truth.&lt;/p&gt;

&lt;p&gt;Compare reality with what you think reality looks like.&lt;/p&gt;

&lt;p&gt;Then repair the differences.&lt;/p&gt;

&lt;p&gt;In our case:&lt;/p&gt;

&lt;p&gt;GitHub represents the authoritative repository state.&lt;/p&gt;

&lt;p&gt;WebiU maintains a persistent local representation.&lt;/p&gt;

&lt;p&gt;So periodically, the system can fetch the actual repository state from GitHub and compare it against what exists locally.&lt;/p&gt;

&lt;p&gt;If everything matches?&lt;/p&gt;

&lt;p&gt;Great :))&lt;/p&gt;

&lt;p&gt;Move on.&lt;/p&gt;

&lt;p&gt;If something doesn't?&lt;/p&gt;

&lt;p&gt;Now we know drift has occurred.&lt;/p&gt;

&lt;p&gt;And the system can recover.&lt;/p&gt;




&lt;h1&gt;
  
  
  Webhooks + Reconciliation
&lt;/h1&gt;

&lt;p&gt;This is where the architecture started making much more sense to me.&lt;/p&gt;

&lt;p&gt;Webhooks and scheduled synchronization aren't competing approaches.&lt;/p&gt;

&lt;p&gt;They solve different problems.&lt;/p&gt;

&lt;p&gt;Webhooks give us:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fast updates&lt;/li&gt;
&lt;li&gt;Event-driven processing&lt;/li&gt;
&lt;li&gt;Fewer unnecessary API requests&lt;/li&gt;
&lt;li&gt;Near real-time synchronization&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Reconciliation gives us:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Recovery from missed events&lt;/li&gt;
&lt;li&gt;Drift detection&lt;/li&gt;
&lt;li&gt;Eventual correctness&lt;/li&gt;
&lt;li&gt;Protection against historical inconsistencies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Together, they create something much stronger.&lt;/p&gt;

&lt;p&gt;The architecture becomes roughly:&lt;/p&gt;

&lt;p&gt;GitHub changes&lt;/p&gt;

&lt;p&gt;→ Webhook event&lt;/p&gt;

&lt;p&gt;→ Backend processes event&lt;/p&gt;

&lt;p&gt;→ Database updates immediately&lt;/p&gt;

&lt;p&gt;Then, separately:&lt;/p&gt;

&lt;p&gt;Scheduled reconciliation&lt;/p&gt;

&lt;p&gt;→ Fetch authoritative GitHub state&lt;/p&gt;

&lt;p&gt;→ Compare against persisted state&lt;/p&gt;

&lt;p&gt;→ Detect differences&lt;/p&gt;

&lt;p&gt;→ Repair inconsistencies&lt;/p&gt;

&lt;p&gt;The webhook path handles the normal case.&lt;/p&gt;

&lt;p&gt;The reconciliation path handles the:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Something somewhere went wrong three days ago and nobody noticed." XD&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;case.&lt;/p&gt;

&lt;p&gt;And those cases matter more than I originally expected.&lt;/p&gt;




&lt;h1&gt;
  
  
  Idempotency Suddenly Matters
&lt;/h1&gt;

&lt;p&gt;Once you have multiple synchronization paths, another problem appears.&lt;/p&gt;

&lt;p&gt;The same repository update might arrive through a webhook...&lt;/p&gt;

&lt;p&gt;and later be discovered again during reconciliation.&lt;/p&gt;

&lt;p&gt;Should the system update everything twice?&lt;/p&gt;

&lt;p&gt;Create duplicate records?&lt;/p&gt;

&lt;p&gt;Trigger duplicate downstream work?&lt;/p&gt;

&lt;p&gt;Hopefully not :')&lt;/p&gt;

&lt;p&gt;This is where &lt;strong&gt;idempotency&lt;/strong&gt; becomes important.&lt;/p&gt;

&lt;p&gt;An operation should be safe to perform multiple times without creating incorrect results.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Synchronize repository X with GitHub.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Whether that operation runs once or five times, the final state should still represent GitHub correctly.&lt;/p&gt;

&lt;p&gt;This sounds obvious when written in one sentence.&lt;/p&gt;

&lt;p&gt;Designing your code so that it actually behaves this way is slightly less obvious XD&lt;/p&gt;

&lt;p&gt;But once synchronization systems become asynchronous, retryable, and event-driven, idempotency stops being a nice architectural word.&lt;/p&gt;

&lt;p&gt;It becomes a survival mechanism.&lt;/p&gt;




&lt;h1&gt;
  
  
  Failures Should Become State
&lt;/h1&gt;

&lt;p&gt;Another interesting lesson came from thinking about failed synchronization.&lt;/p&gt;

&lt;p&gt;The naive approach is:&lt;/p&gt;

&lt;p&gt;Synchronization fails.&lt;/p&gt;

&lt;p&gt;Log the error.&lt;/p&gt;

&lt;p&gt;Done.&lt;/p&gt;

&lt;p&gt;But logs are mostly useful to developers who already know something is wrong.&lt;/p&gt;

&lt;p&gt;What about the system itself?&lt;/p&gt;

&lt;p&gt;If a repository failed synchronization yesterday, shouldn't the application know that?&lt;/p&gt;

&lt;p&gt;Instead of treating synchronization failures as temporary console messages, we started representing synchronization state explicitly.&lt;/p&gt;

&lt;p&gt;A repository can have information about whether it is synchronized correctly.&lt;/p&gt;

&lt;p&gt;Whether synchronization failed.&lt;/p&gt;

&lt;p&gt;Why it failed.&lt;/p&gt;

&lt;p&gt;Where the latest reconciliation came from.&lt;/p&gt;

&lt;p&gt;This turns operational problems into queryable application state.&lt;/p&gt;

&lt;p&gt;And that opens the door to much better observability.&lt;/p&gt;

&lt;p&gt;Instead of searching through logs wondering:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Which repository is broken?" ._.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The system itself can answer that question.&lt;/p&gt;




&lt;h1&gt;
  
  
  The Database Became More Than Storage
&lt;/h1&gt;

&lt;p&gt;This was another shift in how I thought about persistence.&lt;/p&gt;

&lt;p&gt;Initially, it's easy to think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Database = place where data lives.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But in a synchronization-heavy system, the database also becomes a record of what the application believes about the outside world.&lt;/p&gt;

&lt;p&gt;That means metadata becomes important.&lt;/p&gt;

&lt;p&gt;When was this repository last synchronized?&lt;/p&gt;

&lt;p&gt;Was the synchronization successful?&lt;/p&gt;

&lt;p&gt;Where did this update come from?&lt;/p&gt;

&lt;p&gt;Is this repository still active?&lt;/p&gt;

&lt;p&gt;Did reconciliation detect drift?&lt;/p&gt;

&lt;p&gt;Suddenly, your persistence model isn't just representing repositories.&lt;/p&gt;

&lt;p&gt;It's representing the &lt;strong&gt;health of your relationship with the external system&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I definitely wasn't thinking about databases like that when I first started building CRUD applications xD&lt;/p&gt;




&lt;h1&gt;
  
  
  GitHub API Rate Limits Still Matter
&lt;/h1&gt;

&lt;p&gt;Of course, reconciliation introduces its own problem.&lt;/p&gt;

&lt;p&gt;Remember why we didn't want to poll GitHub constantly in the first place?&lt;/p&gt;

&lt;p&gt;Rate limits.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fft5wrbn5tmu774bben2d.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fft5wrbn5tmu774bben2d.png" alt="1err -&gt; 2err -&gt; 20err !!!" width="447" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have hundreds of repositories and periodically fetch everything from GitHub without thinking about efficiency...&lt;/p&gt;

&lt;p&gt;Congratulations.&lt;/p&gt;

&lt;p&gt;You've reinvented aggressive polling with extra steps XD&lt;/p&gt;

&lt;p&gt;So reconciliation needs to be intentional.&lt;/p&gt;

&lt;p&gt;Not every piece of data needs the same synchronization frequency.&lt;/p&gt;

&lt;p&gt;Not every repository needs to be refreshed constantly.&lt;/p&gt;

&lt;p&gt;Bulk operations can reduce unnecessary requests.&lt;/p&gt;

&lt;p&gt;Cached data can prevent repeated work.&lt;/p&gt;

&lt;p&gt;The system needs to understand which information is actually worth refreshing.&lt;/p&gt;

&lt;p&gt;This is where architecture becomes less about:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Can we build this?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and more about:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Can we build this without creating another problem somewhere else?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That question keeps appearing suspiciously often in software engineering :')&lt;/p&gt;




&lt;h1&gt;
  
  
  Synchronization Is a Consistency Problem
&lt;/h1&gt;

&lt;p&gt;Before working on this system, I mostly thought about GitHub integration as an API problem.&lt;/p&gt;

&lt;p&gt;Call endpoint.&lt;/p&gt;

&lt;p&gt;Get JSON.&lt;/p&gt;

&lt;p&gt;Save JSON.&lt;/p&gt;

&lt;p&gt;Done.&lt;/p&gt;

&lt;p&gt;But once you're maintaining persistent state, it becomes something else entirely.&lt;/p&gt;

&lt;p&gt;It's a consistency problem.&lt;/p&gt;

&lt;p&gt;You have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An external source of truth&lt;/li&gt;
&lt;li&gt;Your local representation&lt;/li&gt;
&lt;li&gt;Events arriving asynchronously&lt;/li&gt;
&lt;li&gt;Operations that can fail&lt;/li&gt;
&lt;li&gt;Network requests that can time out&lt;/li&gt;
&lt;li&gt;Rate limits&lt;/li&gt;
&lt;li&gt;Retries&lt;/li&gt;
&lt;li&gt;Historical data&lt;/li&gt;
&lt;li&gt;Multiple synchronization mechanisms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now you're not simply consuming an API.&lt;/p&gt;

&lt;p&gt;You're designing how two systems agree with each other over time.&lt;/p&gt;

&lt;p&gt;That is a much more interesting problem.&lt;/p&gt;

&lt;p&gt;And also a much better way to accidentally spend an entire evening staring at architecture diagrams :')&lt;/p&gt;




&lt;h1&gt;
  
  
  The Architecture We Ended Up With
&lt;/h1&gt;

&lt;p&gt;At a high level, the synchronization strategy became:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. PostgreSQL for persistent repository state
&lt;/h3&gt;

&lt;p&gt;WebiU keeps a local representation of repository information rather than fetching everything directly from GitHub for every request.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. GitHub webhooks for fast updates
&lt;/h3&gt;

&lt;p&gt;When important events occur, GitHub can notify the backend and allow the system to react quickly.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Scheduled reconciliation for correctness
&lt;/h3&gt;

&lt;p&gt;The system periodically compares persisted state against GitHub to detect and repair drift.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Synchronization metadata for observability
&lt;/h3&gt;

&lt;p&gt;Repositories can expose their synchronization status instead of hiding failures inside logs.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Idempotent synchronization operations
&lt;/h3&gt;

&lt;p&gt;Updates should remain safe even when the same state is processed multiple times.&lt;/p&gt;

&lt;p&gt;Together, these mechanisms create something much more resilient than:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;GitHub webhook → database update.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Because production systems need to account for what happens when the happy path isn't so happy XD&lt;/p&gt;




&lt;h1&gt;
  
  
  What I'd Do Differently Now
&lt;/h1&gt;

&lt;p&gt;One thing I'm slowly learning is that the first architecture you imagine is usually optimized for the happy path.&lt;/p&gt;

&lt;p&gt;The more you work on production systems, the more you start designing for everything surrounding that path.&lt;/p&gt;

&lt;p&gt;What happens when this fails?&lt;/p&gt;

&lt;p&gt;Can it retry?&lt;/p&gt;

&lt;p&gt;What happens if the retry runs twice?&lt;/p&gt;

&lt;p&gt;How do we detect stale data?&lt;/p&gt;

&lt;p&gt;Can the system repair itself?&lt;/p&gt;

&lt;p&gt;How do we know it's broken?&lt;/p&gt;

&lt;p&gt;What happens when the external API disappears for ten minutes?&lt;/p&gt;

&lt;p&gt;Those aren't questions I naturally asked when I was building my first React applications.&lt;/p&gt;

&lt;p&gt;Back then, my biggest architectural concern was probably:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Should this component go inside the components folder or the pages folder?" XD&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now I find myself thinking about synchronization, consistency, persistence, failure recovery, and observability.&lt;/p&gt;

&lt;p&gt;And I'm still very much learning all of it.&lt;/p&gt;

&lt;p&gt;But that's probably been one of the most interesting parts of working on WebiU through Google Summer of Code.&lt;/p&gt;

&lt;p&gt;The problems keep getting deeper.&lt;/p&gt;

&lt;p&gt;And every time I think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Okay, I understand this architecture now."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;another edge case quietly walks into the room :')&lt;/p&gt;




&lt;h1&gt;
  
  
  The Biggest Lesson
&lt;/h1&gt;

&lt;p&gt;If there's one thing I'd take away from building this system, it's this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Don't design only for how data gets updated. Design for how your system recovers when it doesn't.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Webhooks are excellent.&lt;/p&gt;

&lt;p&gt;We use them because they solve an important problem.&lt;/p&gt;

&lt;p&gt;But they aren't a complete synchronization strategy.&lt;/p&gt;

&lt;p&gt;Reliable systems need a way to question their own state.&lt;/p&gt;

&lt;p&gt;To compare it against reality.&lt;/p&gt;

&lt;p&gt;To detect when something went wrong.&lt;/p&gt;

&lt;p&gt;And ideally...&lt;/p&gt;

&lt;p&gt;to fix themselves without waiting for a developer to discover three weeks later that something has been broken the entire time XD&lt;/p&gt;

&lt;p&gt;I'm still learning.&lt;/p&gt;

&lt;p&gt;Still designing.&lt;/p&gt;

&lt;p&gt;Still finding edge cases I didn't know existed.&lt;/p&gt;

&lt;p&gt;Still occasionally looking at a simple feature and realizing it has somehow become a distributed systems problem :')&lt;/p&gt;

&lt;p&gt;But I think that's the part of software engineering I'm starting to enjoy the most.&lt;/p&gt;

&lt;p&gt;The code is one part.&lt;/p&gt;

&lt;p&gt;Understanding how the entire system behaves when things go wrong?&lt;/p&gt;

&lt;p&gt;That's where things start getting really interesting :))&lt;/p&gt;

</description>
      <category>github</category>
      <category>webhook</category>
      <category>googlesummerofcode</category>
      <category>webdev</category>
    </item>
    <item>
      <title>When a Static Website Isn’t Enough: Building an Open Source Intelligence Platform</title>
      <dc:creator>Tarunya Kesharwani</dc:creator>
      <pubDate>Thu, 09 Jul 2026 09:15:26 +0000</pubDate>
      <link>https://dev.to/tarunya/when-a-static-website-isnt-enough-building-an-open-source-intelligence-platform-5e5o</link>
      <guid>https://dev.to/tarunya/when-a-static-website-isnt-enough-building-an-open-source-intelligence-platform-5e5o</guid>
      <description>&lt;h1&gt;
  
  
  The Architecture Decisions That Turned a Static Website into an Open Source Intelligence Platform
&lt;/h1&gt;

&lt;p&gt;Open source organizations grow in a very... interesting way :)&lt;/p&gt;

&lt;p&gt;It usually starts simple.&lt;/p&gt;

&lt;p&gt;A homepage.&lt;/p&gt;

&lt;p&gt;A few project cards.&lt;/p&gt;

&lt;p&gt;Contributor information.&lt;/p&gt;

&lt;p&gt;Maybe a page for programs like Google Summer of Code.&lt;/p&gt;

&lt;p&gt;Everything feels clean.&lt;/p&gt;

&lt;p&gt;Predictable.&lt;/p&gt;

&lt;p&gt;Manageable.&lt;/p&gt;

&lt;p&gt;You look at it and think,&lt;/p&gt;

&lt;p&gt;"Yeah... this is easy. We got this XD"&lt;/p&gt;

&lt;p&gt;And honestly?&lt;/p&gt;

&lt;p&gt;At the beginning, it &lt;em&gt;is&lt;/em&gt; easy.&lt;/p&gt;

&lt;p&gt;Until one day...&lt;/p&gt;

&lt;p&gt;it just isn't anymore :')&lt;/p&gt;

&lt;p&gt;As repositories grow, contributors increase, and GitHub activity keeps changing every single day, something slowly starts breaking.&lt;/p&gt;

&lt;p&gt;Not the code.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;process&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;That was exactly the situation we walked into while working on &lt;strong&gt;WebiU 2.0&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;At first, I thought we were redesigning a website.&lt;/p&gt;

&lt;p&gt;Turns out...&lt;/p&gt;

&lt;p&gt;we were redesigning how the entire system &lt;em&gt;thinks&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fw17r3h1oyiww3tn224h7.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fw17r3h1oyiww3tn224h7.png" alt=" " width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem with Static Data
&lt;/h2&gt;

&lt;p&gt;Static websites are amazing.&lt;/p&gt;

&lt;p&gt;They're fast.&lt;/p&gt;

&lt;p&gt;Easy to deploy.&lt;/p&gt;

&lt;p&gt;Simple to reason about.&lt;/p&gt;

&lt;p&gt;Honestly, I used to love them because everything felt under control :)&lt;/p&gt;

&lt;p&gt;But open source organizations?&lt;/p&gt;

&lt;p&gt;They are &lt;em&gt;not&lt;/em&gt; static.&lt;/p&gt;

&lt;p&gt;Repositories evolve constantly.&lt;/p&gt;

&lt;p&gt;Contributors join... and sometimes disappear.&lt;/p&gt;

&lt;p&gt;Stars go up.&lt;/p&gt;

&lt;p&gt;Forks change.&lt;/p&gt;

&lt;p&gt;Issues open.&lt;/p&gt;

&lt;p&gt;Pull requests get merged.&lt;/p&gt;

&lt;p&gt;New projects suddenly appear out of nowhere.&lt;/p&gt;

&lt;p&gt;And then you realize something slightly terrifying:&lt;/p&gt;

&lt;p&gt;Every single one of those changes needs to be reflected on the website.&lt;/p&gt;

&lt;p&gt;Manually.&lt;/p&gt;

&lt;p&gt;At first, it's manageable.&lt;/p&gt;

&lt;p&gt;Then it becomes annoying.&lt;/p&gt;

&lt;p&gt;Then it becomes... impossible XD&lt;/p&gt;

&lt;p&gt;Not because people don't care.&lt;/p&gt;

&lt;p&gt;But because the system itself doesn't scale with reality.&lt;/p&gt;

&lt;p&gt;And slowly...&lt;/p&gt;

&lt;p&gt;the website stops reflecting what's actually happening.&lt;/p&gt;

&lt;p&gt;Which is probably the worst thing an open source platform can do :0&lt;/p&gt;




&lt;h2&gt;
  
  
  The Real Problem Wasn't the Frontend
&lt;/h2&gt;

&lt;p&gt;Naturally, my first instinct was:&lt;/p&gt;

&lt;p&gt;"Okay, let's improve the UI."&lt;/p&gt;

&lt;p&gt;Better layouts.&lt;/p&gt;

&lt;p&gt;Cleaner components.&lt;/p&gt;

&lt;p&gt;Filters.&lt;/p&gt;

&lt;p&gt;Search.&lt;/p&gt;

&lt;p&gt;Animations maybe? xD&lt;/p&gt;

&lt;p&gt;But something felt off.&lt;/p&gt;

&lt;p&gt;No matter how much we improved the frontend...&lt;/p&gt;

&lt;p&gt;the core problem didn't go away.&lt;/p&gt;

&lt;p&gt;That's when it hit me:&lt;/p&gt;

&lt;p&gt;This wasn't a frontend problem at all.&lt;/p&gt;

&lt;p&gt;It was a &lt;em&gt;data problem&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;And once you start asking data questions...&lt;/p&gt;

&lt;p&gt;things get serious real fast XD&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Where does the data come from?&lt;/li&gt;
&lt;li&gt;How often is it updated?&lt;/li&gt;
&lt;li&gt;How do we know it's correct?&lt;/li&gt;
&lt;li&gt;What happens if GitHub is slow?&lt;/li&gt;
&lt;li&gt;What happens if we hit API rate limits?&lt;/li&gt;
&lt;li&gt;How do we keep things fast &lt;em&gt;and&lt;/em&gt; accurate?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At that point, you're no longer thinking like a frontend developer.&lt;/p&gt;

&lt;p&gt;You're thinking like someone designing a system.&lt;/p&gt;

&lt;p&gt;And honestly...&lt;/p&gt;

&lt;p&gt;that shift was both exciting and slightly scary :')&lt;/p&gt;




&lt;h2&gt;
  
  
  Treating GitHub as a Data Source Instead of a CMS
&lt;/h2&gt;

&lt;p&gt;Originally, GitHub was basically our source of truth.&lt;/p&gt;

&lt;p&gt;But the website still relied heavily on static data.&lt;/p&gt;

&lt;p&gt;Which works...&lt;/p&gt;

&lt;p&gt;until it doesn't.&lt;/p&gt;

&lt;p&gt;When you're dealing with a few repositories, it's fine.&lt;/p&gt;

&lt;p&gt;When you're dealing with dozens...&lt;/p&gt;

&lt;p&gt;or eventually hundreds...&lt;/p&gt;

&lt;p&gt;things start getting messy real quick XD&lt;/p&gt;

&lt;p&gt;So we changed how we thought about GitHub.&lt;/p&gt;

&lt;p&gt;Instead of treating it like a place where people browse code...&lt;/p&gt;

&lt;p&gt;we started treating it like a &lt;em&gt;live data source&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;And suddenly, everything looked different.&lt;/p&gt;

&lt;p&gt;Repository metadata.&lt;/p&gt;

&lt;p&gt;Contributor information.&lt;/p&gt;

&lt;p&gt;Languages.&lt;/p&gt;

&lt;p&gt;Topics.&lt;/p&gt;

&lt;p&gt;Commit activity.&lt;/p&gt;

&lt;p&gt;Releases.&lt;/p&gt;

&lt;p&gt;Project health.&lt;/p&gt;

&lt;p&gt;All of this wasn't just "information" anymore.&lt;/p&gt;

&lt;p&gt;It became &lt;em&gt;data we could build on&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;But here's the catch...&lt;/p&gt;

&lt;p&gt;Once you think like this, your problem changes.&lt;/p&gt;

&lt;p&gt;You're no longer asking:&lt;/p&gt;

&lt;p&gt;"How do we display this?"&lt;/p&gt;

&lt;p&gt;You're asking:&lt;/p&gt;

&lt;p&gt;"How do we collect, organize, and keep this data reliable?"&lt;/p&gt;

&lt;p&gt;And yeah...&lt;/p&gt;

&lt;p&gt;that's where things start getting interesting XD&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Scalability Changes Everything
&lt;/h2&gt;

&lt;p&gt;Scaling sounds like a big word.&lt;/p&gt;

&lt;p&gt;But in reality, it just means:&lt;/p&gt;

&lt;p&gt;"Things are getting out of hand... in a good way" :)&lt;/p&gt;

&lt;p&gt;A few repositories?&lt;/p&gt;

&lt;p&gt;Easy.&lt;/p&gt;

&lt;p&gt;Hundreds?&lt;/p&gt;

&lt;p&gt;Not so easy.&lt;/p&gt;

&lt;p&gt;At first, the obvious solution was:&lt;/p&gt;

&lt;p&gt;"Just fetch everything from GitHub whenever we need it."&lt;/p&gt;

&lt;p&gt;Simple, right?&lt;/p&gt;

&lt;p&gt;Yeah...&lt;/p&gt;

&lt;p&gt;until you remember GitHub has API rate limits :')&lt;/p&gt;

&lt;p&gt;And suddenly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Requests become slower&lt;/li&gt;
&lt;li&gt;Pages take longer to load&lt;/li&gt;
&lt;li&gt;You depend entirely on an external service&lt;/li&gt;
&lt;li&gt;Performance becomes unpredictable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not exactly ideal XD&lt;/p&gt;

&lt;p&gt;That's when we realized something important:&lt;/p&gt;

&lt;p&gt;The website shouldn't be &lt;em&gt;discovering&lt;/em&gt; data every time.&lt;/p&gt;

&lt;p&gt;It should be &lt;em&gt;serving&lt;/em&gt; data.&lt;/p&gt;

&lt;p&gt;That one realization changed everything.&lt;/p&gt;




&lt;h2&gt;
  
  
  Moving Toward a Persistence Layer
&lt;/h2&gt;

&lt;p&gt;This was probably one of the biggest "wait... what?" moments for me :0&lt;/p&gt;

&lt;p&gt;Instead of fetching everything live...&lt;/p&gt;

&lt;p&gt;we store it.&lt;/p&gt;

&lt;p&gt;Yeah.&lt;/p&gt;

&lt;p&gt;A database.&lt;/p&gt;

&lt;p&gt;Sounds obvious now.&lt;/p&gt;

&lt;p&gt;But at that moment, it felt like we were crossing into a completely different level of engineering XD&lt;/p&gt;

&lt;p&gt;Once we introduced persistent storage, things started unlocking:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Historical analytics&lt;/li&gt;
&lt;li&gt;Better search&lt;/li&gt;
&lt;li&gt;Relationships between contributors and repositories&lt;/li&gt;
&lt;li&gt;Admin tools&lt;/li&gt;
&lt;li&gt;Custom metadata&lt;/li&gt;
&lt;li&gt;Caching&lt;/li&gt;
&lt;li&gt;Background jobs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And suddenly I was like...&lt;/p&gt;

&lt;p&gt;"Wait... weren't we just building a website?" :')&lt;/p&gt;

&lt;p&gt;This is where I really started understanding something important:&lt;/p&gt;

&lt;p&gt;GitHub doesn't have to be your runtime dependency.&lt;/p&gt;

&lt;p&gt;It can be one of your &lt;em&gt;data sources&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;And that shift?&lt;/p&gt;

&lt;p&gt;It changes everything.&lt;/p&gt;




&lt;h2&gt;
  
  
  Search Is More Than a Search Box
&lt;/h2&gt;

&lt;p&gt;Search sounds simple.&lt;/p&gt;

&lt;p&gt;Until you actually try to build it XD&lt;/p&gt;

&lt;p&gt;At first, I thought:&lt;/p&gt;

&lt;p&gt;"Just search by repository name. Done."&lt;/p&gt;

&lt;p&gt;Yeah... no :)&lt;/p&gt;

&lt;p&gt;Real search is way more complex.&lt;/p&gt;

&lt;p&gt;People want to search by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Language&lt;/li&gt;
&lt;li&gt;Topics&lt;/li&gt;
&lt;li&gt;Maintainers&lt;/li&gt;
&lt;li&gt;Activity&lt;/li&gt;
&lt;li&gt;Contribution opportunities&lt;/li&gt;
&lt;li&gt;Project health&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And suddenly you're not building a search box.&lt;/p&gt;

&lt;p&gt;You're building a &lt;em&gt;data system&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Good search isn't about UI.&lt;/p&gt;

&lt;p&gt;It's about how well your data is structured underneath.&lt;/p&gt;

&lt;p&gt;And honestly...&lt;/p&gt;

&lt;p&gt;this was one of those moments where I realized:&lt;/p&gt;

&lt;p&gt;Frontend is just the surface.&lt;/p&gt;

&lt;p&gt;The real magic happens underneath :)&lt;/p&gt;




&lt;h2&gt;
  
  
  Analytics Need Structure
&lt;/h2&gt;

&lt;p&gt;Another thing I underestimated...&lt;/p&gt;

&lt;p&gt;analytics don't just "appear" XD&lt;/p&gt;

&lt;p&gt;You don't magically get insights.&lt;/p&gt;

&lt;p&gt;You have to design for them.&lt;/p&gt;

&lt;p&gt;Questions like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which repositories are most active?&lt;/li&gt;
&lt;li&gt;Which contributors are working across multiple projects?&lt;/li&gt;
&lt;li&gt;Which technologies are most common?&lt;/li&gt;
&lt;li&gt;How has the organization grown over time?&lt;/li&gt;
&lt;li&gt;Which projects need more maintainers?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These sound simple.&lt;/p&gt;

&lt;p&gt;But without structured data?&lt;/p&gt;

&lt;p&gt;They're painful.&lt;/p&gt;

&lt;p&gt;With the right architecture?&lt;/p&gt;

&lt;p&gt;They're almost free :)&lt;/p&gt;

&lt;p&gt;That realization felt like unlocking a new level in engineering XD&lt;/p&gt;




&lt;h2&gt;
  
  
  Architecture Is Mostly About Trade-offs
&lt;/h2&gt;

&lt;p&gt;This is something I'm still learning every day.&lt;/p&gt;

&lt;p&gt;Every decision feels right...&lt;/p&gt;

&lt;p&gt;until it introduces new problems XD&lt;/p&gt;

&lt;p&gt;Static files?&lt;/p&gt;

&lt;p&gt;Simple.&lt;/p&gt;

&lt;p&gt;Databases?&lt;/p&gt;

&lt;p&gt;Powerful... but complex.&lt;/p&gt;

&lt;p&gt;Live API requests?&lt;/p&gt;

&lt;p&gt;Fresh data.&lt;/p&gt;

&lt;p&gt;Persistent storage?&lt;/p&gt;

&lt;p&gt;Fast... but needs synchronization.&lt;/p&gt;

&lt;p&gt;Search?&lt;/p&gt;

&lt;p&gt;Useful... but needs indexing.&lt;/p&gt;

&lt;p&gt;Caching?&lt;/p&gt;

&lt;p&gt;Fast... but cache invalidation is... yeah... let's not talk about that :')&lt;/p&gt;

&lt;p&gt;There is no perfect architecture.&lt;/p&gt;

&lt;p&gt;Only trade-offs.&lt;/p&gt;

&lt;p&gt;And honestly...&lt;/p&gt;

&lt;p&gt;engineering feels less like "finding the right answer"&lt;/p&gt;

&lt;p&gt;and more like&lt;/p&gt;

&lt;p&gt;"choosing which problems you're okay dealing with" XD&lt;/p&gt;




&lt;h2&gt;
  
  
  Looking Ahead
&lt;/h2&gt;

&lt;p&gt;WebiU is slowly becoming something much bigger than we initially imagined.&lt;/p&gt;

&lt;p&gt;It's no longer just a project showcase.&lt;/p&gt;

&lt;p&gt;It's evolving into an Open Source Intelligence Platform.&lt;/p&gt;

&lt;p&gt;A place where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Repository data&lt;/li&gt;
&lt;li&gt;Contributor insights&lt;/li&gt;
&lt;li&gt;Project discovery&lt;/li&gt;
&lt;li&gt;Analytics&lt;/li&gt;
&lt;li&gt;Admin workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;all come together.&lt;/p&gt;

&lt;p&gt;And the interesting part?&lt;/p&gt;

&lt;p&gt;This evolution isn't happening because we're adding more pages.&lt;/p&gt;

&lt;p&gt;It's happening because we're improving what's underneath.&lt;/p&gt;

&lt;p&gt;The architecture.&lt;/p&gt;

&lt;p&gt;The system.&lt;/p&gt;

&lt;p&gt;The thinking.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;When I first started working on this project, I thought I was going to improve a website.&lt;/p&gt;

&lt;p&gt;Now...&lt;/p&gt;

&lt;p&gt;I feel like I'm learning how to design systems.&lt;/p&gt;

&lt;p&gt;And honestly?&lt;/p&gt;

&lt;p&gt;I'm still figuring things out.&lt;/p&gt;

&lt;p&gt;Still reading docs.&lt;/p&gt;

&lt;p&gt;Still asking questions.&lt;/p&gt;

&lt;p&gt;Still getting confused sometimes XD&lt;/p&gt;

&lt;p&gt;But something has definitely changed.&lt;/p&gt;

&lt;p&gt;I no longer look at software as just "pages connected together."&lt;/p&gt;

&lt;p&gt;I look at it as systems.&lt;/p&gt;

&lt;p&gt;Flows.&lt;/p&gt;

&lt;p&gt;Data.&lt;/p&gt;

&lt;p&gt;Trade-offs.&lt;/p&gt;

&lt;p&gt;And yeah...&lt;/p&gt;

&lt;p&gt;that shift has been one of the coolest parts of this journey :)&lt;/p&gt;

&lt;p&gt;Still learning.&lt;/p&gt;

&lt;p&gt;Still building.&lt;/p&gt;

&lt;p&gt;Still breaking things sometimes xD&lt;/p&gt;

&lt;p&gt;But slowly...&lt;/p&gt;

&lt;p&gt;starting to think like an engineer who understands &lt;em&gt;why&lt;/em&gt; things work.&lt;/p&gt;

&lt;p&gt;And not just &lt;em&gt;how&lt;/em&gt; to build them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/TarunyaProgrammer" rel="noopener noreferrer"&gt;https://github.com/TarunyaProgrammer&lt;br&gt;
&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;LinkedIn&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://linkedin.com/in/tarunyakesharwani" rel="noopener noreferrer"&gt;https://linkedin.com/in/tarunyakesharwani&lt;br&gt;
&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Portfolio&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://tarunyaportfolio.vercel.app" rel="noopener noreferrer"&gt;https://tarunyaportfolio.vercel.app&lt;/a&gt;&lt;/p&gt;

</description>
      <category>systemdesign</category>
      <category>googlesummerofcode</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Before Writing Code, I Reviewed 104 Pull Requests</title>
      <dc:creator>Tarunya Kesharwani</dc:creator>
      <pubDate>Wed, 10 Jun 2026 21:46:35 +0000</pubDate>
      <link>https://dev.to/tarunya/before-writing-code-i-reviewed-104-pull-requests-2dgl</link>
      <guid>https://dev.to/tarunya/before-writing-code-i-reviewed-104-pull-requests-2dgl</guid>
      <description>&lt;h1&gt;
  
  
  Before Writing Code, I Reviewed 104 Pull Requests
&lt;/h1&gt;

&lt;h3&gt;
  
  
  My Community Bonding Journey as a GSoC 2026 Contributor for WebiU
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Sometimes the most important code you write during GSoC isn't written during GSoC at all.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When people think about Google Summer of Code, they usually imagine coding.&lt;/p&gt;

&lt;p&gt;Building features.&lt;/p&gt;

&lt;p&gt;Opening pull requests.&lt;/p&gt;

&lt;p&gt;Writing thousands of lines of code.&lt;/p&gt;

&lt;p&gt;Getting things merged.&lt;/p&gt;

&lt;p&gt;I thought the same.&lt;/p&gt;

&lt;p&gt;Then my GSoC journey started with something completely different.&lt;/p&gt;

&lt;p&gt;Reviewing 104 pull requests.&lt;/p&gt;

&lt;p&gt;Not writing them.&lt;/p&gt;

&lt;p&gt;Reviewing them.&lt;/p&gt;

&lt;p&gt;And honestly...&lt;/p&gt;

&lt;p&gt;I didn't expect that experience to completely change how I think about software engineering.&lt;/p&gt;




&lt;h2&gt;
  
  
  From Contributor to GSoC Contributor
&lt;/h2&gt;

&lt;p&gt;A few months ago, I was just another contributor trying to understand an unfamiliar codebase.&lt;/p&gt;

&lt;p&gt;WebiU, the project I now work on under Google Summer of Code 2026, is an open-source platform developed by C2SI to showcase repositories, contributors, projects, research work, publications, and community activity.&lt;/p&gt;

&lt;p&gt;Like most contributors, I started small.&lt;/p&gt;

&lt;p&gt;A few issues.&lt;/p&gt;

&lt;p&gt;A few pull requests.&lt;/p&gt;

&lt;p&gt;A few discussions.&lt;/p&gt;

&lt;p&gt;Then more discussions.&lt;/p&gt;

&lt;p&gt;Then architectural discussions.&lt;/p&gt;

&lt;p&gt;Then feature planning.&lt;/p&gt;

&lt;p&gt;Then roadmap discussions.&lt;/p&gt;

&lt;p&gt;And somehow...&lt;/p&gt;

&lt;p&gt;Before I realized it, I had become deeply involved in the project.&lt;/p&gt;

&lt;p&gt;By the time proposal season arrived, I wasn't proposing random ideas anymore.&lt;/p&gt;

&lt;p&gt;I was proposing solutions to problems I had already experienced firsthand.&lt;/p&gt;

&lt;p&gt;Problems like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub API rate limits&lt;/li&gt;
&lt;li&gt;Slow request-time data fetching&lt;/li&gt;
&lt;li&gt;Scalability bottlenecks&lt;/li&gt;
&lt;li&gt;Missing persistence layers&lt;/li&gt;
&lt;li&gt;Future infrastructure concerns&lt;/li&gt;
&lt;li&gt;Long-term maintainability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The proposal I eventually submitted focused on transforming WebiU from a request-driven GitHub data platform into an event-driven repository intelligence system.&lt;/p&gt;

&lt;p&gt;At that point, it sounded ambitious.&lt;/p&gt;

&lt;p&gt;What happened next was even more interesting.&lt;/p&gt;




&lt;h2&gt;
  
  
  The 104 Pull Request Audit
&lt;/h2&gt;

&lt;p&gt;During Community Bonding, one of the first major tasks wasn't coding.&lt;/p&gt;

&lt;p&gt;It was auditing pull requests.&lt;/p&gt;

&lt;p&gt;A lot of them.&lt;/p&gt;

&lt;p&gt;104 open pull requests.&lt;/p&gt;

&lt;p&gt;Damnnn.&lt;/p&gt;

&lt;p&gt;That number sounds much smaller until you actually start reviewing them.&lt;/p&gt;

&lt;p&gt;Some were active.&lt;/p&gt;

&lt;p&gt;Some were outdated.&lt;/p&gt;

&lt;p&gt;Some solved issues that no longer existed.&lt;/p&gt;

&lt;p&gt;Some duplicated each other.&lt;/p&gt;

&lt;p&gt;Some conflicted with the future direction of the project.&lt;/p&gt;

&lt;p&gt;And some were genuinely good contributions that had simply been sitting there waiting for attention.&lt;/p&gt;

&lt;p&gt;The challenge wasn't technical.&lt;/p&gt;

&lt;p&gt;The challenge was human.&lt;/p&gt;

&lt;p&gt;Every pull request represented somebody's effort.&lt;/p&gt;

&lt;p&gt;Someone had spent hours.&lt;/p&gt;

&lt;p&gt;Maybe days.&lt;/p&gt;

&lt;p&gt;Maybe weeks.&lt;/p&gt;

&lt;p&gt;Trying to contribute.&lt;/p&gt;

&lt;p&gt;Closing a pull request suddenly feels very different when you realize there's a real person on the other side of it.&lt;/p&gt;

&lt;p&gt;For the first time, I experienced open source from the maintainer's perspective instead of the contributor's.&lt;/p&gt;

&lt;p&gt;And that perspective changes everything.&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%2Fr17dl0ui162kydn83n9d.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%2Fr17dl0ui162kydn83n9d.png" alt=" " width="800" height="597"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Funny Side of Open Source
&lt;/h2&gt;

&lt;p&gt;Not every review was serious.&lt;/p&gt;

&lt;p&gt;Thankfully.&lt;/p&gt;

&lt;p&gt;Because after reading pull request number 63, your brain starts asking difficult questions like:&lt;/p&gt;

&lt;p&gt;"Why am I doing this to myself?"&lt;/p&gt;

&lt;p&gt;XD&lt;/p&gt;

&lt;p&gt;One of my favorite moments was opening a pull request discussion expecting serious implementation reasoning...&lt;/p&gt;

&lt;p&gt;...only to find random laughing reactions in the middle of a completely serious technical conversation.&lt;/p&gt;

&lt;p&gt;There we were discussing architecture decisions...&lt;/p&gt;

&lt;p&gt;And somebody was apparently having the time of their life.&lt;/p&gt;

&lt;p&gt;Those little moments remind you that behind every GitHub profile is an actual human being.&lt;/p&gt;

&lt;p&gt;Open source communities are built by people.&lt;/p&gt;

&lt;p&gt;Not repositories.&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%2F3oadurs5igt40lyb59pu.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%2F3oadurs5igt40lyb59pu.png" alt=" " width="640" height="477"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What Reviewing 104 Pull Requests Actually Teaches You
&lt;/h2&gt;

&lt;p&gt;Reviewing code teaches lessons that writing code never will.&lt;/p&gt;

&lt;p&gt;As contributors, we mostly see our own work.&lt;/p&gt;

&lt;p&gt;As reviewers, we see everybody's work.&lt;/p&gt;

&lt;p&gt;Different coding styles.&lt;/p&gt;

&lt;p&gt;Different problem-solving approaches.&lt;/p&gt;

&lt;p&gt;Different levels of experience.&lt;/p&gt;

&lt;p&gt;Different interpretations of the same issue.&lt;/p&gt;

&lt;p&gt;You start noticing patterns.&lt;/p&gt;

&lt;p&gt;You start seeing why maintainers ask for seemingly "small" changes.&lt;/p&gt;

&lt;p&gt;You begin understanding how tiny implementation details can become future technical debt.&lt;/p&gt;

&lt;p&gt;Most importantly, you start appreciating how difficult maintaining a project actually is.&lt;/p&gt;

&lt;p&gt;After reviewing that many pull requests, I became significantly more careful when creating my own.&lt;/p&gt;

&lt;p&gt;Because now I understood what reviewers see.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conversations That Changed The Project
&lt;/h2&gt;

&lt;p&gt;Once the pull request audit was largely complete, Community Bonding shifted into something else.&lt;/p&gt;

&lt;p&gt;Conversations.&lt;/p&gt;

&lt;p&gt;Lots of conversations.&lt;/p&gt;

&lt;p&gt;Google Meets.&lt;/p&gt;

&lt;p&gt;Slack threads.&lt;/p&gt;

&lt;p&gt;GitHub discussions.&lt;/p&gt;

&lt;p&gt;Private architecture reviews.&lt;/p&gt;

&lt;p&gt;Roadmap planning sessions.&lt;/p&gt;

&lt;p&gt;Shoutout to Mahendra Bhaiya and Utkarsh Bhaiya here.&lt;/p&gt;

&lt;p&gt;One thing I genuinely appreciated was how direct and practical every discussion was.&lt;/p&gt;

&lt;p&gt;Nobody cared about fancy architecture diagrams.&lt;/p&gt;

&lt;p&gt;Nobody cared about buzzwords.&lt;/p&gt;

&lt;p&gt;Nobody cared about building something that simply looked impressive.&lt;/p&gt;

&lt;p&gt;Everybody cared about one thing:&lt;/p&gt;

&lt;p&gt;Building something that would actually work.&lt;/p&gt;

&lt;p&gt;And that mindset changed how I viewed my own proposal.&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%2Fsoy6ju5v5hcxqcdfiof3.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%2Fsoy6ju5v5hcxqcdfiof3.png" alt=" " width="800" height="489"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Proposal Was Just The Beginning
&lt;/h2&gt;

&lt;p&gt;When I originally wrote my proposal, I focused heavily on architecture.&lt;/p&gt;

&lt;p&gt;Webhooks.&lt;/p&gt;

&lt;p&gt;Event-driven systems.&lt;/p&gt;

&lt;p&gt;Background workers.&lt;/p&gt;

&lt;p&gt;Caching.&lt;/p&gt;

&lt;p&gt;Repository intelligence.&lt;/p&gt;

&lt;p&gt;Persistent storage.&lt;/p&gt;

&lt;p&gt;Queue-based processing.&lt;/p&gt;

&lt;p&gt;All the fun distributed systems stuff.&lt;/p&gt;

&lt;p&gt;The proposal aimed to move WebiU away from this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Frontend
   ↓
Backend
   ↓
GitHub API
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;And toward this:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GitHub Events
      ↓
Webhook Layer
      ↓
Queue
      ↓
Workers
      ↓
Database
      ↓
Cache
      ↓
Frontend
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;At the time, it felt like the perfect plan.&lt;/p&gt;

&lt;p&gt;Then mentor discussions began.&lt;/p&gt;

&lt;p&gt;And oooh boy...&lt;/p&gt;

&lt;p&gt;The proposal started getting challenged.&lt;/p&gt;

&lt;p&gt;In a good way.&lt;/p&gt;

&lt;p&gt;The people helping select the proposal were often the same people questioning parts of it the hardest.&lt;/p&gt;

&lt;p&gt;Looking back, many of our meetings felt less like mentor meetings and more like architecture review boards.&lt;/p&gt;

&lt;p&gt;And honestly?&lt;/p&gt;

&lt;p&gt;That's exactly how it should be.&lt;/p&gt;

&lt;p&gt;Nobody cared about protecting the proposal.&lt;/p&gt;

&lt;p&gt;Everybody cared about improving the project.&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%2Fu8s7i531ddg6qagrv0vn.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%2Fu8s7i531ddg6qagrv0vn.png" alt=" " width="800" height="990"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Defining The Real P0 Priorities
&lt;/h2&gt;

&lt;p&gt;One lesson became obvious very quickly.&lt;/p&gt;

&lt;p&gt;Successful projects are not built by solving every problem.&lt;/p&gt;

&lt;p&gt;They are built by solving the right problems first.&lt;/p&gt;

&lt;p&gt;Together, we started identifying the actual P0 priorities.&lt;/p&gt;

&lt;p&gt;The things that absolutely had to be done before anything else.&lt;/p&gt;
&lt;h3&gt;
  
  
  1. Deployment Strategy
&lt;/h3&gt;

&lt;p&gt;Before building features, we needed deployment clarity.&lt;/p&gt;

&lt;p&gt;Where does the frontend live?&lt;/p&gt;

&lt;p&gt;Where does the backend live?&lt;/p&gt;

&lt;p&gt;How do we keep costs low?&lt;/p&gt;

&lt;p&gt;How do we keep maintenance manageable?&lt;/p&gt;

&lt;p&gt;Turns out deployment decisions affect architecture far more than most people realize.&lt;/p&gt;
&lt;h3&gt;
  
  
  2. Long-Term Cache Strategy
&lt;/h3&gt;

&lt;p&gt;Caching sounds simple until you have to maintain it.&lt;/p&gt;

&lt;p&gt;Then suddenly you're discussing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cache invalidation&lt;/li&gt;
&lt;li&gt;Data freshness&lt;/li&gt;
&lt;li&gt;Expiration policies&lt;/li&gt;
&lt;li&gt;GitHub API limits&lt;/li&gt;
&lt;li&gt;Future scalability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And you realize there are entire careers built around solving these problems.&lt;/p&gt;
&lt;h3&gt;
  
  
  3. GitHub API Dependency
&lt;/h3&gt;

&lt;p&gt;One of the biggest architectural concerns was reducing dependency on live GitHub API requests.&lt;/p&gt;

&lt;p&gt;Every design discussion eventually came back to the same question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How do we serve more data while making fewer GitHub requests?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That question influenced nearly every major decision.&lt;/p&gt;
&lt;h3&gt;
  
  
  4. Commitments To Project Leadership
&lt;/h3&gt;

&lt;p&gt;This was probably one of the most eye-opening discussions.&lt;/p&gt;

&lt;p&gt;Mentors don't just build features.&lt;/p&gt;

&lt;p&gt;They are accountable for outcomes.&lt;/p&gt;

&lt;p&gt;They make commitments.&lt;/p&gt;

&lt;p&gt;They manage expectations.&lt;/p&gt;

&lt;p&gt;They balance technical decisions against practical constraints.&lt;/p&gt;

&lt;p&gt;Understanding that changed how I approached every discussion moving forward.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Maintainer Access Moment
&lt;/h2&gt;

&lt;p&gt;At some point, I noticed something unusual.&lt;/p&gt;

&lt;p&gt;I wasn't only contributing anymore.&lt;/p&gt;

&lt;p&gt;I was helping review work.&lt;/p&gt;

&lt;p&gt;Helping make decisions.&lt;/p&gt;

&lt;p&gt;Helping plan execution.&lt;/p&gt;

&lt;p&gt;Helping close pull requests.&lt;/p&gt;

&lt;p&gt;Helping shape project direction.&lt;/p&gt;

&lt;p&gt;That's a level of trust I don't take lightly.&lt;/p&gt;

&lt;p&gt;Because every merge.&lt;/p&gt;

&lt;p&gt;Every review.&lt;/p&gt;

&lt;p&gt;Every approval.&lt;/p&gt;

&lt;p&gt;Every decision.&lt;/p&gt;

&lt;p&gt;Eventually affects somebody else.&lt;/p&gt;

&lt;p&gt;And that's a responsibility worth taking seriously.&lt;/p&gt;


&lt;h2&gt;
  
  
  Building The Roadmap
&lt;/h2&gt;

&lt;p&gt;Once priorities became clear, I started planning the implementation roadmap.&lt;/p&gt;

&lt;p&gt;One thing reviewing 104 pull requests taught me is this:&lt;/p&gt;

&lt;p&gt;Large pull requests are painful.&lt;/p&gt;

&lt;p&gt;Painful to review.&lt;/p&gt;

&lt;p&gt;Painful to test.&lt;/p&gt;

&lt;p&gt;Painful to merge.&lt;/p&gt;

&lt;p&gt;Painful to maintain.&lt;/p&gt;

&lt;p&gt;So instead of building everything at once, we broke the project down into focused phases.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Infrastructure Cleanup&lt;/li&gt;
&lt;li&gt;Authentication Foundation&lt;/li&gt;
&lt;li&gt;Deployment Preparation&lt;/li&gt;
&lt;li&gt;Backend Improvements&lt;/li&gt;
&lt;li&gt;Admin Features&lt;/li&gt;
&lt;li&gt;Webhook Foundations&lt;/li&gt;
&lt;li&gt;Repository Intelligence Systems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each PR would have a single responsibility.&lt;/p&gt;

&lt;p&gt;Each merge would move the project one step forward.&lt;/p&gt;

&lt;p&gt;Simple.&lt;/p&gt;

&lt;p&gt;Predictable.&lt;/p&gt;

&lt;p&gt;Reviewable.&lt;/p&gt;

&lt;p&gt;Maintainable.&lt;/p&gt;


&lt;h2&gt;
  
  
  Accountability
&lt;/h2&gt;

&lt;p&gt;One message from GSoC's Community Bonding period stuck with me.&lt;/p&gt;

&lt;p&gt;Mentors guide.&lt;/p&gt;

&lt;p&gt;Contributors execute.&lt;/p&gt;

&lt;p&gt;The responsibility ultimately belongs to the contributor.&lt;/p&gt;

&lt;p&gt;And honestly, I think that's one of the best lessons GSoC teaches.&lt;/p&gt;

&lt;p&gt;So I've been documenting everything.&lt;/p&gt;

&lt;p&gt;Meeting notes.&lt;/p&gt;

&lt;p&gt;Decisions.&lt;/p&gt;

&lt;p&gt;Roadmaps.&lt;/p&gt;

&lt;p&gt;Discussions.&lt;/p&gt;

&lt;p&gt;Trade-offs.&lt;/p&gt;

&lt;p&gt;Reasoning.&lt;/p&gt;

&lt;p&gt;Not because anyone asked me to.&lt;/p&gt;

&lt;p&gt;Because future contributors deserve context.&lt;/p&gt;

&lt;p&gt;And because six months later, nobody remembers why a decision was made unless somebody writes it down.&lt;/p&gt;


&lt;h2&gt;
  
  
  What Comes Next
&lt;/h2&gt;

&lt;p&gt;The funny thing is...&lt;/p&gt;

&lt;p&gt;The coding phase has barely started.&lt;/p&gt;

&lt;p&gt;The audits are done.&lt;/p&gt;

&lt;p&gt;The architecture discussions are done.&lt;/p&gt;

&lt;p&gt;The deployment direction is mostly finalized.&lt;/p&gt;

&lt;p&gt;The priorities are clear.&lt;/p&gt;

&lt;p&gt;Now comes the difficult part.&lt;/p&gt;

&lt;p&gt;Execution.&lt;/p&gt;

&lt;p&gt;Over the next few months, the goal is to transform WebiU into something faster, more scalable, easier to maintain, and less dependent on request-time GitHub API calls.&lt;/p&gt;

&lt;p&gt;But regardless of what gets built next, one lesson will stay with me.&lt;/p&gt;

&lt;p&gt;Open source isn't just about code.&lt;/p&gt;

&lt;p&gt;It's about responsibility.&lt;/p&gt;

&lt;p&gt;Responsibility toward contributors.&lt;/p&gt;

&lt;p&gt;Responsibility toward maintainers.&lt;/p&gt;

&lt;p&gt;Responsibility toward the people who trust your decisions.&lt;/p&gt;

&lt;p&gt;And somehow...&lt;/p&gt;

&lt;p&gt;That lesson started with reviewing 104 pull requests.&lt;/p&gt;


&lt;h1&gt;
  
  
  A Small Surprise
&lt;/h1&gt;

&lt;p&gt;Over the last few weeks, quite a few people have messaged me asking questions like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How did you write your proposal?&lt;/li&gt;
&lt;li&gt;How detailed was it?&lt;/li&gt;
&lt;li&gt;What architecture did you propose?&lt;/li&gt;
&lt;li&gt;What actually gets someone selected?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And honestly...&lt;/p&gt;

&lt;p&gt;When I was applying, I had the exact same questions.&lt;/p&gt;

&lt;p&gt;I remember spending hours searching for accepted proposals, architecture documents, timelines, and implementation plans.&lt;/p&gt;

&lt;p&gt;So instead of gatekeeping it, let's do the opposite.&lt;/p&gt;

&lt;p&gt;Here's the exact proposal that got me selected for Google Summer of Code 2026.&lt;/p&gt;

&lt;p&gt;Read it.&lt;/p&gt;

&lt;p&gt;Critique it.&lt;/p&gt;

&lt;p&gt;Learn from it.&lt;/p&gt;

&lt;p&gt;Improve upon it.&lt;/p&gt;

&lt;p&gt;Disagree with it.&lt;/p&gt;

&lt;p&gt;That's how engineering gets better.&lt;/p&gt;
&lt;h3&gt;
  
  
  Proposal
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://drive.google.com/drive/folders/1xY4t65HgWwPl6TlEChYB4cvcGIL7i2eQ?usp=sharing" rel="noopener noreferrer"&gt;https://drive.google.com/drive/folders/1xY4t65HgWwPl6TlEChYB4cvcGIL7i2eQ?usp=sharing&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Just remember:&lt;/p&gt;

&lt;p&gt;The proposal got me selected.&lt;/p&gt;

&lt;p&gt;The real work started after that.&lt;/p&gt;

&lt;p&gt;:)&lt;/p&gt;


&lt;h1&gt;
  
  
  Let's Connect
&lt;/h1&gt;

&lt;p&gt;If you're interested in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Google Summer of Code&lt;/li&gt;
&lt;li&gt;Open Source&lt;/li&gt;
&lt;li&gt;Angular&lt;/li&gt;
&lt;li&gt;NestJS&lt;/li&gt;
&lt;li&gt;System Design&lt;/li&gt;
&lt;li&gt;Distributed Systems&lt;/li&gt;
&lt;li&gt;Building in Public&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Feel free to reach out.&lt;/p&gt;
&lt;h3&gt;
  
  
  GitHub
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/TarunyaProgrammer" rel="noopener noreferrer"&gt;https://github.com/TarunyaProgrammer&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  LinkedIn
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://linkedin.com/in/tarunyakesharwani" rel="noopener noreferrer"&gt;https://linkedin.com/in/tarunyakesharwani&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Portfolio
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://tarunyaportfolio.vercel.app" rel="noopener noreferrer"&gt;https://tarunyaportfolio.vercel.app&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  DEV.to
&lt;/h3&gt;


&lt;div class="ltag__user ltag__user__id__3918455"&gt;
    &lt;a href="/tarunya" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media2.dev.to/dynamic/image/width=150,height=150,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3918455%2Fac55c709-b748-46bf-b9f4-adce2a7eea64.png" alt="tarunya image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/tarunya"&gt;Tarunya Kesharwani&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/tarunya"&gt;GSoC contributor building with Angular, NestJS &amp;amp; TypeScript. Interested in OSS, scalable systems, PR reviews, architecture, and developer tooling.&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;I'm always happy to discuss open source, review ideas, exchange feedback, or just talk about building things on the internet.&lt;/p&gt;

&lt;p&gt;And if you're contributing to WebiU...&lt;/p&gt;

&lt;p&gt;There's a decent chance I've already broken the thing you're trying to fix.&lt;/p&gt;

&lt;p&gt;XD&lt;/p&gt;

</description>
      <category>googlesummerofcode</category>
      <category>opensource</category>
      <category>softwareengineering</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Stop Watching 40-Hour Tutorials: Here's How I'd Learn MERN Today</title>
      <dc:creator>Tarunya Kesharwani</dc:creator>
      <pubDate>Thu, 04 Jun 2026 16:27:16 +0000</pubDate>
      <link>https://dev.to/tarunya/stop-watching-40-hour-tutorials-heres-how-id-learn-mern-today-42kh</link>
      <guid>https://dev.to/tarunya/stop-watching-40-hour-tutorials-heres-how-id-learn-mern-today-42kh</guid>
      <description>&lt;p&gt;Every few weeks, I see someone asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"How do I learn MERN Stack?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And almost every time, the advice looks something like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Learn HTML&lt;/li&gt;
&lt;li&gt;Learn CSS&lt;/li&gt;
&lt;li&gt;Learn JavaScript&lt;/li&gt;
&lt;li&gt;Watch a 40-hour React course&lt;/li&gt;
&lt;li&gt;Watch a 20-hour Node.js course&lt;/li&gt;
&lt;li&gt;Watch a MongoDB course&lt;/li&gt;
&lt;li&gt;Build a project&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Six months later, many people are still stuck in tutorial hell :')&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%2Fi31opr8vzv7bsjew84kn.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%2Fi31opr8vzv7bsjew84kn.png" alt=" " width="800" height="848"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If I had to learn MERN again from absolute zero, I would do things very differently.&lt;/p&gt;

&lt;p&gt;Not because tutorials are bad.&lt;/p&gt;

&lt;p&gt;But because most people spend far too much time watching and far too little time building xD&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%2F8r99ilibqhfg3h2plqi5.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%2F8r99ilibqhfg3h2plqi5.png" alt=" " width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Finish JavaScript Basics First
&lt;/h2&gt;

&lt;p&gt;Before touching React, Express, MongoDB, or anything else...&lt;/p&gt;

&lt;p&gt;Make sure you understand JavaScript properly.&lt;/p&gt;

&lt;p&gt;If JavaScript feels confusing, React will feel even worse ._.&lt;/p&gt;

&lt;p&gt;Do not rush this step.&lt;/p&gt;

&lt;p&gt;Seriously.&lt;/p&gt;

&lt;p&gt;You'll thank yourself later :))&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2: Learn Basic Git &amp;amp; GitHub
&lt;/h2&gt;

&lt;p&gt;You do NOT need to become a Git wizard.&lt;/p&gt;

&lt;p&gt;Just learn the basics.&lt;/p&gt;

&lt;p&gt;Most beginners think they need to master Git before writing code.&lt;/p&gt;

&lt;p&gt;You don't.&lt;/p&gt;

&lt;p&gt;Learn enough to avoid accidentally deleting your work XD&lt;/p&gt;

&lt;p&gt;The advanced stuff can come later.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3: React — Don't Overdo Tutorials
&lt;/h2&gt;

&lt;p&gt;This is where many people lose months T_T&lt;/p&gt;

&lt;p&gt;If you want a deep, hands-on understanding of React, then watch the freeCodeCamp course.&lt;/p&gt;

&lt;p&gt;But here's the thing:&lt;/p&gt;

&lt;p&gt;You do NOT have to finish an 11-hour course before building.&lt;/p&gt;

&lt;p&gt;A lot of people spend weeks collecting React tutorials...&lt;/p&gt;

&lt;p&gt;and somehow never build a React project :')&lt;/p&gt;

&lt;p&gt;That's the trap.&lt;/p&gt;

&lt;p&gt;Watch.&lt;/p&gt;

&lt;p&gt;Build.&lt;/p&gt;

&lt;p&gt;Get stuck.&lt;/p&gt;

&lt;p&gt;Repeat.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4: Build React Projects
&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%2Fksv44rlauvjyisyeqiup.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%2Fksv44rlauvjyisyeqiup.png" alt=" " width="750" height="442"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The goal isn't to make them perfect.&lt;/p&gt;

&lt;p&gt;The goal is to get stuck.&lt;/p&gt;

&lt;p&gt;Because getting stuck is where the real learning starts.&lt;/p&gt;

&lt;p&gt;Nobody remembers the tutorial they watched.&lt;/p&gt;

&lt;p&gt;Everybody remembers the bug that ruined their entire Saturday XD&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 5: Node.js - Don't Spend Weeks Memorizing Modules
&lt;/h2&gt;

&lt;p&gt;This might sound controversial.&lt;/p&gt;

&lt;p&gt;But don't spend weeks trying to memorize Node.js APIs.&lt;/p&gt;

&lt;p&gt;Nobody remembers every method from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fs&lt;/li&gt;
&lt;li&gt;path&lt;/li&gt;
&lt;li&gt;stream&lt;/li&gt;
&lt;li&gt;crypto&lt;/li&gt;
&lt;li&gt;os&lt;/li&gt;
&lt;/ul&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%2Fwckka7ce36xpg5lohfyl.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%2Fwckka7ce36xpg5lohfyl.png" alt=" " width="800" height="542"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And if someone claims they do...&lt;/p&gt;

&lt;p&gt;they're probably lying :))&lt;/p&gt;

&lt;p&gt;Most developers check docs constantly.&lt;/p&gt;

&lt;p&gt;I still do.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 6: Learn Express
&lt;/h2&gt;

&lt;p&gt;This is where backend development starts becoming fun :D&lt;/p&gt;

&lt;p&gt;Routes start talking to databases.&lt;/p&gt;

&lt;p&gt;APIs start returning actual data.&lt;/p&gt;

&lt;p&gt;Frontend and backend finally become friends instead of strangers XD&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 7: Learn Axios
&lt;/h2&gt;

&lt;p&gt;A surprisingly important skill.&lt;/p&gt;

&lt;p&gt;This is usually the moment where people go:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"WAIT... my frontend can actually talk to my backend?!"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And suddenly things start feeling like real software :')&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 8: Learn Testing
&lt;/h2&gt;

&lt;p&gt;Most tutorials completely skip testing.&lt;/p&gt;

&lt;p&gt;Then people join a real project and see hundreds of test files.&lt;/p&gt;

&lt;p&gt;Their reaction is usually something like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What fresh hell is this?" XD&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Learn the basics.&lt;/p&gt;

&lt;p&gt;Future you will be grateful.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 9: MongoDB — Learn the 20% That Gives 80% Results
&lt;/h2&gt;

&lt;p&gt;Many beginners overcomplicate MongoDB.&lt;/p&gt;

&lt;p&gt;Honestly?&lt;/p&gt;

&lt;p&gt;Just learn CRUD.&lt;/p&gt;

&lt;p&gt;No, seriously.&lt;/p&gt;

&lt;p&gt;Just CRUD.&lt;/p&gt;

&lt;p&gt;Create.&lt;/p&gt;

&lt;p&gt;Read.&lt;/p&gt;

&lt;p&gt;Update.&lt;/p&gt;

&lt;p&gt;Delete.&lt;/p&gt;

&lt;p&gt;That's enough to build a shocking number of projects :))&lt;/p&gt;

&lt;p&gt;Don't spend three weeks studying database theory before writing your first query.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 10: Build a Full MERN Project
&lt;/h2&gt;

&lt;p&gt;Now combine everything.&lt;/p&gt;

&lt;p&gt;React + Express + MongoDB.&lt;/p&gt;

&lt;p&gt;At this stage you'll discover what you actually don't know.&lt;/p&gt;

&lt;p&gt;And trust me...&lt;/p&gt;

&lt;p&gt;that list will be longer than expected XD&lt;/p&gt;

&lt;p&gt;Which is completely normal.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 11: Join Open Source and Get Scared Like Crazy
&lt;/h2&gt;

&lt;p&gt;Seriously.&lt;/p&gt;

&lt;p&gt;This was one of the biggest learning accelerators for me.&lt;/p&gt;

&lt;p&gt;Find an organization.&lt;/p&gt;

&lt;p&gt;Clone their repository.&lt;/p&gt;

&lt;p&gt;Run the project.&lt;/p&gt;

&lt;p&gt;Watch it fail.&lt;/p&gt;

&lt;p&gt;Read the README.&lt;/p&gt;

&lt;p&gt;Miss a step.&lt;/p&gt;

&lt;p&gt;Watch it fail again.&lt;/p&gt;

&lt;p&gt;See 500 folders.&lt;/p&gt;

&lt;p&gt;See 20,000 lines of code.&lt;/p&gt;

&lt;p&gt;Question your life choices.&lt;/p&gt;

&lt;p&gt;Question your career choices.&lt;/p&gt;

&lt;p&gt;Question reality itself.&lt;/p&gt;

&lt;p&gt;Then slowly figure things out :')&lt;/p&gt;

&lt;p&gt;That's where the real growth starts.&lt;/p&gt;

&lt;p&gt;Not in tutorials.&lt;/p&gt;

&lt;p&gt;Not in courses.&lt;/p&gt;

&lt;p&gt;Not in roadmap videos.&lt;/p&gt;

&lt;p&gt;In confusion XD&lt;/p&gt;

&lt;p&gt;Lots and lots of confusion.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/c2siorg/Webiu/issues?q=is%3Aissue%20state%3Aclosed%20author%3ATarunyaProgrammer" rel="noopener noreferrer"&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%2Fonb5z4qyon44ogxevqo4.png" alt="Open Source Contributions" width="800" height="520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Click the image to explore some of the issues I've worked on in open source :))&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Biggest Mistake Beginners Make
&lt;/h2&gt;

&lt;p&gt;They keep preparing.&lt;/p&gt;

&lt;p&gt;Another course.&lt;/p&gt;

&lt;p&gt;Another tutorial.&lt;/p&gt;

&lt;p&gt;Another roadmap.&lt;/p&gt;

&lt;p&gt;Another "complete guide."&lt;/p&gt;

&lt;p&gt;Another YouTube playlist.&lt;/p&gt;

&lt;p&gt;Another productivity system.&lt;/p&gt;

&lt;p&gt;Another Notion page.&lt;/p&gt;

&lt;p&gt;Another bookmark folder.&lt;/p&gt;

&lt;p&gt;At some point you have to stop preparing and actually build something ¯&lt;em&gt;(ツ)&lt;/em&gt;/¯&lt;/p&gt;

&lt;p&gt;You won't feel ready.&lt;/p&gt;

&lt;p&gt;Build anyway.&lt;/p&gt;







&lt;h2&gt;
  
  
  Resources I'd Actually Recommend
&lt;/h2&gt;

&lt;p&gt;Instead of collecting hundreds of bookmarks, I'd focus on a handful of high-quality resources and repeatedly use them while building projects.&lt;/p&gt;

&lt;h3&gt;
  
  
  JavaScript
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;SuperSimpleDev JavaScript Course&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=EerdGm-ehJQ" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=EerdGm-ehJQ&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;MDN JavaScript Guide&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Git &amp;amp; GitHub
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Git &amp;amp; GitHub Crash Course&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=SWYqp7iY_Tc" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=SWYqp7iY_Tc&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  React
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;React Course (freeCodeCamp)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=bMknfKXIFA8" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=bMknfKXIFA8&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;React Official Documentation&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://react.dev/learn" rel="noopener noreferrer"&gt;https://react.dev/learn&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Node.js
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Node.js Learn&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://nodejs.org/learn" rel="noopener noreferrer"&gt;https://nodejs.org/learn&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Node.js Documentation&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://nodejs.org/docs/latest/api/" rel="noopener noreferrer"&gt;https://nodejs.org/docs/latest/api/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Express.js
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Express Documentation&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://expressjs.com/" rel="noopener noreferrer"&gt;https://expressjs.com/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Axios
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Axios Documentation&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://axios-http.com/docs/intro" rel="noopener noreferrer"&gt;https://axios-http.com/docs/intro&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  MongoDB
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;MongoDB Documentation&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.mongodb.com/docs/" rel="noopener noreferrer"&gt;https://www.mongodb.com/docs/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;MongoDB University&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://learn.mongodb.com/" rel="noopener noreferrer"&gt;https://learn.mongodb.com/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Testing
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Jest&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://jestjs.io/" rel="noopener noreferrer"&gt;https://jestjs.io/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Jasmine&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://jasmine.github.io/" rel="noopener noreferrer"&gt;https://jasmine.github.io/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Karma&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://karma-runner.github.io/" rel="noopener noreferrer"&gt;https://karma-runner.github.io/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Final Advice
&lt;/h2&gt;

&lt;p&gt;If I could give only one piece of advice:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Stop optimizing your learning roadmap and start building.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Most developers don't have a knowledge problem.&lt;/p&gt;

&lt;p&gt;They have an execution problem.&lt;/p&gt;

&lt;p&gt;Build projects.&lt;/p&gt;

&lt;p&gt;Join open source.&lt;/p&gt;

&lt;p&gt;Get stuck.&lt;/p&gt;

&lt;p&gt;Figure things out.&lt;/p&gt;

&lt;p&gt;That's where the real learning happens.&lt;/p&gt;




&lt;h2&gt;
  
  
  Let’s Connect
&lt;/h2&gt;

&lt;p&gt;If you're also learning, building, or exploring software engineering beyond tutorials, feel free to connect.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LinkedIn: &lt;a href="https://www.linkedin.com/in/tarunyakesharwani/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/tarunyakesharwani/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;X/Twitter: &lt;a href="https://x.com/TarunyaKesh" rel="noopener noreferrer"&gt;https://x.com/TarunyaKesh&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/TarunyaProgrammer" rel="noopener noreferrer"&gt;https://github.com/TarunyaProgrammer&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I regularly write about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open Source&lt;/li&gt;
&lt;li&gt;GSoC&lt;/li&gt;
&lt;li&gt;Angular&lt;/li&gt;
&lt;li&gt;React&lt;/li&gt;
&lt;li&gt;NestJS&lt;/li&gt;
&lt;li&gt;TypeScript&lt;/li&gt;
&lt;li&gt;Backend Engineering&lt;/li&gt;
&lt;li&gt;Software Architecture&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Still learning.&lt;/p&gt;

&lt;p&gt;Still breaking things.&lt;/p&gt;

&lt;p&gt;Still Googling error messages.&lt;/p&gt;

&lt;p&gt;Still reading documentation.&lt;/p&gt;

&lt;p&gt;Still wondering why the code worked yesterday but not today XD&lt;/p&gt;

&lt;p&gt;And still convinced that building beats watching :))&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>javascript</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Open Source Changed How I Think About Software Engineering</title>
      <dc:creator>Tarunya Kesharwani</dc:creator>
      <pubDate>Thu, 07 May 2026 20:33:49 +0000</pubDate>
      <link>https://dev.to/tarunya/open-source-changed-how-i-think-about-software-engineering-1ig9</link>
      <guid>https://dev.to/tarunya/open-source-changed-how-i-think-about-software-engineering-1ig9</guid>
      <description>&lt;p&gt;A few months ago, I thought software engineering was mostly about building features that worked.&lt;/p&gt;

&lt;p&gt;If the app ran, the API responded, and the UI looked decent — I considered the job done.&lt;/p&gt;

&lt;p&gt;Then I started contributing to open source.&lt;/p&gt;

&lt;p&gt;And honestly, it completely changed the way I look at software development.&lt;/p&gt;

&lt;p&gt;Suddenly, I realized how much tutorials usually skip.&lt;/p&gt;

&lt;p&gt;Not just coding.&lt;/p&gt;

&lt;p&gt;But things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;understanding someone else’s code,&lt;/li&gt;
&lt;li&gt;writing maintainable features,&lt;/li&gt;
&lt;li&gt;reviewing pull requests,&lt;/li&gt;
&lt;li&gt;handling feedback,&lt;/li&gt;
&lt;li&gt;debugging strange edge cases,&lt;/li&gt;
&lt;li&gt;and building software with other people.&lt;/li&gt;
&lt;/ul&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%2Fimages.unsplash.com%2Fphoto-1552308995-2baac1ad5490%3Fq%3D80%26w%3D2670%26auto%3Dformat%26fit%3Dcrop%26ixlib%3Drb-4.1.0%26ixid%3DM3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%253D%253D" 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%2Fimages.unsplash.com%2Fphoto-1552308995-2baac1ad5490%3Fq%3D80%26w%3D2670%26auto%3Dformat%26fit%3Dcrop%26ixlib%3Drb-4.1.0%26ixid%3DM3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%253D%253D" alt="My Workspace / Setup" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  “Working” Code Isn’t Always Good Code
&lt;/h2&gt;

&lt;p&gt;One of the biggest mindset shifts for me was realizing that real engineering is full of tradeoffs.&lt;/p&gt;

&lt;p&gt;Earlier, I used to think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“If it works, it’s done.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now I catch myself thinking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Will this still make sense 6 months later?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Things I barely paid attention to before suddenly started becoming important:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;readability&lt;/li&gt;
&lt;li&gt;architecture&lt;/li&gt;
&lt;li&gt;API design&lt;/li&gt;
&lt;li&gt;state management&lt;/li&gt;
&lt;li&gt;scalability&lt;/li&gt;
&lt;li&gt;maintainability&lt;/li&gt;
&lt;li&gt;collaboration&lt;/li&gt;
&lt;li&gt;PR review quality&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And the more I learned, the more I realized software engineering is much bigger than just writing code.&lt;/p&gt;




&lt;h2&gt;
  
  
  Open Source Taught Me More Than Tutorials
&lt;/h2&gt;

&lt;p&gt;Reading other people’s code teaches you things tutorials usually can’t.&lt;/p&gt;

&lt;p&gt;You start noticing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;why naming matters,&lt;/li&gt;
&lt;li&gt;why maintainers reject “working” code,&lt;/li&gt;
&lt;li&gt;why folder structures matter,&lt;/li&gt;
&lt;li&gt;and why small engineering decisions become important at scale.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even a small PR review comment can sometimes teach more than an entire tutorial video.&lt;/p&gt;

&lt;p&gt;That honestly surprised me.&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%2Frkyjsyf5ms4rdkzvw20o.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%2Frkyjsyf5ms4rdkzvw20o.png" alt="GitHub Contributions" width="800" height="465"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What I’m Learning Right Now
&lt;/h2&gt;

&lt;p&gt;Currently, I’m exploring:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Angular&lt;/li&gt;
&lt;li&gt;React&lt;/li&gt;
&lt;li&gt;NestJS&lt;/li&gt;
&lt;li&gt;TypeScript&lt;/li&gt;
&lt;li&gt;RxJS&lt;/li&gt;
&lt;li&gt;Redis&lt;/li&gt;
&lt;li&gt;backend systems&lt;/li&gt;
&lt;li&gt;system design&lt;/li&gt;
&lt;li&gt;OSS workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Recently, being selected as a GSoC contributor pushed me even deeper into understanding how collaborative software development actually works in real projects.&lt;/p&gt;

&lt;p&gt;And I still feel like I’m only scratching the surface.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I’ll Write About Here
&lt;/h2&gt;

&lt;p&gt;I want this blog to become a place where I document:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;lessons from open source,&lt;/li&gt;
&lt;li&gt;frontend/backend engineering,&lt;/li&gt;
&lt;li&gt;debugging experiences,&lt;/li&gt;
&lt;li&gt;architecture ideas,&lt;/li&gt;
&lt;li&gt;developer tooling,&lt;/li&gt;
&lt;li&gt;PR review insights,&lt;/li&gt;
&lt;li&gt;and mistakes I make while building projects.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not as an expert.&lt;/p&gt;

&lt;p&gt;Just as someone genuinely trying to understand how real software gets built.&lt;/p&gt;




&lt;p&gt;Still learning.&lt;/p&gt;

&lt;p&gt;Still curious.&lt;/p&gt;

&lt;p&gt;Still occasionally overthinking architecture decisions.&lt;/p&gt;




&lt;h2&gt;
  
  
  Let’s Connect
&lt;/h2&gt;

&lt;p&gt;If you're also learning, building, or exploring software engineering beyond tutorials, feel free to connect.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LinkedIn: &lt;a href="https://www.linkedin.com/in/tarunyakesharwani/" rel="noopener noreferrer"&gt;TarunyaKesharwani&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;X/Twitter: &lt;a href="https://x.com/TarunyaKesh" rel="noopener noreferrer"&gt;TarunyaKesh&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/TarunyaProgrammer" rel="noopener noreferrer"&gt;TarunyaProgrammer&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>opensource</category>
      <category>architecture</category>
      <category>career</category>
      <category>systemdesign</category>
    </item>
  </channel>
</rss>
