<?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: 𝗝𝗼𝗵𝗻</title>
    <description>The latest articles on DEV Community by 𝗝𝗼𝗵𝗻 (@johnnylemonny).</description>
    <link>https://dev.to/johnnylemonny</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3868757%2F52777a3a-3f32-4bcd-8f3c-002c1983dcac.jpg</url>
      <title>DEV Community: 𝗝𝗼𝗵𝗻</title>
      <link>https://dev.to/johnnylemonny</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/johnnylemonny"/>
    <language>en</language>
    <item>
      <title>The AI Code Review Checklist I Use Before Merging Any TypeScript PR</title>
      <dc:creator>𝗝𝗼𝗵𝗻</dc:creator>
      <pubDate>Thu, 30 Apr 2026 10:40:00 +0000</pubDate>
      <link>https://dev.to/johnnylemonny/the-ai-code-review-checklist-i-use-before-merging-any-typescript-pr-fc0</link>
      <guid>https://dev.to/johnnylemonny/the-ai-code-review-checklist-i-use-before-merging-any-typescript-pr-fc0</guid>
      <description>&lt;p&gt;AI can write code quickly.&lt;/p&gt;

&lt;p&gt;That is no longer the interesting part.&lt;/p&gt;

&lt;p&gt;The interesting part is what happens &lt;strong&gt;after&lt;/strong&gt; the code is generated.&lt;/p&gt;

&lt;p&gt;Because in real projects, the bottleneck is rarely “how do we get code faster?”&lt;br&gt;
It is usually:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is this correct?&lt;/li&gt;
&lt;li&gt;Does it match the architecture?&lt;/li&gt;
&lt;li&gt;Does it handle edge cases?&lt;/li&gt;
&lt;li&gt;Is it safe to merge?&lt;/li&gt;
&lt;li&gt;Can someone else maintain it next month?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is why I stopped treating AI output like finished code.&lt;/p&gt;

&lt;p&gt;Now I treat it like a draft that needs a reliable review system.&lt;/p&gt;

&lt;p&gt;This is the checklist I use before I merge any AI-generated TypeScript PR.&lt;/p&gt;

&lt;p&gt;Not a theoretical checklist.&lt;br&gt;
A practical one.&lt;/p&gt;
&lt;h2&gt;
  
  
  1. Can I explain the change in one sentence?
&lt;/h2&gt;

&lt;p&gt;Before I look at the code, I force myself to summarize the PR in one sentence.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;“This change validates uploaded image metadata before saving records to the database.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If I cannot describe the change clearly, one of two things is probably true:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the PR is doing too much&lt;/li&gt;
&lt;li&gt;the code is hiding the real intent&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI often produces code that &lt;em&gt;looks&lt;/em&gt; organized while actually mixing multiple concerns.&lt;/p&gt;

&lt;p&gt;If the purpose is fuzzy, I stop there and split the change.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. Does the code match the requested scope?
&lt;/h2&gt;

&lt;p&gt;AI loves to be helpful.&lt;/p&gt;

&lt;p&gt;Sometimes too helpful.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;rename unrelated variables&lt;/li&gt;
&lt;li&gt;refactor nearby code&lt;/li&gt;
&lt;li&gt;introduce “small improvements”&lt;/li&gt;
&lt;li&gt;create utility functions nobody asked for&lt;/li&gt;
&lt;li&gt;solve adjacent problems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That makes review harder.&lt;/p&gt;

&lt;p&gt;So one of my first checks is simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Did the model change only what needed to change?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If a PR was supposed to fix one validation bug but now touches eight files, I get suspicious immediately.&lt;/p&gt;

&lt;p&gt;A good AI-generated PR is usually narrower than you think.&lt;/p&gt;
&lt;h2&gt;
  
  
  3. Are the boundaries explicit?
&lt;/h2&gt;

&lt;p&gt;For TypeScript projects, this is one of the biggest signals of quality.&lt;/p&gt;

&lt;p&gt;I look for clear boundaries:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;input types&lt;/li&gt;
&lt;li&gt;output types&lt;/li&gt;
&lt;li&gt;domain models&lt;/li&gt;
&lt;li&gt;DTOs&lt;/li&gt;
&lt;li&gt;API contracts&lt;/li&gt;
&lt;li&gt;validation layers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI-generated code is much easier to trust when the edges are visible.&lt;/p&gt;

&lt;p&gt;Bad sign:&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;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;saveUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Better:&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="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;CreateUserInput&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;displayName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;CreateUserResult&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;displayName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;saveUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CreateUserInput&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CreateUserResult&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the AI patch adds logic without tightening the contract, I usually improve the boundary before I approve the implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Did the AI generate code, or did it generate a new abstraction?
&lt;/h2&gt;

&lt;p&gt;This matters a lot.&lt;/p&gt;

&lt;p&gt;Sometimes AI gives you useful implementation.&lt;br&gt;
Sometimes it gives you a brand new architecture you did not ask for.&lt;/p&gt;

&lt;p&gt;Watch for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;extra layers&lt;/li&gt;
&lt;li&gt;generic helpers&lt;/li&gt;
&lt;li&gt;“reusable” wrappers&lt;/li&gt;
&lt;li&gt;configuration systems&lt;/li&gt;
&lt;li&gt;class hierarchies for simple logic&lt;/li&gt;
&lt;li&gt;abstraction before repetition actually exists&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A useful question here is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Would I still create this abstraction if a human teammate had not suggested it?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If the answer is no, I remove it.&lt;/p&gt;

&lt;p&gt;AI-generated code often becomes bloated not because it is broken, but because it is too eager to generalize.&lt;/p&gt;
&lt;h2&gt;
  
  
  5. Is there a test for the thing that actually changed?
&lt;/h2&gt;

&lt;p&gt;I do not just ask, “Are there tests?”&lt;/p&gt;

&lt;p&gt;I ask:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is there a test for the exact behavior this PR claims to fix or add?&lt;/strong&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;one test for the happy path&lt;/li&gt;
&lt;li&gt;one test for the expected failure mode&lt;/li&gt;
&lt;li&gt;one test for the edge case that is easiest to miss&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the PR fixes a parsing bug, I want a parsing test.&lt;br&gt;
If it changes authorization logic, I want an authorization test.&lt;br&gt;
If it adds fallback behavior, I want a test that proves the fallback works.&lt;/p&gt;

&lt;p&gt;AI often writes tests that mirror the implementation too closely.&lt;/p&gt;

&lt;p&gt;So I look for tests that verify behavior, not just structure.&lt;/p&gt;
&lt;h2&gt;
  
  
  6. Does the code fail safely?
&lt;/h2&gt;

&lt;p&gt;A surprising amount of AI-generated code handles success better than failure.&lt;/p&gt;

&lt;p&gt;So I explicitly review:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;missing values&lt;/li&gt;
&lt;li&gt;invalid input&lt;/li&gt;
&lt;li&gt;timeouts&lt;/li&gt;
&lt;li&gt;third-party failures&lt;/li&gt;
&lt;li&gt;null and undefined cases&lt;/li&gt;
&lt;li&gt;partial success scenarios&lt;/li&gt;
&lt;li&gt;retries&lt;/li&gt;
&lt;li&gt;logging&lt;/li&gt;
&lt;li&gt;user-facing error messages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I ask myself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What happens if this dependency is down?&lt;/li&gt;
&lt;li&gt;What happens if the payload shape changes?&lt;/li&gt;
&lt;li&gt;What happens if this field is missing?&lt;/li&gt;
&lt;li&gt;What happens if the operation succeeds halfway?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the answer is “the app probably throws something weird,” the PR is not ready.&lt;/p&gt;
&lt;h2&gt;
  
  
  7. Are runtime checks present at the system edges?
&lt;/h2&gt;

&lt;p&gt;TypeScript is great, but it does not validate runtime data by itself.&lt;/p&gt;

&lt;p&gt;So any AI-generated code that touches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;request bodies&lt;/li&gt;
&lt;li&gt;query parameters&lt;/li&gt;
&lt;li&gt;local storage&lt;/li&gt;
&lt;li&gt;database results&lt;/li&gt;
&lt;li&gt;webhooks&lt;/li&gt;
&lt;li&gt;environment variables&lt;/li&gt;
&lt;li&gt;third-party APIs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;should make me ask:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where is the runtime validation?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Types help inside the codebase.&lt;br&gt;
Validation protects the boundary.&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 typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;zod&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CreatePostSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;([]),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;CreatePostInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;infer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;CreatePostSchema&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;parseCreatePostInput&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;CreatePostInput&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;CreatePostSchema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&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;If AI writes strongly typed code without validating incoming data, it creates a false sense of safety.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Are names better after the change — or worse?
&lt;/h2&gt;

&lt;p&gt;AI can produce valid code with terrible naming.&lt;/p&gt;

&lt;p&gt;And bad names are expensive because they survive code review surprisingly often.&lt;/p&gt;

&lt;p&gt;So I check:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;function names&lt;/li&gt;
&lt;li&gt;variable names&lt;/li&gt;
&lt;li&gt;type names&lt;/li&gt;
&lt;li&gt;file names&lt;/li&gt;
&lt;li&gt;booleans&lt;/li&gt;
&lt;li&gt;enum values&lt;/li&gt;
&lt;li&gt;error messages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I want names that reflect the domain, not the implementation trick.&lt;/p&gt;

&lt;p&gt;Bad:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dataProcessorManager&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createHandler&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Better:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;invoiceRetryScheduler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createRetryScheduler&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When naming gets vague, maintainability drops fast.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Does the PR introduce duplicate logic?
&lt;/h2&gt;

&lt;p&gt;AI often rewrites something that already exists somewhere else in the codebase.&lt;/p&gt;

&lt;p&gt;That creates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;near-duplicate validators&lt;/li&gt;
&lt;li&gt;inconsistent helpers&lt;/li&gt;
&lt;li&gt;slightly different parsing functions&lt;/li&gt;
&lt;li&gt;multiple ways to do the same thing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So I always scan for duplication before approving.&lt;/p&gt;

&lt;p&gt;My rule is simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;if the logic already exists, reuse it&lt;/li&gt;
&lt;li&gt;if the existing abstraction is bad, improve it&lt;/li&gt;
&lt;li&gt;do not allow AI to create parallel versions of the same idea&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Duplicate code is especially dangerous when it looks clean.&lt;br&gt;
It feels harmless at first and becomes expensive later.&lt;/p&gt;

&lt;h2&gt;
  
  
  10. Would I be comfortable debugging this at 2 AM?
&lt;/h2&gt;

&lt;p&gt;This is one of my favorite review questions.&lt;/p&gt;

&lt;p&gt;Because code can be technically correct and still be operationally terrible.&lt;/p&gt;

&lt;p&gt;I look for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;meaningful logs&lt;/li&gt;
&lt;li&gt;useful error messages&lt;/li&gt;
&lt;li&gt;predictable branching&lt;/li&gt;
&lt;li&gt;obvious control flow&lt;/li&gt;
&lt;li&gt;easy-to-trace data transformations&lt;/li&gt;
&lt;li&gt;no “magic” hidden in helpers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If production breaks, will this code help the next person understand what happened?&lt;/p&gt;

&lt;p&gt;Or will it force them to reverse-engineer AI-generated cleverness under pressure?&lt;/p&gt;

&lt;p&gt;If debugging would be painful, I simplify the code before merge.&lt;/p&gt;

&lt;h2&gt;
  
  
  11. Is the security model still intact?
&lt;/h2&gt;

&lt;p&gt;Any AI-generated PR that touches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;auth&lt;/li&gt;
&lt;li&gt;permissions&lt;/li&gt;
&lt;li&gt;tokens&lt;/li&gt;
&lt;li&gt;cookies&lt;/li&gt;
&lt;li&gt;headers&lt;/li&gt;
&lt;li&gt;uploads&lt;/li&gt;
&lt;li&gt;database access&lt;/li&gt;
&lt;li&gt;redirects&lt;/li&gt;
&lt;li&gt;HTML rendering&lt;/li&gt;
&lt;li&gt;shell commands&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;gets a slower review.&lt;/p&gt;

&lt;p&gt;I specifically check:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;authorization, not just authentication&lt;/li&gt;
&lt;li&gt;input handling&lt;/li&gt;
&lt;li&gt;secret leakage&lt;/li&gt;
&lt;li&gt;unsafe defaults&lt;/li&gt;
&lt;li&gt;overly broad permissions&lt;/li&gt;
&lt;li&gt;accidental exposure of internal fields&lt;/li&gt;
&lt;li&gt;client/server boundary mistakes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I do not trust “looks secure.”&lt;/p&gt;

