<?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>Forem: Gustavo Graña</title>
    <description>The latest articles on Forem by Gustavo Graña (@devgrana).</description>
    <link>https://forem.com/devgrana</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%2F3090352%2Fccb62f42-5fe2-47e8-a97d-2e253db1e32a.jpg</url>
      <title>Forem: Gustavo Graña</title>
      <link>https://forem.com/devgrana</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/devgrana"/>
    <language>en</language>
    <item>
      <title>How AI Might Change the Freemium Model</title>
      <dc:creator>Gustavo Graña</dc:creator>
      <pubDate>Mon, 27 Oct 2025 00:41:28 +0000</pubDate>
      <link>https://forem.com/devgrana/how-ai-might-change-the-freemium-model-5am4</link>
      <guid>https://forem.com/devgrana/how-ai-might-change-the-freemium-model-5am4</guid>
      <description>&lt;p&gt;Every major wave of technology forces some kind of adaptation.&lt;br&gt;
When mobile took over, we had to rethink design and performance.&lt;br&gt;
When social media grew, we had to learn new ways to reach users.&lt;br&gt;
Now, as AI and automation become part of everyday tools and workflows, we might need to rethink something deeper: how we define a &lt;em&gt;user&lt;/em&gt; in the first place.&lt;/p&gt;




&lt;h2&gt;
  
  
  When Free Stops Being Simple
&lt;/h2&gt;

&lt;p&gt;The freemium model depends on trust — that a real person is using your product, seeing your ads, and maybe converting later. But that trust is starting to erode.&lt;br&gt;
Modern bots and AI agents can now behave like real users: signing up, clicking through, “watching” videos, or even chatting with interfaces. They’re not always malicious — sometimes they’re testing, learning, or scraping data — but they still distort what engagement actually means.&lt;/p&gt;

&lt;p&gt;If you’re running a free tier that relies on ad revenue, this becomes a hard problem. Advertisers are already skeptical about fake impressions. As AI agents flood the web, it’ll only get harder to prove that those views and clicks come from humans. The core of the freemium economy — attention as currency — becomes unstable.&lt;/p&gt;




&lt;h2&gt;
  
  
  Rethinking Trust Without Losing Privacy
&lt;/h2&gt;

&lt;p&gt;One possible path forward is validation.&lt;br&gt;
Maybe not full KYC-level verification, but lightweight ways to prove that someone behind an account is real. That could mean micro-subscriptions (a few dollars per month), or external services that verify real users across multiple platforms — something like “proof of humanity” APIs. Another idea is reputation-based systems, where long-term accounts or verified behavior carry more credibility than new anonymous ones.&lt;/p&gt;

&lt;p&gt;But any attempt at validation needs to respect &lt;strong&gt;privacy and security&lt;/strong&gt;. Asking users to share personal identity documents or sensitive data like ID numbers would introduce huge risks — leaks, impersonation, and surveillance. We can’t trade privacy for authenticity. The goal is to confirm that users are real &lt;em&gt;without revealing who they are&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;That’s why this shift shouldn’t come from governments or regulation. Governments move slowly and often focus on headlines rather than long-term privacy or security. Centralized identity systems they might propose would likely ignore privacy concerns. Instead, I believe this conversation will emerge naturally within &lt;strong&gt;the advertising and technology industries&lt;/strong&gt;, where the impact is most direct. As non-human traffic increases, ad networks and agencies will need better ways to ensure their ads reach real people — creating the market pressure that will shape how platforms and developers define what a “user” truly is.&lt;/p&gt;

&lt;p&gt;AI might push the internet toward a more verified but still private era — one where authenticity and anonymity find a new balance.&lt;br&gt;
The idea of “free” might evolve, but perhaps that’s the necessary cost of keeping trust — and privacy — alive online.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>ads</category>
      <category>freemium</category>
      <category>programming</category>
    </item>
    <item>
      <title>Avoid performance issues when using Zustand</title>
      <dc:creator>Gustavo Graña</dc:creator>
      <pubDate>Mon, 28 Apr 2025 03:10:49 +0000</pubDate>
      <link>https://forem.com/devgrana/avoid-performance-issues-when-using-zustand-12ee</link>
      <guid>https://forem.com/devgrana/avoid-performance-issues-when-using-zustand-12ee</guid>
      <description>&lt;p&gt;When using Zustand in a React app, it's important to know how your selectors are structured.&lt;/p&gt;

&lt;p&gt;Incorrect patterns can easily cause &lt;strong&gt;unnecessary re-renders&lt;/strong&gt;, hurting your app's performance, especially as your application grows.&lt;/p&gt;

&lt;p&gt;One common mistake happens because of how IDEs like VSCode autocomplete function signatures.&lt;/p&gt;

&lt;p&gt;The IDE often suggests destructuring inside the selector, leading developers to accidentally introduce new object references on every render.  &lt;/p&gt;

&lt;p&gt;This isn't just a stylistic issue — it's a &lt;strong&gt;real performance problem&lt;/strong&gt; in React's rendering model.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Common Mistake
&lt;/h2&gt;