&lt;p&gt;I want the security assumptions to be obvious in the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  12. Can I roll this back easily?
&lt;/h2&gt;

&lt;p&gt;This final check is underrated.&lt;/p&gt;

&lt;p&gt;Even a good change can fail in production.&lt;/p&gt;

&lt;p&gt;So before merging I ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;is the change isolated?&lt;/li&gt;
&lt;li&gt;is it behind a flag?&lt;/li&gt;
&lt;li&gt;can it be reverted cleanly?&lt;/li&gt;
&lt;li&gt;does it change data shape or persistence behavior?&lt;/li&gt;
&lt;li&gt;does it create migration risk?&lt;/li&gt;
&lt;li&gt;does it depend on coordinated deployment?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI makes it easy to create larger patches than necessary.&lt;br&gt;
Rollback thinking forces the patch back into a safer shape.&lt;/p&gt;

&lt;h2&gt;
  
  
  My quick merge rubric
&lt;/h2&gt;

&lt;p&gt;If I need a fast decision, I use this simple rubric.&lt;/p&gt;

&lt;h3&gt;
  
  
  I merge when:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;the scope is narrow&lt;/li&gt;
&lt;li&gt;the intent is obvious&lt;/li&gt;
&lt;li&gt;the boundaries are typed&lt;/li&gt;
&lt;li&gt;runtime input is validated&lt;/li&gt;
&lt;li&gt;tests prove the claimed behavior&lt;/li&gt;
&lt;li&gt;failure paths are handled&lt;/li&gt;
&lt;li&gt;naming is clear&lt;/li&gt;
&lt;li&gt;security assumptions are visible&lt;/li&gt;
&lt;li&gt;rollback is simple&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  I request changes when:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;the PR does more than requested&lt;/li&gt;
&lt;li&gt;the code adds unnecessary abstractions&lt;/li&gt;
&lt;li&gt;tests are shallow&lt;/li&gt;
&lt;li&gt;boundary validation is missing&lt;/li&gt;
&lt;li&gt;names are vague&lt;/li&gt;
&lt;li&gt;duplicate logic appears&lt;/li&gt;
&lt;li&gt;debugging would be painful&lt;/li&gt;
&lt;li&gt;the operational or security story is unclear&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final thought
&lt;/h2&gt;

&lt;p&gt;AI can absolutely make teams faster.&lt;/p&gt;

&lt;p&gt;But speed only matters if the output is reviewable, understandable, and safe to ship.&lt;/p&gt;

&lt;p&gt;That is why I do not ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Did AI write this?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Would I still approve this if I had to own it in production?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That single question has improved my reviews more than any tool setting.&lt;/p&gt;

&lt;p&gt;If you are using AI heavily in your TypeScript workflow, build a checklist like this one.&lt;/p&gt;

&lt;p&gt;It does not have to be identical.&lt;/p&gt;

&lt;p&gt;It just has to be consistent.&lt;/p&gt;

&lt;p&gt;Because the real productivity gain is not generated code.&lt;/p&gt;

&lt;p&gt;It is generated code that survives review without creating future pain.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>typescript</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I recommend this!</title>
      <dc:creator>𝗝𝗼𝗵𝗻</dc:creator>
      <pubDate>Tue, 28 Apr 2026 16:37:34 +0000</pubDate>
      <link>https://dev.to/johnnylemonny/i-recommend-this-1bo7</link>
      <guid>https://dev.to/johnnylemonny/i-recommend-this-1bo7</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/georgekobaidze/15-essential-sections-every-readme-needs-give-your-project-what-it-deserves-fie" class="crayons-story__hidden-navigation-link"&gt;15 Essential Sections Every README Needs: Give Your Project What It Deserves&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
      &lt;a href="https://dev.to/georgekobaidze/15-essential-sections-every-readme-needs-give-your-project-what-it-deserves-fie" class="crayons-article__context-note crayons-article__context-note__feed"&gt;&lt;p&gt;Ready-to-use markdown template&lt;/p&gt;

&lt;/a&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/georgekobaidze" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F55651%2F29e2a161-9d78-410b-a6e5-9aca17092fa3.jpeg" alt="georgekobaidze profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/georgekobaidze" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Giorgi Kobaidze
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Giorgi Kobaidze
                &lt;a href="/++"&gt;&lt;img alt="Subscriber" class="subscription-icon" src="https://assets.dev.to/assets/subscription-icon-805dfa7ac7dd660f07ed8d654877270825b07a92a03841aa99a1093bd00431b2.png"&gt;&lt;/a&gt;
              
              &lt;div id="story-author-preview-content-3553477" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/georgekobaidze" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F55651%2F29e2a161-9d78-410b-a6e5-9aca17092fa3.jpeg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Giorgi Kobaidze&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/georgekobaidze/15-essential-sections-every-readme-needs-give-your-project-what-it-deserves-fie" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Apr 26&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/georgekobaidze/15-essential-sections-every-readme-needs-give-your-project-what-it-deserves-fie" id="article-link-3553477"&gt;
          15 Essential Sections Every README Needs: Give Your Project What It Deserves
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/documentation"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;documentation&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/opensource"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;opensource&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/tutorial"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;tutorial&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/development"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;development&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/georgekobaidze/15-essential-sections-every-readme-needs-give-your-project-what-it-deserves-fie" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/raised-hands-74b2099fd66a39f2d7eed9305ee0f4553df0eb7b4f11b01b6b1b499973048fe5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;153&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/georgekobaidze/15-essential-sections-every-readme-needs-give-your-project-what-it-deserves-fie#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


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

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

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

&lt;/div&gt;


</description>
    </item>
    <item>
      <title>How I Started Learning Kotlin by Building a Real Android App</title>
      <dc:creator>𝗝𝗼𝗵𝗻</dc:creator>
      <pubDate>Wed, 22 Apr 2026 09:20:00 +0000</pubDate>
      <link>https://dev.to/johnnylemonny/how-i-started-learning-kotlin-by-building-a-real-android-app-32ic</link>
      <guid>https://dev.to/johnnylemonny/how-i-started-learning-kotlin-by-building-a-real-android-app-32ic</guid>
      <description>&lt;p&gt;For a long time, Kotlin was one of those technologies I kept meaning to learn “properly.”&lt;/p&gt;

&lt;p&gt;You probably know the feeling.&lt;/p&gt;

&lt;p&gt;You read a few examples.&lt;br&gt;&lt;br&gt;
You understand the syntax.&lt;br&gt;&lt;br&gt;
You save a few tutorials.&lt;br&gt;&lt;br&gt;
You tell yourself you’ll build something with it “soon.”&lt;/p&gt;

&lt;p&gt;And then nothing happens.&lt;/p&gt;

&lt;p&gt;That was me for a while.&lt;/p&gt;

&lt;p&gt;The problem wasn’t that Kotlin looked hard.&lt;br&gt;&lt;br&gt;
The problem was that learning it in isolation felt abstract.&lt;/p&gt;

&lt;p&gt;I could read about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;null safety,&lt;/li&gt;
&lt;li&gt;data classes,&lt;/li&gt;
&lt;li&gt;coroutines,&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;when&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;extension functions,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;but none of it really &lt;em&gt;stuck&lt;/em&gt; until I had a reason to use it inside a real Android app.&lt;/p&gt;

&lt;p&gt;That’s when things changed.&lt;/p&gt;

&lt;p&gt;Instead of trying to “finish a Kotlin course,” I decided to learn Kotlin by building something real — small enough to complete, but real enough to force me to understand how Android development actually works.&lt;/p&gt;

&lt;p&gt;This post is about what that approach taught me, what slowed me down, and what I’d focus on first if I started learning Kotlin again today.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I chose to learn Kotlin by building instead of studying longer
&lt;/h2&gt;

&lt;p&gt;At some point I realized I was consuming too much “learning material” and not enough actual friction.&lt;/p&gt;

&lt;p&gt;And friction is where real learning starts.&lt;/p&gt;

&lt;p&gt;It is easy to feel productive when you are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;reading docs,&lt;/li&gt;
&lt;li&gt;watching tutorials,&lt;/li&gt;
&lt;li&gt;highlighting syntax,&lt;/li&gt;
&lt;li&gt;copying code examples.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But you don’t really understand a language until you hit questions like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How should I structure this screen?&lt;/li&gt;
&lt;li&gt;Where should this logic live?&lt;/li&gt;
&lt;li&gt;Why is this nullable?&lt;/li&gt;
&lt;li&gt;Why does this state not update the way I expected?&lt;/li&gt;
&lt;li&gt;What is the most Kotlin-like way to write this instead of just translating Java or JavaScript habits?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Building an app forces those questions to happen naturally.&lt;/p&gt;

&lt;p&gt;It also gives you a much better feedback loop:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;write code,&lt;/li&gt;
&lt;li&gt;break something,&lt;/li&gt;
&lt;li&gt;fix it,&lt;/li&gt;
&lt;li&gt;understand one concept more deeply,&lt;/li&gt;
&lt;li&gt;repeat.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That loop taught me more than another week of passive learning would have.&lt;/p&gt;




&lt;h2&gt;
  
  
  The kind of app I built
&lt;/h2&gt;

&lt;p&gt;I did &lt;strong&gt;not&lt;/strong&gt; start with a big idea.&lt;/p&gt;

&lt;p&gt;I didn’t try to build:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a full social app,&lt;/li&gt;
&lt;li&gt;an e-commerce platform,&lt;/li&gt;
&lt;li&gt;a chat system,&lt;/li&gt;
&lt;li&gt;or a feature-packed productivity tool.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That would have been a mistake.&lt;/p&gt;

&lt;p&gt;Instead, I picked something small and realistic:&lt;br&gt;
a simple Android app with a few clear screens, local state, user input, and enough structure to feel like a real product.&lt;/p&gt;

&lt;p&gt;That mattered a lot.&lt;/p&gt;

&lt;p&gt;A good beginner project should be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;small enough to finish,&lt;/li&gt;
&lt;li&gt;useful enough to stay motivating,&lt;/li&gt;
&lt;li&gt;and complex enough to teach real patterns.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is not to impress people with scope.&lt;/p&gt;

&lt;p&gt;The goal is to create a project that forces you to use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Kotlin syntax in real conditions,&lt;/li&gt;
&lt;li&gt;Android UI structure,&lt;/li&gt;
&lt;li&gt;state handling,&lt;/li&gt;
&lt;li&gt;user interactions,&lt;/li&gt;
&lt;li&gt;navigation,&lt;/li&gt;
&lt;li&gt;and a bit of architecture.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s where the language starts making sense.&lt;/p&gt;




&lt;h2&gt;
  
  
  What helped me most when learning Kotlin
&lt;/h2&gt;

&lt;p&gt;A few things made a huge difference early on.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Writing Kotlin every day, even in small amounts
&lt;/h3&gt;

&lt;p&gt;I learned very quickly that consistency mattered more than long study sessions.&lt;/p&gt;

&lt;p&gt;A focused 30–45 minutes of building something real helped me much more than occasionally spending 4 hours jumping between tutorials.&lt;/p&gt;

&lt;p&gt;Kotlin started to feel natural only after repeated exposure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;writing functions,&lt;/li&gt;
&lt;li&gt;handling nullable values,&lt;/li&gt;
&lt;li&gt;creating data models,&lt;/li&gt;
&lt;li&gt;wiring UI interactions,&lt;/li&gt;
&lt;li&gt;refactoring small pieces of code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At first, even simple things felt slower than they should.&lt;/p&gt;

&lt;p&gt;But that’s normal.&lt;/p&gt;

&lt;p&gt;The important part was not speed.&lt;br&gt;&lt;br&gt;
It was repetition.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. Accepting that Kotlin is not just “better Java”
&lt;/h3&gt;

&lt;p&gt;This was one of the biggest mental shifts.&lt;/p&gt;

&lt;p&gt;If you come from another language, especially something like Java, JavaScript, or TypeScript, it is tempting to treat Kotlin as “the same thing with nicer syntax.”&lt;/p&gt;

&lt;p&gt;That mindset slows you down.&lt;/p&gt;

&lt;p&gt;Kotlin becomes much more enjoyable when you stop translating your old habits directly and start asking:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is the idiomatic Kotlin way to do this?&lt;/li&gt;
&lt;li&gt;Why does this language encourage immutability here?&lt;/li&gt;
&lt;li&gt;Why is null handling so explicit?&lt;/li&gt;
&lt;li&gt;Why do data classes feel so natural in app development?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The more I leaned into Kotlin as its own language, the easier it became to write cleaner code.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. Building features instead of collecting concepts
&lt;/h3&gt;

&lt;p&gt;At the beginning, I thought I needed to “learn coroutines,” “learn data classes,” or “learn sealed classes” one by one.&lt;/p&gt;

&lt;p&gt;That was not the best approach for me.&lt;/p&gt;

&lt;p&gt;What worked better was learning those things inside real features.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;user input taught me about state,&lt;/li&gt;
&lt;li&gt;screen transitions taught me about navigation,&lt;/li&gt;
&lt;li&gt;modeling items taught me about data classes,&lt;/li&gt;
&lt;li&gt;error handling taught me about nullability,&lt;/li&gt;
&lt;li&gt;asynchronous work pushed me toward coroutines.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That approach made the concepts feel useful immediately.&lt;/p&gt;

&lt;p&gt;And useful concepts are easier to remember than isolated definitions.&lt;/p&gt;




&lt;h2&gt;
  
  
  What confused me the most at first
&lt;/h2&gt;

&lt;p&gt;Learning Kotlin through a real Android project was helpful — but not frictionless.&lt;/p&gt;

&lt;p&gt;A few things definitely slowed me down.&lt;/p&gt;




&lt;h3&gt;
  
  
  1. Null safety felt great… until I had to actually design around it
&lt;/h3&gt;

&lt;p&gt;At first, null safety looked like one of Kotlin’s cleanest features.&lt;/p&gt;

&lt;p&gt;And it is.&lt;/p&gt;

&lt;p&gt;But it also forced me to become more deliberate.&lt;/p&gt;

&lt;p&gt;Instead of casually passing values around and “handling it later,” I had to think earlier about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what can actually be null,&lt;/li&gt;
&lt;li&gt;what should be required,&lt;/li&gt;
&lt;li&gt;what should have a default value,&lt;/li&gt;
&lt;li&gt;and where I was making assumptions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That was frustrating at first because it exposed weak decisions immediately.&lt;/p&gt;

&lt;p&gt;But looking back, that was a good thing.&lt;/p&gt;

&lt;p&gt;Kotlin was not making development harder.&lt;br&gt;&lt;br&gt;
It was making sloppy assumptions harder.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. Android structure is part of the learning curve, not just Kotlin
&lt;/h3&gt;

&lt;p&gt;This is important.&lt;/p&gt;

&lt;p&gt;When you learn Kotlin for Android, you are not learning just one thing.&lt;/p&gt;

&lt;p&gt;You are learning at least three layers at once:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Kotlin itself,&lt;/li&gt;
&lt;li&gt;Android concepts,&lt;/li&gt;
&lt;li&gt;and your chosen UI / architecture approach.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That means confusion is not always caused by the language.&lt;/p&gt;

&lt;p&gt;Sometimes the real question is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is this a Kotlin issue?&lt;/li&gt;
&lt;li&gt;an Android lifecycle issue?&lt;/li&gt;
&lt;li&gt;a UI state issue?&lt;/li&gt;
&lt;li&gt;a project structure issue?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once I understood that, I stopped blaming Kotlin for every confusing moment.&lt;/p&gt;

&lt;p&gt;A lot of beginner frustration actually comes from trying to learn the whole Android stack at once.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. There is a difference between “it works” and “this is clean”
&lt;/h3&gt;

&lt;p&gt;One of the biggest lessons was realizing how easy it is to build something that works… and how much harder it is to build something that still feels clean after the third or fourth feature.&lt;/p&gt;

&lt;p&gt;Early in the project, I often wrote code like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;directly inside the screen,&lt;/li&gt;
&lt;li&gt;with too much logic in one place,&lt;/li&gt;
&lt;li&gt;and without thinking much about separation of concerns.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That got me moving quickly, which was good.&lt;/p&gt;

&lt;p&gt;But after a while, I could feel the cost:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;harder refactors,&lt;/li&gt;
&lt;li&gt;messier UI code,&lt;/li&gt;
&lt;li&gt;less confidence when adding features.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That was actually one of the most valuable parts of the project.&lt;/p&gt;

&lt;p&gt;It taught me that learning Kotlin is not just about syntax.&lt;br&gt;&lt;br&gt;
It is also about learning where code should live.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Kotlin features that clicked fastest for me
&lt;/h2&gt;

&lt;p&gt;Some Kotlin features made sense almost immediately once I used them in a real app.&lt;/p&gt;

&lt;h3&gt;
  
  
  Data classes
&lt;/h3&gt;

&lt;p&gt;These were one of the quickest wins.&lt;/p&gt;

&lt;p&gt;As soon as I started modeling app data, data classes felt obvious and useful.&lt;/p&gt;

&lt;p&gt;They reduce boilerplate and make data easier to reason about.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;code&gt;when&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This felt much cleaner than long conditional chains.&lt;/p&gt;

&lt;p&gt;It became especially useful for handling UI states and branching logic in a more readable way.&lt;/p&gt;




&lt;h3&gt;
  
  
  Null safety
&lt;/h3&gt;

&lt;p&gt;Even though it was frustrating at first, it made my code more intentional.&lt;/p&gt;

&lt;p&gt;Once I stopped fighting it, I started trusting my code more.&lt;/p&gt;




&lt;h3&gt;
  
  
  Immutability by default
&lt;/h3&gt;

&lt;p&gt;This changed how I thought about state.&lt;/p&gt;

&lt;p&gt;When building UI, predictable state matters a lot.&lt;br&gt;&lt;br&gt;
Kotlin nudged me toward better habits there.&lt;/p&gt;




&lt;h3&gt;
  
  
  Extension functions
&lt;/h3&gt;

&lt;p&gt;These made code feel more expressive once I understood where they were actually useful.&lt;/p&gt;

&lt;p&gt;Not “clever” useful — but genuinely cleaner in small repeated patterns.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I would focus on first if I started again
&lt;/h2&gt;

&lt;p&gt;If I had to restart from zero today, I would not try to learn everything.&lt;/p&gt;

&lt;p&gt;I would focus on this order:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Core Kotlin basics
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;variables&lt;/li&gt;
&lt;li&gt;functions&lt;/li&gt;
&lt;li&gt;classes&lt;/li&gt;
&lt;li&gt;nullability&lt;/li&gt;
&lt;li&gt;collections&lt;/li&gt;
&lt;li&gt;control flow&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Kotlin features that matter quickly in apps
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;data classes&lt;/li&gt;
&lt;li&gt;&lt;code&gt;when&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;immutable patterns&lt;/li&gt;
&lt;li&gt;simple extension functions&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Basic Android app flow
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;screens&lt;/li&gt;
&lt;li&gt;user input&lt;/li&gt;
&lt;li&gt;state&lt;/li&gt;
&lt;li&gt;navigation&lt;/li&gt;
&lt;li&gt;local data&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Code organization
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;separating UI from logic&lt;/li&gt;
&lt;li&gt;keeping files readable&lt;/li&gt;
&lt;li&gt;avoiding giant screens or giant classes&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. Then only later: deeper architecture and advanced patterns
&lt;/h3&gt;

&lt;p&gt;I would avoid over-optimizing too early.&lt;/p&gt;

&lt;p&gt;The first milestone should not be:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Build the perfect architecture.”&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;blockquote&gt;
&lt;p&gt;“Build something working, understandable, and easy enough to improve.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That makes everything else easier.&lt;/p&gt;




&lt;h2&gt;
  
  
  My biggest takeaway
&lt;/h2&gt;

&lt;p&gt;The biggest thing I learned is this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Kotlin became much easier once I stopped trying to “master Kotlin” and started trying to build something with it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That shift changed everything.&lt;/p&gt;

&lt;p&gt;A real app gave every concept a reason to exist.&lt;/p&gt;

&lt;p&gt;Without a project, Kotlin was just a list of language features.&lt;/p&gt;

&lt;p&gt;Inside a project, it became:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a way to model data,&lt;/li&gt;
&lt;li&gt;a way to structure UI logic,&lt;/li&gt;
&lt;li&gt;a way to write safer code,&lt;/li&gt;
&lt;li&gt;and a way to think more clearly about app development.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s when learning started to feel real.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;If you are trying to learn Kotlin right now, my honest advice is:&lt;/p&gt;

&lt;p&gt;Don’t wait until you feel “ready.”&lt;/p&gt;

&lt;p&gt;Don’t try to complete every tutorial first.&lt;/p&gt;

&lt;p&gt;Build something small.&lt;br&gt;&lt;br&gt;
Make it real.&lt;br&gt;&lt;br&gt;
Let the project expose the gaps in your understanding.&lt;/p&gt;

&lt;p&gt;That is where the best learning happens.&lt;/p&gt;

&lt;p&gt;Not when everything is clear.&lt;/p&gt;

&lt;p&gt;But when the code forces you to ask better questions.&lt;/p&gt;




&lt;p&gt;If you’re learning Kotlin too, I’d love to know:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What has been harder for you so far — the language itself, Android concepts, or figuring out how to structure a real app?&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>android</category>
      <category>beginners</category>
      <category>mobile</category>
    </item>
    <item>
      <title>NatureNode: An AI-Powered Biodiversity Research Tool for Earth Day</title>
      <dc:creator>𝗝𝗼𝗵𝗻</dc:creator>
      <pubDate>Sat, 18 Apr 2026 09:30:00 +0000</pubDate>
      <link>https://dev.to/johnnylemonny/naturenode-an-ai-powered-biodiversity-research-tool-for-earth-day-35ko</link>
      <guid>https://dev.to/johnnylemonny/naturenode-an-ai-powered-biodiversity-research-tool-for-earth-day-35ko</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for &lt;a href="https://dev.to/challenges/weekend-challenge-2026-04-16"&gt;Weekend Challenge: Earth Day Edition&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




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

&lt;p&gt;&lt;strong&gt;NatureNode&lt;/strong&gt; is a professional biodiversity research tool and Progressive Web App that transforms a smartphone photo into a comprehensive ecological dossier — instantly, in the field, with no backend and full offline capability.&lt;/p&gt;