&lt;p&gt;You might see Zustand being used like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;setMessages&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMessagesStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;setMessages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setMessages&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;At first glance, this seems reasonable:&lt;br&gt;&lt;br&gt;
You're "just" picking a value out of the store, right?&lt;br&gt;&lt;br&gt;
But this pattern causes an important problem: &lt;strong&gt;you're creating a new object every time the component renders.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;React compares selected state via shallow reference equality (&lt;code&gt;===&lt;/code&gt;).&lt;br&gt;&lt;br&gt;
Since &lt;code&gt;{ setMessages: ... }&lt;/code&gt; is a &lt;strong&gt;new object on every call&lt;/strong&gt;, Zustand thinks the selected state has changed — &lt;strong&gt;even if &lt;code&gt;setMessages&lt;/code&gt; itself did not change&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;❌ Your component re-renders unnecessarily, even though nothing meaningful has changed.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why This Matters
&lt;/h2&gt;

&lt;p&gt;In React, avoiding unnecessary re-renders is key for keeping your UI fast and responsive.&lt;br&gt;&lt;br&gt;
Every re-render means re-executing your component, re-running hooks, and possibly causing child components to re-render too.&lt;/p&gt;

&lt;p&gt;At a small scale, it might not seem like a big deal.&lt;br&gt;&lt;br&gt;
But in real-world apps, unnecessary re-renders can &lt;strong&gt;slow down the app&lt;/strong&gt;, &lt;strong&gt;waste CPU cycles&lt;/strong&gt;, and &lt;strong&gt;make UI interactions less smooth&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In short: &lt;strong&gt;don't create new object references inside your Zustand selectors unless you mean to.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The Correct Way
&lt;/h2&gt;

&lt;p&gt;Instead of returning an object, &lt;strong&gt;select the exact value you need directly&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;✅ Correct:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setMessages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMessagesStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setMessages&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way, Zustand can efficiently check if &lt;code&gt;state.setMessages&lt;/code&gt; has changed.&lt;br&gt;&lt;br&gt;
If it hasn't, your component won't re-render — exactly what you want.&lt;/p&gt;
&lt;h3&gt;
  
  
  What If You Need Multiple Values?
&lt;/h3&gt;

&lt;p&gt;Sometimes, you need to select more than one thing from the store.&lt;br&gt;&lt;br&gt;
There are two proper ways to do it:&lt;/p&gt;
&lt;h4&gt;
  
  
  1. Use multiple calls to &lt;code&gt;useMessagesStore&lt;/code&gt;
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setMessages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMessagesStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setMessages&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;messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMessagesStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Zustand allows multiple subscriptions without issue.&lt;br&gt;&lt;br&gt;
Each selector subscribes independently and will only trigger re-renders if its specific piece of state changes.&lt;/p&gt;
&lt;h4&gt;
  
  
  2. Use &lt;code&gt;useShallow&lt;/code&gt; for objects
&lt;/h4&gt;

&lt;p&gt;If you prefer grouping multiple values into a single object, you must &lt;strong&gt;explicitly use a shallow comparison&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Zustand provides a built-in &lt;code&gt;useShallow&lt;/code&gt; helper for this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&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;useShallow&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="s1"&gt;zustand/react/shallow&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;setMessages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;messages&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMessagesStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nf"&gt;useShallow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;setMessages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setMessages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&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;Here, Zustand will do a shallow comparison of the selected object keys.&lt;/p&gt;

&lt;p&gt;The component will only re-render if &lt;strong&gt;&lt;code&gt;setMessages&lt;/code&gt; or &lt;code&gt;messages&lt;/code&gt;&lt;/strong&gt; changes, not simply because the object reference is different.&lt;/p&gt;

</description>
      <category>react</category>
      <category>reactnative</category>
      <category>zustand</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Some Thoughts on AI and Creating Content</title>
      <dc:creator>Gustavo Graña</dc:creator>
      <pubDate>Fri, 25 Apr 2025 20:58:20 +0000</pubDate>
      <link>https://forem.com/devgrana/some-thoughts-on-ai-and-creating-content-3nd5</link>
      <guid>https://forem.com/devgrana/some-thoughts-on-ai-and-creating-content-3nd5</guid>
      <description>&lt;p&gt;AI has brought a lot of concerns around original content creation. I think those concerns are real and important—we should talk about them. But at the same time, AI has also made it easier for many people to create. People who might not have written, designed, or coded before now have a way to get started, and that’s a big shift.&lt;/p&gt;

&lt;p&gt;I believe that, with time, we’ll figure out the right place for AI in the creative process. Hopefully, it will become more of a helpful tool and partner—something we use in our daily work to support our ideas, not replace them.&lt;/p&gt;

&lt;p&gt;Something else I’ve been thinking about is how much content is being generated right now. AI makes it easy to produce things quickly, which is great in some ways, but it also means there’s just a lot more out there.&lt;/p&gt;

&lt;p&gt;And we shouldn't look at this only from the creator’s side. People who are trying to find good, useful, well-made content are also affected. It can get harder to discover what really stands out or feels meaningful. I think we’ll need new tools—or maybe even new roles—to help with that.&lt;/p&gt;

&lt;p&gt;I’ve been using AI a lot. It helps me review texts, organize my thoughts, and support me while I’m coding. I feel like it’s made me more productive overall. It also gives me space to focus more on the ideas themselves, instead of stressing too much about perfect grammar or typos—like with this post, which I’ve written much faster than I would have on my own.&lt;/p&gt;

&lt;p&gt;At the same time, I’ve noticed that a lot of AI-generated content can feel a bit too similar. It can be hard to find things that truly stand out. While I’m excited about where this is all going, I also hope we find the right path—a balance between efficiency and creativity, between automation and the human touch.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>creativity</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