&lt;p&gt;Most identification apps give you a name and a pretty photo. NatureNode gives you what a field researcher actually needs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔬 &lt;strong&gt;Full scientific taxonomy&lt;/strong&gt; — family, genus, species&lt;/li&gt;
&lt;li&gt;🌍 &lt;strong&gt;Conservation status&lt;/strong&gt; (IUCN scale) and native range&lt;/li&gt;
&lt;li&gt;♻️ &lt;strong&gt;Ecological role&lt;/strong&gt; — what this organism contributes to its ecosystem&lt;/li&gt;
&lt;li&gt;🛡️ &lt;strong&gt;Protection guidelines&lt;/strong&gt; — actionable tips to conserve what you found&lt;/li&gt;
&lt;li&gt;📓 &lt;strong&gt;Specimen Journal&lt;/strong&gt; — a persistent local database of all your discoveries&lt;/li&gt;
&lt;li&gt;🗺️ &lt;strong&gt;Location tagging&lt;/strong&gt; + one-tap Google Maps navigation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The design philosophy matched the ambition: dark botanical aesthetics, high information density, and interactions that feel deliberate — like a research dashboard, not a social app.&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%2F1attjgova8v2yd1b9m59.webp" 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%2F1attjgova8v2yd1b9m59.webp" alt="NatureNode — Desktop Analysis View" width="800" height="1154"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;🌿 &lt;strong&gt;Live PWA:&lt;/strong&gt; &lt;a href="https://johnnylemonny.github.io/naturenode/" rel="noopener noreferrer"&gt;https://johnnylemonny.github.io/naturenode/&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;To try it:&lt;/strong&gt; Get a free Gemini API key at &lt;a href="https://aistudio.google.com/app/apikey" rel="noopener noreferrer"&gt;Google AI Studio&lt;/a&gt;, paste it into the app, and upload any photo of a plant, insect, animal, or mushroom. Your key is stored securely in your browser — never on any server.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/johnnylemonny" rel="noopener noreferrer"&gt;
        johnnylemonny
      &lt;/a&gt; / &lt;a href="https://github.com/johnnylemonny/naturenode" rel="noopener noreferrer"&gt;
        naturenode
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      🌿 NatureNode: A premium Progressive Web App (PWA) for advanced biodiversity identification. Powered by Google Gemini AI, featuring professional field research tools, specimen journaling, and ecological conservation insights. Built as part of the DEV Weekend Challenge.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;🌿 NatureNode&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://react.dev/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/b46bfccb78b3b4cd9b05aaf834f04a661af853e66dafff4cb9bfe11d685ee5b8/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f52656163742d31392d626c7565" alt="React"&gt;&lt;/a&gt;
&lt;a href="https://tailwindcss.com/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/53b4c18dfa6a79aecb0effa1cfa88ac1e6f792f3dfbdd336eb6a8df6f293bc43/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5461696c77696e642d342d333862646638" alt="Tailwind CSS"&gt;&lt;/a&gt;
&lt;a href="https://ai.google.dev/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/8383ade6b338d8653b967512384d9a4f83b5311e0901388a647f03b0ced79795/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f47656d696e692532304150492d33253230466c6173682d6f72616e6765" alt="Gemini API"&gt;&lt;/a&gt;
&lt;a href="https://vite-pwa-org.netlify.app/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/58d1f53b9fd14b05947f0432d3dc3cb4920b4e546a2439362dfa5cf423641179/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5057412d52656164792d677265656e" alt="PWA"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NatureNode&lt;/strong&gt; is a professional biodiversity research and identification tool. Designed for field researchers and nature enthusiasts, it leverages state-of-the-art AI to transform simple photos into comprehensive ecological dossiers.&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/johnnylemonny/naturenode/./photos/desktop3.webp"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fjohnnylemonny%2Fnaturenode%2FHEAD%2F.%2Fphotos%2Fdesktop3.webp" alt="NatureNode Desktop Interface"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🌟 Key Features&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Botanical Precision UI&lt;/strong&gt;: A high-density, research-oriented design system using Tailwind CSS v4 and the OKLCH color model for superior visual clarity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI-Driven Identification&lt;/strong&gt;: Powered by &lt;strong&gt;Google Gemini 3 Flash&lt;/strong&gt; for instant, high-accuracy recognition of plants, animals, insects, and fungi.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Specimen Journal&lt;/strong&gt;: A persistent, local history of all your discoveries, allowing you to build your own personal biodiversity database.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;📱 PWA &amp;amp; Offline Support&lt;/strong&gt;: Fully installable as a Progressive Web App. Designed to work in the field with robust offline capabilities.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🗺️ Manual Location Mapping&lt;/strong&gt;: Easily log observation points by town or area name.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;📍 Google Maps Integration&lt;/strong&gt;: One-click navigation and mapping of find locations directly in Google Maps.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ecological Insights&lt;/strong&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/johnnylemonny/naturenode" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;





&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Architecture: Zero-Backend, Privacy-First PWA
&lt;/h3&gt;

&lt;p&gt;The core constraint was: &lt;strong&gt;no backend, no running costs, no privacy compromise&lt;/strong&gt;. Everything that isn't AI inference runs locally in the browser. The Gemini API call goes directly from the user's browser to Google's servers using their own key — a "Bring Your Own Key" model that is the most honest approach to privacy-first AI tooling possible.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Browser
├── React 19 + TypeScript          # UI &amp;amp; state management
├── Vite 8 (Rolldown engine)       # Lightning-fast builds
├── Tailwind CSS v4 (OKLCH model)  # Design system with perceptual color
├── Vite PWA Plugin + Workbox      # Offline support &amp;amp; installability
└── @google/generative-ai SDK      # Direct browser → Gemini calls
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Gemini Integration: Typed JSON Schema
&lt;/h3&gt;

&lt;p&gt;The intelligence layer is engineered around Gemini's &lt;code&gt;responseSchema&lt;/code&gt; API — instead of parsing or validating free-form AI text, the model is constrained to return exactly the data shape that TypeScript expects. Zero parsing errors, deterministic structure:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;responseSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SchemaType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;OBJECT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;commonName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;         &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SchemaType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;STRING&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;scientificName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SchemaType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;STRING&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;conservationStatus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SchemaType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;STRING&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;ecologicalRole&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SchemaType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;STRING&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;protectionTips&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="nx"&gt;SchemaType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ARRAY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SchemaType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;STRING&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;genAI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getGenerativeModel&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gemini-3-flash-preview&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;generationConfig&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;responseMimeType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;responseSchema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;           &lt;span class="c1"&gt;// ← model is constrained to this shape&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;This approach is more reliable than prompt-engineering your way to JSON and faster than asking the model to explain its reasoning. The result: sub-3-second identifications with zero unparseable responses.&lt;/p&gt;

&lt;h3&gt;
  
  
  Secure API Key Storage
&lt;/h3&gt;

&lt;p&gt;GitHub's CodeQL scanner flagged clear-text storage of the user's key in &lt;code&gt;localStorage&lt;/code&gt;. The fix: Base64 obfuscation with a generic storage key name. Not encryption — but it prevents the key from sitting as a plain string visible in browser dev tools, and satisfies static analysis:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;obfuscate&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;btoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;unescape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;encodeURIComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;deobfuscate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;decodeURIComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;escape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;atob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;

&lt;span class="c1"&gt;// Save&lt;/span&gt;
&lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;nn_secure_session&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;obfuscate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// Load&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;nn_secure_session&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;raw&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nf"&gt;deobfuscate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;raw&lt;/span&gt;&lt;span class="p"&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;h3&gt;
  
  
  PWA &amp;amp; Offline
&lt;/h3&gt;

&lt;p&gt;Workbox precaches all static assets at build time — the shell, fonts, and full UI load instantly even with no connection. Only the Gemini API call requires internet, and the app communicates this clearly. The manifest enables full "Add to Home Screen" installability on both Android and iOS.&lt;/p&gt;

&lt;h3&gt;
  
  
  CI/CD Pipeline
&lt;/h3&gt;

&lt;p&gt;Three GitHub Actions workflows run on every push:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Workflow&lt;/th&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;deploy.yml&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;actions/deploy-pages@v4&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Build → GitHub Pages (no branch needed)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;linter.yml&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Super-Linter slim v7&lt;/td&gt;
&lt;td&gt;JS / TS / HTML / JSON quality gates&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;codeql.yml&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;CodeQL&lt;/td&gt;
&lt;td&gt;Security vulnerability scanning&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&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%2F5u1467fb5oui9rwrq8ir.webp" 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%2F5u1467fb5oui9rwrq8ir.webp" alt="NatureNode — Desktop Hero (Upload State)" width="800" height="519"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;🥇 Best Use of Google Gemini&lt;/strong&gt; — Gemini 3 Flash Preview is the entire intelligence layer, used with typed JSON schema enforcement for production-grade, zero-parse AI responses delivered directly from browser to API.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
    </item>
    <item>
      <title>5 Developer Trends That Actually Matter in 2026 (Not Just the Hype)</title>
      <dc:creator>𝗝𝗼𝗵𝗻</dc:creator>
      <pubDate>Thu, 16 Apr 2026 12:45:32 +0000</pubDate>
      <link>https://dev.to/johnnylemonny/5-developer-trends-that-actually-matter-in-2026-not-just-the-hype-4g86</link>
      <guid>https://dev.to/johnnylemonny/5-developer-trends-that-actually-matter-in-2026-not-just-the-hype-4g86</guid>
      <description>&lt;p&gt;Every year, developers get flooded with trend lists.&lt;/p&gt;

&lt;p&gt;Most of them are either too broad to be useful or too early to matter in real projects.&lt;/p&gt;

&lt;p&gt;So instead of listing every shiny new thing, I want to focus on the shifts that are already changing how modern apps are built, shipped, and maintained &lt;strong&gt;right now&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Because 2026 does feel different.&lt;/p&gt;

&lt;p&gt;GitHub’s latest Octoverse data says more than &lt;strong&gt;1.1 million public repositories now use an LLM SDK&lt;/strong&gt;, with &lt;strong&gt;693,867&lt;/strong&gt; of those created in the last 12 months alone. It also reports that &lt;strong&gt;TypeScript became the most-used language on GitHub in August 2025&lt;/strong&gt;, overtaking both Python and JavaScript. &lt;a href="https://github.blog/news-insights/octoverse/octoverse-a-new-developer-joins-github-every-second-as-ai-leads-typescript-to-1/" rel="noopener noreferrer"&gt;1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That is not just noise. That is a signal.&lt;/p&gt;

&lt;p&gt;Here are the five trends I think actually matter in 2026 — and what developers should do about them.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. AI coding agents are moving beyond autocomplete
&lt;/h2&gt;

&lt;p&gt;For a while, AI coding tools were mostly “fancy autocomplete.”&lt;/p&gt;

&lt;p&gt;That is no longer the right mental model.&lt;/p&gt;

&lt;p&gt;Anthropic’s 2026 Agentic Coding Trends Report argues that in 2025, coding agents moved from experimental tools to systems that can handle real implementation workflows, including writing tests, debugging, generating docs, and navigating large codebases. At the same time, the report notes an important nuance: developers may use AI in roughly &lt;strong&gt;60% of their work&lt;/strong&gt;, but they still report being able to &lt;strong&gt;fully delegate only 0–20% of tasks&lt;/strong&gt;. &lt;a href="https://resources.anthropic.com/hubfs/2026%20Agentic%20Coding%20Trends%20Report.pdf" rel="noopener noreferrer"&gt;2&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That means the real shift is not “AI replaces developers.”&lt;/p&gt;

&lt;p&gt;The real shift is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;developers are becoming managers of execution loops.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;ul&gt;
&lt;li&gt;“Can the tool write this function?”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;we now ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“Can the agent plan this task?”&lt;/li&gt;
&lt;li&gt;“Can it inspect the codebase safely?”&lt;/li&gt;
&lt;li&gt;“Can it run tests and recover from failure?”&lt;/li&gt;
&lt;li&gt;“Can it return something reviewable?”&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What this means in practice
&lt;/h3&gt;

&lt;p&gt;The best teams will stop treating AI as a tab in the IDE and start treating it as an &lt;strong&gt;async collaborator&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That changes what matters in your codebase:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;clean file structure,&lt;/li&gt;
&lt;li&gt;consistent naming,&lt;/li&gt;
&lt;li&gt;reliable tests,&lt;/li&gt;
&lt;li&gt;good docs,&lt;/li&gt;
&lt;li&gt;and explicit constraints.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Messy code used to slow down humans.&lt;br&gt;&lt;br&gt;
Now it also slows down agents.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. MCP is becoming the integration layer developers should pay attention to
&lt;/h2&gt;

&lt;p&gt;One of the biggest shifts happening quietly is the rise of &lt;strong&gt;MCP&lt;/strong&gt; — the &lt;strong&gt;Model Context Protocol&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Cloudflare describes MCP as an &lt;strong&gt;open standard&lt;/strong&gt; that connects AI systems to external applications, comparing it to a “USB-C port for AI applications.” Vercel describes it similarly as a standard interface that lets LLMs communicate with external tools and data sources. &lt;a href="https://developers.cloudflare.com/agents/model-context-protocol/" rel="noopener noreferrer"&gt;3&lt;/a&gt;&lt;a href="https://vercel.com/docs/mcp" rel="noopener noreferrer"&gt;5&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Why does that matter?&lt;/p&gt;

&lt;p&gt;Because once agents become useful, the next bottleneck is &lt;strong&gt;tool access&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;databases,&lt;/li&gt;
&lt;li&gt;issue trackers,&lt;/li&gt;
&lt;li&gt;deployment platforms,&lt;/li&gt;
&lt;li&gt;logs,&lt;/li&gt;
&lt;li&gt;docs,&lt;/li&gt;
&lt;li&gt;cloud resources,&lt;/li&gt;
&lt;li&gt;and internal APIs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;MCP is interesting because it reduces custom glue code and pushes the ecosystem toward a common contract.&lt;/p&gt;

&lt;p&gt;And this is no longer theoretical.&lt;/p&gt;

&lt;p&gt;Cloudflare explicitly supports building and deploying MCP servers. Vercel has its own official MCP server and documents support for clients including Claude, ChatGPT, Cursor, VS Code with Copilot, Codex CLI, Windsurf, and more. &lt;a href="https://developers.cloudflare.com/agents/model-context-protocol/" rel="noopener noreferrer"&gt;3&lt;/a&gt;&lt;a href="https://vercel.com/docs/agent-resources/vercel-mcp" rel="noopener noreferrer"&gt;4&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What this means in practice
&lt;/h3&gt;

&lt;p&gt;If you build developer tools, internal platforms, APIs, or anything that might be used by agents, you should already be asking:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Should this expose an MCP interface?&lt;/li&gt;
&lt;li&gt;What tools would actually be safe and useful for an agent?&lt;/li&gt;
&lt;li&gt;What permissions should be scoped tightly?&lt;/li&gt;
&lt;li&gt;What tasks should remain human-only?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In 2026, “AI-ready” increasingly means “toolable by standards.”&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Type safety and boring developer experience are becoming competitive advantages
&lt;/h2&gt;

&lt;p&gt;One of the most underrated trends right now is that &lt;strong&gt;typed and predictable systems are becoming more valuable&lt;/strong&gt;, not less.&lt;/p&gt;

&lt;p&gt;GitHub’s Octoverse says TypeScript overtook both Python and JavaScript in August 2025 to become the most-used language on GitHub, calling it the most significant language shift in more than a decade. GitHub also ties that rise to agent-assisted coding, arguing that typed languages make production work more reliable. &lt;a href="https://github.blog/news-insights/octoverse/octoverse-a-new-developer-joins-github-every-second-as-ai-leads-typescript-to-1/" rel="noopener noreferrer"&gt;1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This matches what many teams are noticing already:&lt;/p&gt;

&lt;p&gt;When humans and agents work together, ambiguity becomes expensive.&lt;/p&gt;

&lt;p&gt;That is why “boring” qualities are suddenly strategic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;strong types,&lt;/li&gt;
&lt;li&gt;explicit contracts,&lt;/li&gt;
&lt;li&gt;stable interfaces,&lt;/li&gt;
&lt;li&gt;predictable scripts,&lt;/li&gt;
&lt;li&gt;clear schemas,&lt;/li&gt;
&lt;li&gt;readable errors.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your stack is easy to reason about, it is easier to automate, test, review, and evolve.&lt;/p&gt;

&lt;h3&gt;
  
  
  What this means in practice
&lt;/h3&gt;

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

&lt;blockquote&gt;
&lt;p&gt;“What is the trendiest stack?”&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;blockquote&gt;
&lt;p&gt;“What stack minimizes ambiguity for both humans and machines?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is one reason TypeScript-heavy workflows feel stronger right now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;they reduce guessing,&lt;/li&gt;
&lt;li&gt;improve refactors,&lt;/li&gt;
&lt;li&gt;and make AI-assisted changes less fragile.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In 2026, good DX is no longer just a human experience.&lt;br&gt;&lt;br&gt;
It is also an &lt;strong&gt;agent experience&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Passkeys are moving from “nice idea” to default modern authentication
&lt;/h2&gt;

&lt;p&gt;Authentication is also going through a real shift.&lt;/p&gt;

&lt;p&gt;Passkeys are no longer just something security people talk about at conferences.&lt;/p&gt;

&lt;p&gt;The FIDO Alliance describes passkeys as phishing-resistant credentials based on FIDO standards that let users sign in with the same process they use to unlock their device. FIDO also says passkeys lead to &lt;strong&gt;20% more successful sign-ins over passwords&lt;/strong&gt;, and reports that &lt;strong&gt;53% of people have enabled passkeys on at least one account&lt;/strong&gt;, while &lt;strong&gt;22% enable them everywhere they can&lt;/strong&gt;. &lt;a href="https://fidoalliance.org/passkeys/" rel="noopener noreferrer"&gt;6&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the implementation side, Microsoft now documents passkeys in ASP.NET Core Identity, and MDN describes WebAuthn as a widely available browser capability that enables strong authentication with public key cryptography. &lt;a href="https://learn.microsoft.com/en-us/aspnet/core/security/authentication/passkeys/?view=aspnetcore-10.0" rel="noopener noreferrer"&gt;7&lt;/a&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API" rel="noopener noreferrer"&gt;8&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That makes passkeys relevant far beyond enterprise identity teams.&lt;/p&gt;

&lt;p&gt;They now matter to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SaaS builders,&lt;/li&gt;
&lt;li&gt;indie hackers,&lt;/li&gt;
&lt;li&gt;frontend engineers,&lt;/li&gt;
&lt;li&gt;full-stack teams,&lt;/li&gt;
&lt;li&gt;and anyone trying to improve signup/login conversion without weakening security.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What this means in practice
&lt;/h3&gt;

&lt;p&gt;If you are building a modern app in 2026, authentication should probably be designed around:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;passkeys,&lt;/li&gt;
&lt;li&gt;OAuth/OIDC where appropriate,&lt;/li&gt;
&lt;li&gt;and fewer custom password flows.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The old “email + password + reset flow + 2FA patchwork” setup is no longer the most compelling default.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;“How do I reduce friction and improve security at the same time?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Passkeys are one of the few trends that genuinely do both.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Open source maintainership is changing because AI lowers contribution friction
&lt;/h2&gt;

&lt;p&gt;One more trend that deserves attention: &lt;strong&gt;AI is increasing contribution volume, but not always contribution quality&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;GitHub’s Octoverse reports record growth in repositories, pull requests, and commits, with more than &lt;strong&gt;36 million new developers&lt;/strong&gt; joining GitHub in the past year, more than &lt;strong&gt;230 new repositories created every minute&lt;/strong&gt;, and &lt;strong&gt;43.2 million pull requests merged on average each month&lt;/strong&gt;. &lt;a href="https://github.blog/news-insights/octoverse/octoverse-a-new-developer-joins-github-every-second-as-ai-leads-typescript-to-1/" rel="noopener noreferrer"&gt;1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That growth is exciting — but it also creates pressure.&lt;/p&gt;

&lt;p&gt;InfoQ, summarizing GitHub’s open source trend analysis, highlights a growing maintainer burden from low-quality AI-generated issues and pull requests, and argues that projects without clear written governance, contribution guidelines, and review expectations will struggle to scale sustainably. &lt;a href="https://www.infoq.com/news/2026/03/github-ai-2026/" rel="noopener noreferrer"&gt;9&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What this means in practice
&lt;/h3&gt;

&lt;p&gt;In 2026, if you maintain a public repository, your project needs more than code.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;contribution rules,&lt;/li&gt;
&lt;li&gt;issue templates,&lt;/li&gt;
&lt;li&gt;review expectations,&lt;/li&gt;
&lt;li&gt;a clear roadmap,&lt;/li&gt;
&lt;li&gt;and documentation that helps people help you.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Open source is becoming more accessible.&lt;br&gt;&lt;br&gt;
That is good.&lt;/p&gt;

&lt;p&gt;But it also means maintainers need better systems, not just better instincts.&lt;/p&gt;




&lt;h2&gt;
  
  
  So what should developers actually do now?
&lt;/h2&gt;

&lt;p&gt;If I had to turn these trends into a practical 30-day plan, it would look like this:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Upgrade how you use AI
&lt;/h3&gt;

&lt;p&gt;Stop using AI only for snippets.&lt;br&gt;&lt;br&gt;
Start testing it on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;scoped feature implementation,&lt;/li&gt;
&lt;li&gt;test generation,&lt;/li&gt;
&lt;li&gt;documentation updates,&lt;/li&gt;
&lt;li&gt;and repetitive refactors.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Audit your codebase for agent-friendliness
&lt;/h3&gt;

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

&lt;ul&gt;
&lt;li&gt;Is the structure obvious?&lt;/li&gt;
&lt;li&gt;Are scripts predictable?&lt;/li&gt;
&lt;li&gt;Are errors readable?&lt;/li&gt;
&lt;li&gt;Are tests reliable?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Learn the MCP mental model
&lt;/h3&gt;

&lt;p&gt;Even if you do not build an MCP server this month, understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;hosts,&lt;/li&gt;
&lt;li&gt;clients,&lt;/li&gt;
&lt;li&gt;servers,&lt;/li&gt;
&lt;li&gt;permissions,&lt;/li&gt;
&lt;li&gt;and where this fits in your stack.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Revisit authentication
&lt;/h3&gt;

&lt;p&gt;If your product still treats passwords as the default forever-plan, it is time to reassess.&lt;br&gt;&lt;br&gt;
Passkeys are no longer “future tech.”&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Treat repositories like products
&lt;/h3&gt;

&lt;p&gt;If you maintain public code, improve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;README,&lt;/li&gt;
&lt;li&gt;contribution docs,&lt;/li&gt;
&lt;li&gt;labels,&lt;/li&gt;
&lt;li&gt;issue templates,&lt;/li&gt;
&lt;li&gt;and release notes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because in 2026, the quality of your repo operations matters almost as much as the quality of your code.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final thought
&lt;/h2&gt;

&lt;p&gt;A lot of trend posts focus on what is &lt;strong&gt;new&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The more useful question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;what is already reshaping real developer workflows?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Right now, the answer looks something like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI agents are becoming real collaborators,&lt;/li&gt;
&lt;li&gt;MCP is becoming the connector layer,&lt;/li&gt;
&lt;li&gt;typed systems are gaining strategic value,&lt;/li&gt;
&lt;li&gt;passkeys are becoming practical default auth,&lt;/li&gt;
&lt;li&gt;and maintainership is becoming more operational.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is not just hype.&lt;br&gt;&lt;br&gt;
That is a workflow shift.&lt;/p&gt;

&lt;p&gt;The developers who adapt fastest will not be the ones who try every new tool.&lt;/p&gt;

&lt;p&gt;They will be the ones who build systems that are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;clearer,&lt;/li&gt;
&lt;li&gt;safer,&lt;/li&gt;
&lt;li&gt;more automatable,&lt;/li&gt;
&lt;li&gt;and easier for both humans and machines to work with.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;What trend are you actually seeing in your day-to-day work right now?&lt;/p&gt;

&lt;p&gt;Is it AI agents, passkeys, TypeScript everywhere, better repo hygiene, or something else?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>github</category>
      <category>webdev</category>
      <category>security</category>
    </item>
    <item>
      <title>How to Build a Public Open-Source Project People Actually Want to Clone, Use, and Contribute To</title>
      <dc:creator>𝗝𝗼𝗵𝗻</dc:creator>
      <pubDate>Mon, 13 Apr 2026 12:42:18 +0000</pubDate>
      <link>https://dev.to/johnnylemonny/how-to-build-a-public-open-source-project-people-actually-want-to-clone-use-and-contribute-to-4lmg</link>
      <guid>https://dev.to/johnnylemonny/how-to-build-a-public-open-source-project-people-actually-want-to-clone-use-and-contribute-to-4lmg</guid>
      <description>&lt;p&gt;Most public repositories do &lt;strong&gt;not&lt;/strong&gt; fail because the code is bad.&lt;/p&gt;

&lt;p&gt;They fail because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;nobody understands &lt;strong&gt;why the project exists&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;it is hard to &lt;strong&gt;run locally&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;the repository looks like an abandoned side experiment,&lt;/li&gt;
&lt;li&gt;and there is no clear reason for anyone to come back a second time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to build public open-source projects that attract attention on GitHub, earn stars, and gain real users, you have to think about your repository as more than a folder of code.&lt;/p&gt;

&lt;p&gt;You have to treat it like a &lt;strong&gt;public product&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In this article, I’ll show you how to build modern open-source projects so they:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;look credible from the first visit,&lt;/li&gt;
&lt;li&gt;are easy to run,&lt;/li&gt;
&lt;li&gt;invite contributions,&lt;/li&gt;
&lt;li&gt;and have a much better chance of growing organically.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  1. Start with a problem, not with a stack
&lt;/h2&gt;

&lt;p&gt;A very common mistake looks like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I’m going to build a new project in Next.js / FastAPI / Rust / Bun to practice.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That may be a fine learning project, but it rarely turns into a strong &lt;strong&gt;public&lt;/strong&gt; project.&lt;/p&gt;

&lt;p&gt;Repositories that have the best chance of getting traction usually solve &lt;strong&gt;one clear problem&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;they save time,&lt;/li&gt;
&lt;li&gt;simplify something,&lt;/li&gt;
&lt;li&gt;automate something repetitive,&lt;/li&gt;
&lt;li&gt;or show a modern, opinionated way to build something useful.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Better ideas than “another starter”:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a starter with a &lt;strong&gt;real-world use case&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;a boilerplate for a specific product type,&lt;/li&gt;
&lt;li&gt;a tool that solves a small but frequent developer pain point,&lt;/li&gt;
&lt;li&gt;a team-ready repository template,&lt;/li&gt;
&lt;li&gt;a dashboard, generator, CLI, integration, or mini-SaaS released as open source.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;A good rule of thumb:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
If you can’t describe the project in one sentence &lt;strong&gt;without naming technologies&lt;/strong&gt;, the idea is probably still too vague.&lt;/p&gt;

&lt;p&gt;Instead of:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“This is a project built with React, Node, Prisma, and Docker.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“This is an open-source starter for building admin panels with authentication, roles, billing, and deployment already set up.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;People click on problems.&lt;br&gt;&lt;br&gt;
Not on stacks.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Build a small but complete vertical slice
&lt;/h2&gt;

&lt;p&gt;A public project does not need to be huge.&lt;br&gt;&lt;br&gt;
It needs to feel &lt;strong&gt;complete&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That is a big difference.&lt;/p&gt;

&lt;p&gt;It is far better to show:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;working authentication,&lt;/li&gt;
&lt;li&gt;one clean core workflow,&lt;/li&gt;
&lt;li&gt;solid UI,&lt;/li&gt;
&lt;li&gt;sensible folder structure,&lt;/li&gt;
&lt;li&gt;documentation,&lt;/li&gt;
&lt;li&gt;and a simple deployment path,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;than to show 27 half-finished features.&lt;/p&gt;

&lt;p&gt;The most shareable open-source projects are often the ones that create this feeling quickly:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Okay, this works. I can see how I would use this.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That’s why modern public apps should include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;clear onboarding,&lt;/li&gt;
&lt;li&gt;a demo or screenshots,&lt;/li&gt;
&lt;li&gt;fast local setup,&lt;/li&gt;
&lt;li&gt;sample data,&lt;/li&gt;
&lt;li&gt;a useful &lt;code&gt;.env.example&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;and one obvious way to run the project.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If someone needs 40 minutes just to reach the first useful screen, you lose most potential users.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Treat your README like a landing page
&lt;/h2&gt;

&lt;p&gt;In practice, your README is your project’s homepage.&lt;/p&gt;

&lt;p&gt;That is where visitors decide, often within seconds:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;whether to stay or leave,&lt;/li&gt;
&lt;li&gt;whether to star the repo,&lt;/li&gt;
&lt;li&gt;whether to clone it,&lt;/li&gt;
&lt;li&gt;or whether to close the tab.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A good README does &lt;strong&gt;not&lt;/strong&gt; begin with:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Project X is a modern application that aims to…”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It begins with a &lt;strong&gt;clear value proposition&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What your README should include near the top
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. A one-line pitch
&lt;/h4&gt;

&lt;p&gt;Make it obvious:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what it is,&lt;/li&gt;
&lt;li&gt;who it is for,&lt;/li&gt;
&lt;li&gt;and why it matters.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An open-source SaaS starter for building modern web apps with auth, billing, roles, and deployment built in.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  2. A screenshot, GIF, or live demo
&lt;/h4&gt;

&lt;p&gt;People understand software much faster when they can &lt;strong&gt;see&lt;/strong&gt; it.&lt;/p&gt;

&lt;p&gt;If it’s an application, show:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the dashboard,&lt;/li&gt;
&lt;li&gt;onboarding,&lt;/li&gt;
&lt;li&gt;settings,&lt;/li&gt;
&lt;li&gt;or the core workflow.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  3. A “why this exists” section
&lt;/h4&gt;

&lt;p&gt;Briefly explain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what problem you are solving,&lt;/li&gt;
&lt;li&gt;how the project is different,&lt;/li&gt;
&lt;li&gt;when someone should use it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  4. A fast start section
&lt;/h4&gt;

&lt;p&gt;Keep it short and practical:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;clone,&lt;/li&gt;
&lt;li&gt;install,&lt;/li&gt;
&lt;li&gt;env,&lt;/li&gt;
&lt;li&gt;run.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  5. Key features
&lt;/h4&gt;

&lt;p&gt;Not every feature.&lt;br&gt;&lt;br&gt;
Only the ones that actually communicate the value.&lt;/p&gt;

&lt;h4&gt;
  
  
  6. A roadmap
&lt;/h4&gt;

&lt;p&gt;People are more likely to follow a project when they can see where it is going.&lt;/p&gt;

&lt;h4&gt;
  
  
  7. A contributor section
&lt;/h4&gt;

&lt;p&gt;Even a short one helps.&lt;br&gt;&lt;br&gt;
It should be obvious how someone can get involved.&lt;/p&gt;

&lt;p&gt;A README does not need to be long.&lt;br&gt;&lt;br&gt;
It needs to be &lt;strong&gt;clear, concrete, and easy to scan&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. A public repository has to inspire trust
&lt;/h2&gt;

&lt;p&gt;A lot of repositories look promising at first glance.&lt;/p&gt;

&lt;p&gt;Then you open them and discover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;no license,&lt;/li&gt;
&lt;li&gt;no idea whether the code can be used,&lt;/li&gt;
&lt;li&gt;no contribution rules,&lt;/li&gt;
&lt;li&gt;no issue templates,&lt;/li&gt;
&lt;li&gt;no signal that the project is actively maintained.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want people to take your project seriously, you need the &lt;strong&gt;trust layer&lt;/strong&gt; of open source.&lt;/p&gt;

&lt;p&gt;At minimum, have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;README.md&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;LICENSE&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CONTRIBUTING.md&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CODE_OF_CONDUCT.md&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SECURITY.md&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;issue and pull request templates&lt;/li&gt;
&lt;li&gt;a meaningful repository description&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are the details that separate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“I uploaded some code”
from&lt;/li&gt;
&lt;li&gt;“I’m building a project people can join.”&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  5. Optimize the first five minutes
&lt;/h2&gt;

&lt;p&gt;The most important moment is &lt;strong&gt;not&lt;/strong&gt; when someone stars your repo.&lt;/p&gt;

&lt;p&gt;The most important moment is when someone tries to &lt;strong&gt;run it locally&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If they hit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;missing environment variables,&lt;/li&gt;
&lt;li&gt;outdated setup instructions,&lt;/li&gt;
&lt;li&gt;confusing scripts,&lt;/li&gt;
&lt;li&gt;broken migrations,&lt;/li&gt;
&lt;li&gt;or secrets hidden in config files,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;they are usually gone.&lt;/p&gt;

&lt;p&gt;That’s why you should test your project as if you were a stranger discovering it for the first time.&lt;/p&gt;

&lt;h3&gt;
  
  
  My simple pre-release checklist
&lt;/h3&gt;

&lt;p&gt;Before making a repo public, I ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can a new person run this without asking me questions?&lt;/li&gt;
&lt;li&gt;Does the README answer the most obvious setup questions?&lt;/li&gt;
&lt;li&gt;Is the configuration predictable?&lt;/li&gt;
&lt;li&gt;Are the error messages understandable?&lt;/li&gt;
&lt;li&gt;Do sample data or seed scripts help show value quickly?&lt;/li&gt;
&lt;li&gt;Are the script names obvious?&lt;/li&gt;
&lt;li&gt;Can this project run on a clean machine without guesswork?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This usually matters more than one more feature.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Package the repository like a product
&lt;/h2&gt;

&lt;p&gt;Strong public projects are not only well-built.&lt;br&gt;&lt;br&gt;
They are also &lt;strong&gt;well-packaged&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you want more visibility:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;choose a clear repository name,&lt;/li&gt;
&lt;li&gt;write a sharp description,&lt;/li&gt;
&lt;li&gt;use relevant tags/topics,&lt;/li&gt;
&lt;li&gt;add a social preview image,&lt;/li&gt;
&lt;li&gt;publish real releases,&lt;/li&gt;
&lt;li&gt;show progress through changelogs and updates.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is especially important for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;modern web apps,&lt;/li&gt;
&lt;li&gt;starters,&lt;/li&gt;
&lt;li&gt;boilerplates,&lt;/li&gt;
&lt;li&gt;developer tools,&lt;/li&gt;
&lt;li&gt;templates,&lt;/li&gt;
&lt;li&gt;and infrastructure projects.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;People often judge project quality from the repository page itself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;is the name clear,&lt;/li&gt;
&lt;li&gt;is the description useful,&lt;/li&gt;
&lt;li&gt;is the value obvious,&lt;/li&gt;
&lt;li&gt;does the project look active?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your code can be excellent and still get ignored if the repository looks neglected.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Build community around the problem, not just the code
&lt;/h2&gt;

&lt;p&gt;A lot of people think open source is only about pull requests.&lt;/p&gt;

&lt;p&gt;That is too narrow.&lt;/p&gt;

&lt;p&gt;People can add value in many ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;reporting bugs,&lt;/li&gt;
&lt;li&gt;suggesting features,&lt;/li&gt;
&lt;li&gt;improving documentation,&lt;/li&gt;
&lt;li&gt;testing edge cases,&lt;/li&gt;
&lt;li&gt;sharing feedback,&lt;/li&gt;
&lt;li&gt;explaining how they use the project.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is why you should create a space not only for code changes, but for discussion and learning.&lt;/p&gt;

&lt;p&gt;Helpful tools include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;issue templates,&lt;/li&gt;
&lt;li&gt;labels like &lt;code&gt;good first issue&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;help wanted&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;a public roadmap,&lt;/li&gt;
&lt;li&gt;a list of contribution ideas,&lt;/li&gt;
&lt;li&gt;an FAQ,&lt;/li&gt;
&lt;li&gt;discussion threads,&lt;/li&gt;
&lt;li&gt;or a feedback board.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The less friction people feel, the more likely they are to participate.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. Publish early, but do not publish chaos
&lt;/h2&gt;

&lt;p&gt;“Ship early” is good advice.&lt;/p&gt;

&lt;p&gt;But “make it public early” does &lt;strong&gt;not&lt;/strong&gt; mean:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Throw everything online before it makes sense.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Before you promote a project, make sure it is at least:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;understandable,&lt;/li&gt;
&lt;li&gt;runnable,&lt;/li&gt;
&lt;li&gt;documented,&lt;/li&gt;
&lt;li&gt;and safe to share publicly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This matters even more if you are building in public on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;X,&lt;/li&gt;
&lt;li&gt;LinkedIn,&lt;/li&gt;
&lt;li&gt;DEV,&lt;/li&gt;
&lt;li&gt;Reddit,&lt;/li&gt;
&lt;li&gt;Hacker News,&lt;/li&gt;
&lt;li&gt;newsletters,&lt;/li&gt;
&lt;li&gt;or YouTube.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One of the most common mistakes in open source is promoting a project too early:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;before the README is useful,&lt;/li&gt;
&lt;li&gt;before setup works,&lt;/li&gt;
&lt;li&gt;before the value proposition is clear.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result?&lt;/p&gt;

&lt;p&gt;Traffic arrives, but it does not turn into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;stars,&lt;/li&gt;
&lt;li&gt;watchers,&lt;/li&gt;
&lt;li&gt;issues,&lt;/li&gt;
&lt;li&gt;contributors,&lt;/li&gt;
&lt;li&gt;or real users.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is better to publish a week later and make a strong first impression.&lt;/p&gt;




&lt;h2&gt;
  
  
  9. Think repo-first for modern apps
&lt;/h2&gt;

&lt;p&gt;If you are building a modern app in public, your repository is part of the product.&lt;/p&gt;

&lt;p&gt;It does not just store code. It:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sells the idea,&lt;/li&gt;
&lt;li&gt;documents decisions,&lt;/li&gt;
&lt;li&gt;builds trust,&lt;/li&gt;
&lt;li&gt;shows quality,&lt;/li&gt;
&lt;li&gt;and invites people in.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A modern repository should answer these questions immediately:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What does this do?&lt;/li&gt;
&lt;li&gt;Why does it exist?&lt;/li&gt;
&lt;li&gt;How do I run it?&lt;/li&gt;
&lt;li&gt;How do I use it?&lt;/li&gt;
&lt;li&gt;How do I report a problem?&lt;/li&gt;
&lt;li&gt;How do I contribute?&lt;/li&gt;
&lt;li&gt;What direction is the project going?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If those answers are visible from the beginning, your repository starts working for you even when you are offline.&lt;/p&gt;




&lt;h2&gt;
  
  
  10. A simple checklist before publishing on GitHub
&lt;/h2&gt;

&lt;p&gt;Use this as a lightweight definition of done for any public project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Product
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] The project solves a specific problem&lt;/li&gt;
&lt;li&gt;[ ] There is a clear use case to show&lt;/li&gt;
&lt;li&gt;[ ] The value can be explained in one or two sentences&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Repository
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] The README is clear and concrete&lt;/li&gt;
&lt;li&gt;[ ] There is a screenshot, GIF, or demo&lt;/li&gt;
&lt;li&gt;[ ] There is a &lt;code&gt;LICENSE&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] There is a &lt;code&gt;CONTRIBUTING.md&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] There is a &lt;code&gt;CODE_OF_CONDUCT.md&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] There is a &lt;code&gt;SECURITY.md&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Issue and PR templates are ready&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Developer Experience
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] There is an &lt;code&gt;.env.example&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Setup works from zero&lt;/li&gt;
&lt;li&gt;[ ] Commands are simple and predictable&lt;/li&gt;
&lt;li&gt;[ ] There is seed or sample data&lt;/li&gt;
&lt;li&gt;[ ] The project runs without guesswork&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Visibility
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] The repo has a good description&lt;/li&gt;
&lt;li&gt;[ ] The repository name is easy to understand&lt;/li&gt;
&lt;li&gt;[ ] Relevant tags/topics are added&lt;/li&gt;
&lt;li&gt;[ ] A first release is prepared&lt;/li&gt;
&lt;li&gt;[ ] The next steps are visible&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Final thought
&lt;/h2&gt;

&lt;p&gt;Open source does not win on code quality alone.&lt;/p&gt;

&lt;p&gt;It wins through a combination of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;usefulness&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;clarity&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;trust&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;easy onboarding&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;and &lt;strong&gt;consistent visible progress&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to build public projects that actually grow, do not just ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“How do I write better code?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Also ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Will a random developer on the internet understand this project, run it, and want to come back?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Because that is where real public open source begins.&lt;/p&gt;




&lt;p&gt;If you are building public repositories yourself, I’d love to know:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What kills open-source projects fastest in your experience — scope creep, weak onboarding, poor README, inconsistent updates, or something else?&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>github</category>
      <category>webdev</category>
      <category>devops</category>
    </item>
    <item>
      <title>Working on Cabal v3: reviving a P2P mobile chat app with React Native</title>
      <dc:creator>𝗝𝗼𝗵𝗻</dc:creator>
      <pubDate>Mon, 13 Apr 2026 08:33:42 +0000</pubDate>
      <link>https://dev.to/johnnylemonny/working-on-cabal-v3-reviving-a-p2p-mobile-chat-app-with-react-native-fd4</link>
      <guid>https://dev.to/johnnylemonny/working-on-cabal-v3-reviving-a-p2p-mobile-chat-app-with-react-native-fd4</guid>
      <description>&lt;p&gt;Right now I’m working on &lt;strong&gt;Cabal v3&lt;/strong&gt; — a modern &lt;strong&gt;peer-to-peer chat app for Android&lt;/strong&gt; built on top of the &lt;strong&gt;Cable protocol&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This project is both a modernization and a revival of the older &lt;strong&gt;cabal-mobile&lt;/strong&gt; effort:&lt;br&gt;
&lt;a href="https://github.com/cabal-club/cabal-mobile" rel="noopener noreferrer"&gt;https://github.com/cabal-club/cabal-mobile&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The original project was created to let people chat with the &lt;strong&gt;P2P swarm&lt;/strong&gt; on mobile devices, and its last tagged release (&lt;code&gt;1.0&lt;/code&gt;) goes back to &lt;strong&gt;June 17, 2018&lt;/strong&gt;. Later, the project README pointed development toward a &lt;code&gt;v2&lt;/code&gt; branch, so the idea of evolving the mobile client has already been part of its history. &lt;a href="https://github.com/cabal-club/cabal-mobile/releases" rel="noopener noreferrer"&gt;1&lt;/a&gt;&lt;a href="https://github.com/cabal-club/cabal-mobile/diffs/0?commit=b49c4b76fbe1af236de5baaac5f3282681f18951&amp;amp;name=master&amp;amp;qualified_name=refs%2Fheads%2Fmaster&amp;amp;sha1=42a9c097684dfc6705c684ba0f6f2ccbdd7c4e00&amp;amp;sha2=b49c4b76fbe1af236de5baaac5f3282681f18951&amp;amp;short_path=5a831ea&amp;amp;unchanged=expanded&amp;amp;w=false" rel="noopener noreferrer"&gt;2&lt;/a&gt;&lt;a href="https://github.com/cabal-club/cabal-mobile/commit/master" rel="noopener noreferrer"&gt;3&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What makes this especially interesting to me is the protocol underneath it.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Cable&lt;/strong&gt; is a lightweight protocol for &lt;strong&gt;peer-to-peer private group chats&lt;/strong&gt;, where peers communicate directly instead of depending on a centralized server. The protocol is designed around encrypted communication between equal peers and the exchange of cryptographically signed chat data. &lt;a href="https://github.com/cabal-club/cable" rel="noopener noreferrer"&gt;4&lt;/a&gt;&lt;a href="https://github.com/cabal-club/cable/blob/main/handshake.md" rel="noopener noreferrer"&gt;5&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For me, this is not just an interesting open-source revival.&lt;br&gt;&lt;br&gt;
It’s also a really good opportunity to learn more about building a &lt;strong&gt;mobile frontend with React Native&lt;/strong&gt; while working on something rooted in decentralized communication.&lt;/p&gt;

&lt;p&gt;So this project sits at a really interesting intersection for me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;mobile development&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;React Native&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Android&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;open source&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;and &lt;strong&gt;peer-to-peer systems&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Still early, but I’m excited to keep pushing it forward.&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>android</category>
      <category>opensource</category>
      <category>mobile</category>
    </item>
    <item>
      <title>From NASA Exoplanet Query to ExoVault: Building a Better Data Exploration Experience</title>
      <dc:creator>𝗝𝗼𝗵𝗻</dc:creator>
      <pubDate>Sat, 11 Apr 2026 13:25:13 +0000</pubDate>
      <link>https://dev.to/johnnylemonny/from-nasa-exoplanet-query-to-exovault-building-a-better-data-exploration-experience-4j06</link>
      <guid>https://dev.to/johnnylemonny/from-nasa-exoplanet-query-to-exovault-building-a-better-data-exploration-experience-4j06</guid>
      <description>&lt;p&gt;Other project idea I recently decided to build in public was inspired by the &lt;strong&gt;NASA Exoplanet Query&lt;/strong&gt; prompt from the App Ideas repository.&lt;/p&gt;

&lt;p&gt;That project eventually became &lt;strong&gt;ExoVault&lt;/strong&gt;:&lt;br&gt;
&lt;a href="https://github.com/johnnylemonny/ExoVault" rel="noopener noreferrer"&gt;https://github.com/johnnylemonny/ExoVault&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What started as a structured data query idea turned into something much more interesting for me:&lt;br&gt;
a more polished, cinematic interface for exploring NASA exoplanet archive data.&lt;/p&gt;




&lt;h2&gt;
  
  
  The original prompt
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;NASA Exoplanet Query&lt;/strong&gt; idea is already a really good challenge.&lt;/p&gt;

&lt;p&gt;It’s built around:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;working with NASA archive data,&lt;/li&gt;
&lt;li&gt;loading CSV efficiently,&lt;/li&gt;
&lt;li&gt;minimizing delays at startup,&lt;/li&gt;
&lt;li&gt;and building a query interface that lets users filter exoplanet data by fields like discovery year, method, host name, and facility.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That made it appealing right away.&lt;/p&gt;

&lt;p&gt;It wasn’t just about rendering data.&lt;br&gt;
It was about thinking carefully about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ingestion,&lt;/li&gt;
&lt;li&gt;structure,&lt;/li&gt;
&lt;li&gt;search,&lt;/li&gt;
&lt;li&gt;and presentation.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What pulled me into this idea
&lt;/h2&gt;

&lt;p&gt;What interested me most wasn’t only the dataset.&lt;/p&gt;

&lt;p&gt;It was the possibility of taking something that could have been “just a query tool” and pushing it toward a better exploration experience.&lt;/p&gt;

&lt;p&gt;I kept thinking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What if this felt less like a utility screen and more like a discovery product?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That question shaped the direction of the whole project.&lt;/p&gt;

&lt;p&gt;Instead of building only the minimum query UI, I wanted to create something that felt more deliberate, more visually refined, and more enjoyable to explore.&lt;/p&gt;

&lt;p&gt;That’s where &lt;strong&gt;ExoVault&lt;/strong&gt; came from.&lt;/p&gt;




&lt;h2&gt;
  
  
  How ExoVault evolved
&lt;/h2&gt;

&lt;p&gt;In my version, the project became a more premium archive explorer built around:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a custom CSV-to-JSON data pipeline,&lt;/li&gt;
&lt;li&gt;a high-performance frontend,&lt;/li&gt;
&lt;li&gt;compare mode for exoplanetary systems,&lt;/li&gt;
&lt;li&gt;glassmorphic visuals,&lt;/li&gt;
&lt;li&gt;and a more cinematic browsing experience.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I built ExoVault with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Astro&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;React&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tailwind CSS&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TypeScript&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and used a custom data pipeline to process NASA’s raw CSV into optimized JSON payloads.&lt;/p&gt;

&lt;p&gt;That part was especially satisfying because it made the project feel more complete end-to-end:&lt;br&gt;
not just UI, not just data handling, but both working together.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I wanted the project to feel like
&lt;/h2&gt;

&lt;p&gt;One of my goals with ExoVault was to make exploration feel intentional.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;filter,&lt;/li&gt;
&lt;li&gt;search,&lt;/li&gt;
&lt;li&gt;render rows,&lt;/li&gt;
&lt;li&gt;done.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I wanted the archive to feel like something people would actually want to browse.&lt;/p&gt;

&lt;p&gt;That meant paying attention to things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;visual hierarchy,&lt;/li&gt;
&lt;li&gt;transitions,&lt;/li&gt;
&lt;li&gt;compare flow,&lt;/li&gt;
&lt;li&gt;and how the interface frames the data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I think there’s a big difference between “showing information” and “creating a discovery experience.”&lt;/p&gt;

&lt;p&gt;This project made me think a lot about that difference.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I learned while building it
&lt;/h2&gt;

&lt;p&gt;A few things stood out while working on ExoVault:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Data projects become more interesting when presentation is treated seriously
&lt;/h3&gt;

&lt;p&gt;A structured dataset can feel dry or compelling depending on how the experience is shaped.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Prompt-based ideas are often stronger than they first appear
&lt;/h3&gt;

&lt;p&gt;The original App Ideas brief gave me a very solid technical core.&lt;br&gt;
The interesting part came from deciding how to evolve it.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Frontend polish matters even in data-heavy apps
&lt;/h3&gt;

&lt;p&gt;If the interface feels flat, the whole experience feels flatter too.&lt;br&gt;
Good data presentation is also a UX problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Public repos push me toward stronger execution
&lt;/h3&gt;

&lt;p&gt;Knowing the project would live openly on GitHub made me care more about the quality of the pipeline, repo structure, documentation, and overall presentation.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I like using structured prompts as a starting point
&lt;/h2&gt;

&lt;p&gt;I think structured prompt repositories are one of the best ways to build momentum — especially if you don’t treat them as the finish line.&lt;/p&gt;

&lt;p&gt;That’s how I’m trying to use them.&lt;/p&gt;

&lt;p&gt;Not as instructions to copy,&lt;br&gt;
but as a framework to build from.&lt;/p&gt;

&lt;p&gt;The prompt gives me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;direction,&lt;/li&gt;
&lt;li&gt;constraints,&lt;/li&gt;
&lt;li&gt;and technical focus.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then the real project begins when I start asking:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;how should this feel?&lt;/li&gt;
&lt;li&gt;what should be improved?&lt;/li&gt;
&lt;li&gt;what makes this worth sharing publicly?&lt;/li&gt;
&lt;li&gt;how can this become more than the base brief?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ExoVault is probably one of my clearest examples of that so far.&lt;/p&gt;




&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ExoVault:&lt;/strong&gt; &lt;a href="https://github.com/johnnylemonny/ExoVault" rel="noopener noreferrer"&gt;https://github.com/johnnylemonny/ExoVault&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Live demo:&lt;/strong&gt; &lt;a href="https://johnnylemonny.github.io/ExoVault/" rel="noopener noreferrer"&gt;https://johnnylemonny.github.io/ExoVault/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;App Ideas:&lt;/strong&gt; &lt;a href="https://github.com/florinpop17/app-ideas" rel="noopener noreferrer"&gt;https://github.com/florinpop17/app-ideas&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading 👋&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>webdev</category>
      <category>astro</category>
      <category>typescript</category>
    </item>
    <item>
      <title>From a Calorie Counter Prompt to a Local-First Nutrition Tracker</title>
      <dc:creator>𝗝𝗼𝗵𝗻</dc:creator>
      <pubDate>Sat, 11 Apr 2026 13:06:38 +0000</pubDate>
      <link>https://dev.to/johnnylemonny/from-a-calorie-counter-prompt-to-a-local-first-nutrition-tracker-239j</link>
      <guid>https://dev.to/johnnylemonny/from-a-calorie-counter-prompt-to-a-local-first-nutrition-tracker-239j</guid>
      <description>&lt;p&gt;One of the things I’ve been trying to do lately is take project prompts seriously enough to turn them into public, polished repositories instead of leaving them as half-finished exercises.&lt;/p&gt;

&lt;p&gt;That’s exactly what happened with &lt;strong&gt;NutraFlux&lt;/strong&gt;:&lt;br&gt;
&lt;a href="https://github.com/johnnylemonny/NutraFlux" rel="noopener noreferrer"&gt;https://github.com/johnnylemonny/NutraFlux&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The project was inspired by the &lt;strong&gt;Calorie Counter&lt;/strong&gt; idea from the App Ideas repository, but I didn’t want to stop at “search foods and show calories.”&lt;/p&gt;

&lt;p&gt;I wanted to push it into something that felt faster, cleaner, and more product-like.&lt;/p&gt;




&lt;h2&gt;
  
  
  The original idea
&lt;/h2&gt;

&lt;p&gt;The original &lt;strong&gt;Calorie Counter&lt;/strong&gt; prompt is already a strong one.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;searching foods,&lt;/li&gt;
&lt;li&gt;showing matching results,&lt;/li&gt;
&lt;li&gt;calorie values,&lt;/li&gt;
&lt;li&gt;and working with structured nutritional data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also introduces useful technical constraints:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;transforming raw food data into a format that is easier to search,&lt;/li&gt;
&lt;li&gt;limiting results,&lt;/li&gt;
&lt;li&gt;and thinking about performance and search strategy.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That made it a really good foundation.&lt;/p&gt;




&lt;h2&gt;
  
  
  What interested me most
&lt;/h2&gt;

&lt;p&gt;What grabbed my attention wasn’t just the calorie tracking part.&lt;/p&gt;

&lt;p&gt;It was the opportunity to build a nutrition tool that felt:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;immediate,&lt;/li&gt;
&lt;li&gt;search-first,&lt;/li&gt;
&lt;li&gt;and frictionless.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A lot of apps in this space feel slower or heavier than they need to.&lt;/p&gt;

&lt;p&gt;So instead of treating this as a basic exercise, I started asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What would this feel like if I designed it more like a fast, privacy-friendly product?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That question eventually led to &lt;strong&gt;NutraFlux&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  How NutraFlux evolved
&lt;/h2&gt;

&lt;p&gt;In my version, the idea became a &lt;strong&gt;local-first daily calorie and macro tracker&lt;/strong&gt; built around speed, privacy, and a more refined frontend experience.&lt;/p&gt;

&lt;p&gt;NutraFlux includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;instant search-first logging,&lt;/li&gt;
&lt;li&gt;wildcard food lookup,&lt;/li&gt;
&lt;li&gt;meal categories,&lt;/li&gt;
&lt;li&gt;calorie budgeting and progress indicators,&lt;/li&gt;
&lt;li&gt;favorites and recently used foods,&lt;/li&gt;
&lt;li&gt;adaptive design,&lt;/li&gt;
&lt;li&gt;and a more polished visual system.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What I liked most about building it was that the original prompt gave me a functional core — but the product identity came from the decisions I made around it.&lt;/p&gt;

&lt;p&gt;That’s where it stopped feeling like a challenge and started feeling like my own project.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I made it local-first
&lt;/h2&gt;

&lt;p&gt;One of the biggest choices behind NutraFlux was making it &lt;strong&gt;strictly local-first&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Everything lives in the browser:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;nutritional data,&lt;/li&gt;
&lt;li&gt;settings,&lt;/li&gt;
&lt;li&gt;and food history.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No account wall.&lt;br&gt;
No cloud sync.&lt;br&gt;
No user data leaving the device.&lt;/p&gt;

&lt;p&gt;I really liked that direction because it made the product feel:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;faster,&lt;/li&gt;
&lt;li&gt;more private,&lt;/li&gt;
&lt;li&gt;and more focused.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also changed how I thought about UX.&lt;/p&gt;

&lt;p&gt;When everything happens instantly and locally, the interface itself has to carry more of the experience.&lt;br&gt;&lt;br&gt;
That made clarity, speed, and smooth interaction much more important.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I learned from building it
&lt;/h2&gt;

&lt;p&gt;A few things really stood out while working on this project:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. A strong prompt is a good starting point — not a limitation
&lt;/h3&gt;

&lt;p&gt;The base idea gave me a clear direction, but the interesting part was deciding how far to take it beyond the original brief.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Product feel matters as much as base functionality
&lt;/h3&gt;

&lt;p&gt;The app can technically work, but it still won’t feel complete unless the UI, feedback, and flow are treated with care.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Privacy can be part of the product identity
&lt;/h3&gt;

&lt;p&gt;Making NutraFlux local-first wasn’t just a technical detail.&lt;br&gt;&lt;br&gt;
It became one of the reasons the app feels different.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Public repos raise the bar in a good way
&lt;/h3&gt;

&lt;p&gt;Once I knew this would live publicly on GitHub, I thought more carefully about polish, structure, and presentation.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I like building from prompts this way
&lt;/h2&gt;

&lt;p&gt;I think project prompt repositories get underestimated sometimes.&lt;/p&gt;

&lt;p&gt;But for me, they’re useful because they remove just enough uncertainty to let me focus on what really matters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;interpretation,&lt;/li&gt;
&lt;li&gt;technical decisions,&lt;/li&gt;
&lt;li&gt;UX,&lt;/li&gt;
&lt;li&gt;polish,&lt;/li&gt;
&lt;li&gt;and project identity.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;NutraFlux is a good example of that.&lt;/p&gt;

&lt;p&gt;It started as inspiration from a calorie counter prompt.&lt;br&gt;
Now it’s part of the kind of public open-source work I want to keep building more of.&lt;/p&gt;




&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;NutraFlux:&lt;/strong&gt; &lt;a href="https://github.com/johnnylemonny/NutraFlux" rel="noopener noreferrer"&gt;https://github.com/johnnylemonny/NutraFlux&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Live demo:&lt;/strong&gt; &lt;a href="https://johnnylemonny.github.io/NutraFlux/" rel="noopener noreferrer"&gt;https://johnnylemonny.github.io/NutraFlux/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;App Ideas:&lt;/strong&gt; &lt;a href="https://github.com/florinpop17/app-ideas" rel="noopener noreferrer"&gt;https://github.com/florinpop17/app-ideas&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading 👋&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>webdev</category>
      <category>react</category>
      <category>buildinpublic</category>
    </item>
    <item>
      <title>I Built a Free Hydration Tracker with No Signup: Here’s What I Learned</title>
      <dc:creator>𝗝𝗼𝗵𝗻</dc:creator>
      <pubDate>Fri, 10 Apr 2026 16:56:20 +0000</pubDate>
      <link>https://dev.to/johnnylemonny/i-built-a-free-hydration-tracker-with-no-signup-heres-what-i-learned-1aon</link>
      <guid>https://dev.to/johnnylemonny/i-built-a-free-hydration-tracker-with-no-signup-heres-what-i-learned-1aon</guid>
      <description>&lt;p&gt;I recently built &lt;strong&gt;Drink Daily&lt;/strong&gt;, a hydration tracking web app designed to be &lt;strong&gt;free, simple to use, and available without registration&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;🔗 Live app: &lt;a href="https://drink-daily.vercel.app/en" rel="noopener noreferrer"&gt;https://drink-daily.vercel.app/en&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;This is one of the projects I’m most proud of so far, not just because it works, but because it reflects the kind of products I like building: practical, lightweight, and polished enough to feel good to use.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I built it
&lt;/h2&gt;

&lt;p&gt;A lot of small health-related apps create friction too early.&lt;/p&gt;

&lt;p&gt;You open the app and immediately hit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a sign-up wall,&lt;/li&gt;
&lt;li&gt;limited functionality,&lt;/li&gt;
&lt;li&gt;too much clutter,&lt;/li&gt;
&lt;li&gt;or an interface that feels more like a form than a product.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I wanted to build something different:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;useful from the first visit&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;no registration required&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;clear and focused&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;pleasant to interact with&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;good enough to feel like a real product, not just a demo&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hydration tracking felt like a good fit for that kind of experience.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Drink Daily is
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Drink Daily&lt;/strong&gt; is a free hydration tracking app that helps users keep track of daily water intake without forcing account creation.&lt;/p&gt;

&lt;p&gt;The goal was to keep the experience:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;frictionless,&lt;/li&gt;
&lt;li&gt;fast,&lt;/li&gt;
&lt;li&gt;understandable,&lt;/li&gt;
&lt;li&gt;and easy to return to.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of overcomplicating the idea, I focused on making the core experience feel smooth and intentional.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I wanted to get right
&lt;/h2&gt;

&lt;p&gt;When I started building it, I cared about more than “just making it work.”&lt;/p&gt;

&lt;p&gt;I wanted the app to feel:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Simple
&lt;/h3&gt;

&lt;p&gt;The app should be easy to understand immediately.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Lightweight
&lt;/h3&gt;

&lt;p&gt;No unnecessary barriers, no bloated flows, no forced registration.&lt;/p&gt;

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

&lt;p&gt;I enjoy building interfaces that feel refined, so I paid attention to layout, spacing, clarity, and the overall experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Actually usable
&lt;/h3&gt;

&lt;p&gt;Even for a small app, I wanted it to feel like something people could genuinely use — not just click through once.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I learned while building it
&lt;/h2&gt;

&lt;p&gt;Building Drink Daily taught me a lot about the difference between &lt;strong&gt;having features&lt;/strong&gt; and &lt;strong&gt;creating a good experience&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A few things stood out:&lt;/p&gt;

&lt;h3&gt;
  
  
  Product decisions matter as much as technical ones
&lt;/h3&gt;

&lt;p&gt;It’s easy to keep adding features, but choosing what &lt;strong&gt;not&lt;/strong&gt; to add is just as important.&lt;/p&gt;

&lt;h3&gt;
  
  
  Small UX details make a huge difference
&lt;/h3&gt;

&lt;p&gt;Spacing, hierarchy, naming, and flow can completely change how “finished” a project feels.&lt;/p&gt;

&lt;h3&gt;
  
  
  Friction shows up fast in simple apps
&lt;/h3&gt;

&lt;p&gt;When the app itself is simple, every unnecessary step becomes more noticeable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Public projects feel different
&lt;/h3&gt;

&lt;p&gt;Building something you’re willing to show publicly makes you think more carefully about quality, clarity, and polish.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I’d improve next
&lt;/h2&gt;

&lt;p&gt;Like most projects, this one still has room to grow.&lt;/p&gt;

&lt;p&gt;Some things I’d like to improve or expand over time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;deeper progress insights&lt;/li&gt;
&lt;li&gt;more personalized tracking options&lt;/li&gt;
&lt;li&gt;more refinement in the user flow&lt;/li&gt;
&lt;li&gt;additional quality-of-life improvements&lt;/li&gt;
&lt;li&gt;continued UI/UX polishing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I also want to keep improving how I present and document my public work.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I’m sharing it
&lt;/h2&gt;

&lt;p&gt;I’m currently growing my public developer profile and becoming more active in open source and build-in-public style sharing.&lt;/p&gt;

&lt;p&gt;This project felt like a good first thing to share because it reflects what I enjoy most:&lt;br&gt;
building practical web apps with a strong focus on &lt;strong&gt;clean UI&lt;/strong&gt;, &lt;strong&gt;smooth UX&lt;/strong&gt;, and &lt;strong&gt;modern frontend development&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you try the app, I’d genuinely appreciate any feedback:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What feels good?&lt;/li&gt;
&lt;li&gt;What feels unclear?&lt;/li&gt;
&lt;li&gt;What would you improve?&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Live app:&lt;/strong&gt; &lt;a href="https://drink-daily.vercel.app/en" rel="noopener noreferrer"&gt;https://drink-daily.vercel.app/en&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/johnnylemonny" rel="noopener noreferrer"&gt;https://github.com/johnnylemonny&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading 👋&lt;br&gt;&lt;br&gt;
This is my first post here, so I’m excited to keep sharing more as I build.&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%2Fdf3hklgrtzb8ii7kh98b.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%2Fdf3hklgrtzb8ii7kh98b.png" alt="Screenshot of the Drink Daily app" width="800" height="1632"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
      <category>typescript</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
