<?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: Playful Programming</title>
    <description>The latest articles on DEV Community by Playful Programming (playfulprogramming).</description>
    <link>https://dev.to/playfulprogramming</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F3314%2Ffd92caab-2014-431e-a19e-8ab47f2bf5ab.png</url>
      <title>DEV Community: Playful Programming</title>
      <link>https://dev.to/playfulprogramming</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/playfulprogramming"/>
    <language>en</language>
    <item>
      <title>My AI Content Journey</title>
      <dc:creator>Ryan Carniato</dc:creator>
      <pubDate>Wed, 19 Aug 2026 16:47:10 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/my-ai-content-journey-1b8p</link>
      <guid>https://dev.to/playfulprogramming/my-ai-content-journey-1b8p</guid>
      <description>&lt;p&gt;&lt;em&gt;I apologize ahead of time, what follows has no tooling applied to it. No grammar checks, no AI, and no edit passes for flow. It might be a bit rough, but that's important.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For those who know me, I've written hundreds of articles over the last 8 years. I realized very early into my journey of creating SolidJS that education was going to be a fundamental barrier. React's rhetoric had consumed the frontend space in such way that the discussion of different ideas was not welcomed warmly. It may have started with the ideas, but the complexity of the move to modern tooling had left many feeling overwhelmed. The term "JavaScript Fatigue" was being thrown around, and those who didn't sneak in before  2016 were subject to it.&lt;/p&gt;

&lt;p&gt;My early writing was rough. I mean really rough. I'd try to articulate my ideas, but they were hard to translate. It wasn't that I didn't have decent command of the English language. I always had done well in school. But the ideas I wanted to articulate extended past code examples. They borrowed from years of observations and cross discipline learning. It would take the span of a whole article for me to get my point across and it was really easy to get lost in the details.&lt;/p&gt;

&lt;p&gt;It didn't help that I wrote like I talked. Which is rather disjointed. When I used to type messages on ICQ and MSN back in the day I'd keep thumbing the "." as a way to convey to the recipient the pacing. The more "..." the longer the pause. I had needed to communicate at work, obviously and had gotten used to rewriting my emails on average three times so that I could cut out things that were unnecessary.&lt;/p&gt;

&lt;p&gt;So I published my earlier articles on Medium in 2018 and fortunately for me, the early Solid community on Gitter and Spectrum started providing me edits. This pattern of reviewing my articles with the community never went away. Most of my articles today still appear in the Solid Discord days before publishing.&lt;/p&gt;




&lt;h2&gt;
  
  
  Stepping up my Game
&lt;/h2&gt;

&lt;p&gt;At some point, a community member suggested I pick up Grammarly. Honestly, it was such a huge help. I always skipped words and commas in certain places. Given I had the free tier it would also hint when I phrased something a lot oddly so I could at least give a shot at rewriting it.&lt;/p&gt;

&lt;p&gt;This was better but honestly it fixed less than you would think. I wasn't falling into the simple traps. But the writing wasn't really anymore clear. The big break through there was when I started getting my work published through online publications. Specifically, "Angular in Depth" in 2019 time period. They were really supportive of my content but they saw that it was missing the audience.&lt;/p&gt;

&lt;p&gt;I remember at one point &lt;a class="mentioned-user" href="https://dev.to/layzee"&gt;@layzee&lt;/a&gt; sat down with me and picked through an article with me showing me how to break my writing up into more paragraphs. I was accustomed to having a paragraph express what I considered a complete idea. That meant 6-8 run-on sentences. He was like no more than 3. Give them a break to sit with what you just told them. Add spacing and images to your articles for the same reason.&lt;/p&gt;

&lt;p&gt;I didn't like this much at first because it made my articles longer. Too long as far as I thought. But it also forced me to really focus on what I wanted to say. I'd need to do one editing pass to break things up and another to eliminate the cruft.&lt;/p&gt;

&lt;p&gt;At this point, Solid was picking up steam, and there were others in the community that were interested in seeing us succeed. Some of you may not know but Theo Browne (T3.gg) reviewed many of my articles during the 2020-2022 time period. He had a lot less tolerance for sentences that didn't flow and he would go through and gut all my unnecessary phrasing. All the "And ...", "In fact", "But Honestly", "Actually..", "Simply put,". He emphasized it didn't add anything. By doing that I was able to save those for when I wanted to make a real impact.&lt;/p&gt;

&lt;p&gt;So that gives you some insight into where my writing process was through the end of 2025. I'd write something rough, do multiple passes myself, run it through Grammarly, feed it to the Solid community. Have feedback, then pass it to a few specific reviewers (although some like Theo were getting too busy to look at my work regularly). And half a dozen people and twice as many hours later we had an article.&lt;/p&gt;




&lt;h2&gt;
  
  
  Enter LLMs
&lt;/h2&gt;

&lt;p&gt;Now I never prompted an LLM intentionally before the end of 2025. As I have noted in previous articles, I was an AI laggard. Sure Gemini results would show up on a Google search. And I had dabbled with some image generation for Articles/Streams. But I did not use Chat LLMs directly at all. Funny enough, since late 2023 I had noticed two phenomena.&lt;/p&gt;

&lt;p&gt;First, absolute garbage articles quoting my work in like "Best JavaScript Frameworks to use in 2023". At first I thought these were just low effort marketing articles. Some of them probably were. But after a while I came to recognize these as AI generated.&lt;/p&gt;

&lt;p&gt;Second, people coming on to my articles and accusing them as being AI generated. My response would be, "Did you read the article?" There is no way AI makes that argument. But the general feedback was that the articles were vague because they tried to pack too much into a small space. And the move between macro and micro details was disorienting.  Ironically my trademark writing style because it was born out of necessity.&lt;/p&gt;

&lt;p&gt;I mostly pushed both of these aside. What had always mattered was the content. Those two couldn't be more obviously different. Even if I did my own yearly JavaScript summaries, any one with half a brain could tell the difference. My articles had takes that existed nowhere else and provided a deep insight.&lt;/p&gt;




&lt;h2&gt;
  
  
  Trying LLMs for Myself
&lt;/h2&gt;

&lt;p&gt;I was working on Solid 2.0. High-level design stuff late 2025 and I decided to give LLMs a try. Not for coding just to talk through the problem and see if they had an insight. I believe GPT 5.3 was out but I was just using CoPilot for free which was on 5.1. I found the process very frustrating because it kept losing details. I realized pretty quickly I needed to have it write things down.&lt;/p&gt;

&lt;p&gt;As I got more excited about formalizing these designs I got AI to write short explainers about what we had talked about so that I could share them in Discord. This was very helpful since my HackMDs I had been writing were cryptic and people could immediately understand what I was talking about this way. Maybe not deeply but the gist of it.&lt;/p&gt;

&lt;p&gt;Summaries of really high level stuff. The thing I was particularly bad at writing. It was very common in the Solid community for people to post AI written summaries on my writing since no one seemed to get what I was saying and I didn't have time to clarify while working on cutting edge things.&lt;/p&gt;

&lt;p&gt;But every time I tried to get AI to really capture the real point behind my stuff it missed. Even after moving to Cursor and frontier models. AI could write something coherent but it was never the position or argument the way I'd make it. As before it didn't have my original positioning/takes. Occasionally it would come up with something interesting like: &lt;a href="https://hackmd.io/@0u1u3zEAQAO0iYWVAStEvw/rJM9ws3Kbg" rel="noopener noreferrer"&gt;The Architecture of Temporal Determinism&lt;/a&gt;. But that was a rare occurence.&lt;/p&gt;




&lt;h2&gt;
  
  
  AI Assisted Writing
&lt;/h2&gt;

&lt;p&gt;So at some point, tired of the Yellow squigglies I was getting from Grammarly--the ones that you need to pay for that refer to structural issues--I was like why don't I feed my article to the LLM instead? And I was amazed.&lt;/p&gt;

&lt;p&gt;It took what I wrote and it sounded coherent. No initial 3 passes, no Grammarly, no community pass, no special editors. Yes I still ended up doing all of those but it was like it skipped to the finish line. There was very little feedback down the line.&lt;/p&gt;

&lt;p&gt;The part that really loved was it simultaneously made my writing shorter while bringing back that pacing I heard in my head. The old pauses. The way it used semi-colons and &lt;code&gt;--&lt;/code&gt; was exactly what I intended. No broken sentences. No confusion on flow. It just read perfectly.&lt;/p&gt;

&lt;p&gt;I was so impressed. There were a couple things I thought odd. It really liked sumarizing at the end of each section. I had a habit of connecting sections with a probing sentence for sure, but AI liked to try to tie things in a bow. And those additions were the place that I immediately cut out. Easy to see. But for the most part it was like what I had always been looking for. I'd struggled being terse and clear and it just gave it to me, in mostly my own words.&lt;/p&gt;

&lt;p&gt;I released my first article like this:&lt;/p&gt;


&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/playfulprogramming/two-react-design-choices-developers-dont-like-but-cant-avoid-d6g" class="crayons-story__hidden-navigation-link"&gt;Two React Design Choices Developers Don’t Like—But Can’t Avoid&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;
          &lt;a class="crayons-logo crayons-logo--l" href="/playfulprogramming"&gt;
            &lt;img alt="Playful Programming logo" 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%2Forganization%2Fprofile_image%2F3314%2Ffd92caab-2014-431e-a19e-8ab47f2bf5ab.png" class="crayons-logo__image" width="800" height="800"&gt;
          &lt;/a&gt;

          &lt;a href="/ryansolid" class="crayons-avatar  crayons-avatar--s absolute -right-2 -bottom-2 border-solid border-2 border-base-inverted  "&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%2F186199%2Fa3d1cfed-a1ca-41cd-a146-9db4e65711d4.jpeg" alt="ryansolid profile" class="crayons-avatar__image" width="460" height="460"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/ryansolid" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Ryan Carniato
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Ryan Carniato
                
                
              
              &lt;div id="story-author-preview-content-3344810" 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="/ryansolid" 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%2F186199%2Fa3d1cfed-a1ca-41cd-a146-9db4e65711d4.jpeg" class="crayons-avatar__image" alt="" width="460" height="460"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Ryan Carniato&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;span&gt;
              &lt;span class="crayons-story__tertiary fw-normal"&gt; for &lt;/span&gt;&lt;a href="/playfulprogramming" class="crayons-story__secondary fw-medium"&gt;Playful Programming&lt;/a&gt;
            &lt;/span&gt;
          &lt;/div&gt;
          &lt;a href="https://dev.to/playfulprogramming/two-react-design-choices-developers-dont-like-but-cant-avoid-d6g" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Mar 13&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/playfulprogramming/two-react-design-choices-developers-dont-like-but-cant-avoid-d6g" id="article-link-3344810"&gt;
          Two React Design Choices Developers Don’t Like—But Can’t Avoid
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/javascript"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;javascript&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/webdev"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;webdev&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/solidjs"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;solidjs&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/react"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;react&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/playfulprogramming/two-react-design-choices-developers-dont-like-but-cant-avoid-d6g" 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/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;94&lt;span class="hidden s:inline"&gt;&amp;nbsp;reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/playfulprogramming/two-react-design-choices-developers-dont-like-but-cant-avoid-d6g#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              42&lt;span class="hidden s:inline"&gt;&amp;nbsp;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;
            9 min read
          &lt;/small&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


&lt;p&gt;and I was pretty excited. This was an important article. It was where I was going to do the unexpected: express to the world that React, a long time competitor philosophically, was actually completely right about a few things. It was controversial. It was honest. And it needed to be clear more than anything I'd done before.&lt;/p&gt;

&lt;p&gt;In hindsight, the response should have been obvious. People couldn't get over the AI phrasings in places. That's the thing. It only takes a couple of places for the radar to go off. I had the before and after AI for this article I actually showed it on stream. I wrote every bit of the source. The things that people were accusing being AI were as much me. I thought that by taking accountability, owning it would be enough. &lt;/p&gt;

&lt;p&gt;But this kicked up a rage. And I admit I felt a bit resentful. This is critical work. From my perspective earthshaking and all people could seem to talk about was that I used AI to make the message clearer. I had been dismissed in the past for being vague or hard to follow. Now I was being dismissed for the opposite.&lt;/p&gt;

&lt;p&gt;I had also received similar feedback on using AI-generated covers. Previously, I was picking up random free images online. It took some cleverness to choose the image but it wasn't some work that I put in. AI had actually given me images suitable to my content. Again it seemed so much better to me. I'm not an artist. But somehow it wasn't acceptable. It seemed irrational to me. I put more effort in, to come up with a better result. I was clearly missing something. &lt;/p&gt;




&lt;h2&gt;
  
  
  Another Attempt
&lt;/h2&gt;

&lt;p&gt;Last week, I took that lesson and tried something a little different when we dropped the &lt;a href="https://www.solidjs.com/blog/solid-2-0-rc-the-big-reveal" rel="noopener noreferrer"&gt;Solid 2.0 RC release announcement&lt;/a&gt;. I had written release articles before but they were always tough. Short attention spans and a need to get to the point. And Solid 2.0 was proving difficult. It just had too much stuff in it. A point form list undersold it but there was no way I was going to be able to get into all the details.&lt;/p&gt;

&lt;p&gt;I had written an article showed it to AI and it had done some edits. And this time I was more careful to cleanup language. Not because I thought it was bad but because I knew it would trigger people. However, no matter what I did the article was way too long. At some point the agent suggested the obvious. Make a follow-up article series. It would summarize the some of the pieces we would be removing. And we would be set.&lt;/p&gt;

&lt;p&gt;I looked at the work and I was impressed it had kept my opening and sentimental parts and filled in the gap with the type of clear, to-the-point way that I'd expect in a release article. It was way shorter than what I had written and after a quick pass, everyone who reviewed agreed it was much more approachable. The language here was not nearly as AI-sounding because I didn't get it to really rewrite what I had written where it mattered. But obviously, even after human edits on the more marketing side there were still some traits.&lt;/p&gt;

&lt;p&gt;Again, and I imagine it was because people didn't get to the end. The response was half about the use of AI in those point form lists. The general sentiment was that it was subtle but still enough to notice. It was genuinely a better article for it, it fit the purpose of the writing. But they couldn't see past it. Most of the article had the human soul, but a few point form lists ruined it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Today
&lt;/h2&gt;

&lt;p&gt;I had an odd week. It started with seeing an &lt;a href="https://gist.github.com/aleclarson/0f4266d63fd83c7a5ea5512441bbea0c" rel="noopener noreferrer"&gt;AI Gist comparing Solid 2.0 to Octane&lt;/a&gt;. I saw that Dominic had responded with some agent-assisted prose, and I knew there was no way I was going to keep up with that discussion while pushing forward all the post-release things I needed to do without doing the same. We literally had the Agents arguing our points. You can tell they are our points. Our fundamental positioning, but it isn't our voice.&lt;/p&gt;

&lt;p&gt;But the most warmly genuine thing happens at the end. We both remove the Agent and have a real discussion. I think we both realized how ridiculous it had become.&lt;/p&gt;

&lt;p&gt;Now, the problem is that it isn't too far from how we are working today. When I have an agent review and issue or PR even if I'm driving it, reviewing the changes, and setting the response, it no longer sounds like me. It's easy to justify the reasoning.&lt;/p&gt;

&lt;p&gt;Look at how many open issues/PRs are on &lt;a href="https://github.com/solidjs/solid" rel="noopener noreferrer"&gt;SolidJS&lt;/a&gt; right now. There is no way we could be as responsive without it. We've almost closed out every issue. That is between issue submitters using agent-guided PRs and from our own agent work. But a certain human aspect is gone. I used to go on every PR and write a thank you note personally and I know I haven't done that as much the last couple months. I can justify it, but there is a human cost.&lt;/p&gt;

&lt;p&gt;I'm also about to release another article. I'm trying yet another approach to this. Where I write it, feed it to AI, but never let AI edit the actual article. When it identifies something that it rewrites, I take that as a sign my writing isn't the best there and read what the AI wrote, then minimize the window and write back the structure myself using my own voice. We'll see if this lands better.&lt;/p&gt;

&lt;p&gt;It's tricky because I can already hear LLMism in my own writing. According to critics, I was already pretty close years ago. And if I already think it sounds better than what I write I have a bias. But it's the most honest thing I can do to produce good content. And I mean good content. Not whatever this is. So I'm going to try again. I'm still figuring this out.&lt;/p&gt;

&lt;p&gt;That's all we can keep doing.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>devjournal</category>
    </item>
    <item>
      <title>Functional languages are heavily imperative.</title>
      <dc:creator>Mike Pearson</dc:creator>
      <pubDate>Mon, 17 Aug 2026 07:39:18 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/functional-languages-are-heavily-imperative-4c1</link>
      <guid>https://dev.to/playfulprogramming/functional-languages-are-heavily-imperative-4c1</guid>
      <description>&lt;p&gt;This article will seem full of contradictions.&lt;/p&gt;

&lt;p&gt;Even writing it feels like a contradiction: Why am I digging through academic Haskell papers from the '90s right in the middle of my AI psychosis moment? Literally, as I write this, I am running my first experiment with an agent delegating tasks to another agent. So why am I spending time on esoteric academic nonsense instead of giving in to the vibes and building my loopy graphy software factory?&lt;/p&gt;

&lt;p&gt;I am writing this because AI is a nuclear amplifier on the patterns we establish in our codebases, and we literally do not have the right terminology to establish scalable patterns. Nobody has the answers we need because nobody even has the right terminology to talk about it. &lt;/p&gt;

&lt;h2&gt;
  
  
  Two Dimensions, Not One
&lt;/h2&gt;

&lt;p&gt;Industry dogma says that functional and declarative are synonyms—that code is either side-effectful &lt;em&gt;and&lt;/em&gt; imperative, or pure &lt;em&gt;and&lt;/em&gt; declarative:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7durxsp38qjbtmu9xxel.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7durxsp38qjbtmu9xxel.png" alt="Functional - imperative_declarative_binary.svg" width="800" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But functional and declarative are independent dimensions:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi8on4tbfkddhezidq8oq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi8on4tbfkddhezidq8oq.png" alt="good_quadrants_horizontal_left_labels_gap_tuned.svg" width="800" height="619"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Code that is both functional and imperative debunks this, and so does code that is both side-effectful and declarative.&lt;/p&gt;

&lt;p&gt;Both exist!&lt;/p&gt;

&lt;h2&gt;
  
  
  "Imperative Functional Programming"
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm1ti1r4jqetdlqwb17so.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm1ti1r4jqetdlqwb17so.png" alt="quadrants_tl_br_questions_other_three_70pct_transparent.svg" width="800" height="617"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Simon L Peyton Jones and Philip Wadler helped create Haskell, which is a beautiful, pure functional programming language.&lt;/p&gt;

&lt;p&gt;In 1993 they wrote a paper called &lt;a href="https://dl.acm.org/doi/epdf/10.1145/158511.158524" rel="noopener noreferrer"&gt;"Imperative Functional Programming."&lt;/a&gt; The title may sound like an oxymoron, but it isn't. &lt;/p&gt;

&lt;p&gt;The functional programming community had been struggling with how to manage side-effects like I/O, and these co-creators of Haskell proposed a way to decouple the &lt;em&gt;expression&lt;/em&gt; of I/O commands from their &lt;em&gt;execution&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;But they noticed something:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It will not have escaped the reader’s notice that programs written in the monadic style look rather similar to imperative programs. For example, the echo program in C:&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;loop:&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;eof&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;putchar&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;goto&lt;/span&gt; &lt;span class="n"&gt;loop&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;In Haskell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;IO&lt;/span&gt; &lt;span class="nb"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getcIO&lt;/span&gt; &lt;span class="n"&gt;'bindI0'&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="kr"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;eof&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kr"&gt;then&lt;/span&gt;
        &lt;span class="n"&gt;doneIO&lt;/span&gt;
    &lt;span class="kr"&gt;else&lt;/span&gt; &lt;span class="n"&gt;putcI0&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;'seqI0'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Does the monadic style force one, in effect, to write a functional facsimile of an imperative program, thereby losing any advantages of writing in x functional language?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Nope! Jones and Wadler list two advantages that remain:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;List operations (like &lt;code&gt;map&lt;/code&gt;and  &lt;code&gt;append&lt;/code&gt;) can still operate on monadic commands&lt;/li&gt;
&lt;li&gt;Effects can be expressed without immediately executing them. "It's a bit like being able to define your own control structures in an imperative language."&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Recognizing the imperative structure of the Haskell monadic pattern does not mean we have to abandon the advantages that are &lt;em&gt;inherent&lt;/em&gt; in pure functional programming.&lt;/p&gt;

&lt;p&gt;But it &lt;em&gt;is&lt;/em&gt; still imperative structure. &lt;/p&gt;

&lt;h3&gt;
  
  
  "Lazy Imperative Programming"
&lt;/h3&gt;

&lt;p&gt;John Launchbury, another creator of Haskell, wrote a paper the following year called &lt;a href="https://www.researchgate.net/publication/2248360_Lazy_Imperative_Programming" rel="noopener noreferrer"&gt;Lazy Imperative Programming.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In it he says,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Imperative features were introduced to Glasgow Haskell for expressing input and output.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Could this be plainer? Haskell has imperative features. &lt;/p&gt;

&lt;p&gt;And the Haskell code that uses them is imperative. Also from his paper, an "Imperative Scan Left":&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9tecj6o9rjt7h7g2zfg1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9tecj6o9rjt7h7g2zfg1.png" alt="Haskell - John Launchbury - Imperative Scan Left - Pasted image 20260811005543.png" width="799" height="277"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;writeVar&lt;/code&gt; is an imperative statement, which is why this is an example of imperative code—written entirely with pure functions!!!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.researchgate.net/publication/2248360_Lazy_Imperative_Programming" rel="noopener noreferrer"&gt;The paper&lt;/a&gt; has many other references to imperative stuff, including this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In a strict imperative framework such as the IO monad (and most imperative languages), no value could be returned until the whole of the list was traversed. Using lazy sequences, however, this is not the case. If only the head of the list is required then very little of the computation is performed: the variable is allocated and initialised, it is read, and the list returned with that value in the head. If even less is required, merely whether the final list is empty for example, then the variable is not even allocated as only xs needs to be examined in order to give the structure of ys.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;🤯&lt;br&gt;
This is insanely cool.&lt;/p&gt;

&lt;p&gt;Again, not everything in Haskell &lt;em&gt;has&lt;/em&gt; to be declarative for it to still allow for incredible &lt;em&gt;execution&lt;/em&gt; properties!&lt;/p&gt;
&lt;h3&gt;
  
  
  The "Imperative Feel" of Concurrent Haskell
&lt;/h3&gt;

&lt;p&gt;Paul Hudak (another creator of Haskell) and Conal Elliot wrote &lt;a href="https://dl.acm.org/doi/pdf/10.1145/258948.258973" rel="noopener noreferrer"&gt;a paper&lt;/a&gt; in 1997 where they weren't happy with the "strongly imperative feel" of Concurrent Haskell—even though it was 100% purely functional.&lt;/p&gt;

&lt;p&gt;(Side note: I owe my passion for programming to this paper. More on that later.)&lt;/p&gt;

&lt;p&gt;Here's an example of what that pure functional approach with an "strongly imperative feel" looked like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;box&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;newEmptyMVar&lt;/span&gt;

&lt;span class="n"&gt;forkIO&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="kr"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;threadDelay&lt;/span&gt; &lt;span class="mi"&gt;1000000&lt;/span&gt;
  &lt;span class="n"&gt;putMVar&lt;/span&gt; &lt;span class="n"&gt;box&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;

&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;takeMVar&lt;/span&gt; &lt;span class="n"&gt;box&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;puTMVar box 42&lt;/code&gt; expresses a command to set &lt;code&gt;box&lt;/code&gt;'s value to 42. &lt;/p&gt;

&lt;p&gt;In the authors' own words,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;While this system is purely functional in the technical sense, its semantics has a strongly imperative feel&lt;/strong&gt;. That is, expressions are evaluated without side-effects to yield concurrent, imperative computations, which are executed to perform the &lt;strong&gt;implied side effects&lt;/strong&gt;. In contrast, modeling entire behaviors as implicitly concurrent functions of continuous time yields what we consider &lt;strong&gt;a more declarative feel&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is not a coincidence that the definition of "imperative" in English is "expresses a command" and that a line of code that literally "expresses a command" had an "strongly imperative feel"—even in Haskell.&lt;/p&gt;

&lt;p&gt;But the authors were dissatisfied with that "imperative feel"—so they invented functional reactive programming (FRP):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;box&lt;/span&gt; &lt;span class="n"&gt;t0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;&lt;span class="n"&gt;untilB&lt;/span&gt;&lt;span class="p"&gt;`&lt;/span&gt;
    &lt;span class="n"&gt;predicate&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=*&lt;/span&gt; &lt;span class="n"&gt;t0&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;t0&lt;/span&gt;
      &lt;span class="o"&gt;-=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just a single declaration. Nothing here expresses a command at all. &lt;code&gt;putMVar&lt;/code&gt; is 100% imperative, while this is 100% declarative and 0% imperative.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;
  Note on "more declarative" and monoparadigmatic dogma
  &lt;h4&gt;
  
  
  Note on "more declarative" and monoparadigmatic dogma
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;Since the industry dogma in the 1990s was "functional = declarative", they had to call FRP &lt;strong&gt;more declarative&lt;/strong&gt;. Concurrent Haskell was already declarative, supposedly, by virtue of being in Haskell—so this had to be &lt;em&gt;extra&lt;/em&gt; declarative 🤷&lt;/p&gt;

&lt;p&gt;And I say that with great admiration for these authors, because I owe my passion for programming to this paper. This was the origin of both RxJS and signals, which I love... very much. Too much for many people.&lt;/p&gt;

&lt;p&gt;The "Lazy Imperative Programming" paper was more contradictory. The author often contrasted Haskell with "imperative languages," while dozens of times referring to features &lt;em&gt;within&lt;/em&gt; Haskell as imperative. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;On the one hand, functional languages are commonly more expressive and easier to reason about than imperative languages,&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After reading 20 or so papers from the 1990s talking about programming paradigms, you will understand that the terminology was extremely entrenched. Academics classified programming languages into rigid categories to help explain the programming patterns of the time.&lt;/p&gt;

&lt;p&gt;Functional programmers were especially guilty of reinforcing this reductionism, since they were a minority of programmers and had to fight against the grain with every rhetorical tool they could. Branding functional programming languages as automatically 100% declarative was an enticing selling point—even though we have many Haskell creators very plainly referring to features &lt;em&gt;within&lt;/em&gt; Haskell as imperative.&lt;/p&gt;

&lt;p&gt;Also, in the 1990s very few "imperative languages" had added much functional features, having not had to deal with much concurrent processing yet, which meant languages really did mostly fall into neat categories; multi-paradigmatic languages were not the norm like they are now. The concept of entire languages as "imperative" or "declarative" somewhat applied back then, but today is a nothing but a leftover from decades of synchronous code that all matched the same 2-3 structural patterns.&lt;/p&gt;

&lt;p&gt;We have to make a mental note of this history, but if we do not push to correct the terminology, it will continue to confuse developers and AI. Many developers think that stuffing imperative features between &lt;code&gt;&amp;lt; &amp;gt;&lt;/code&gt; characters magically makes them declarative because it's part of HTML, a "declarative language." Some are attempting this and creating masses of spaghetti code that only cosmetically looks different from the imperative JavaScript spaghetti they were writing last year.&lt;/p&gt;

&lt;p&gt;There are no "declarative languages" and "imperative languages", as much as it would simplify selling them. There are commands expressed in code, which are &lt;strong&gt;imperative&lt;/strong&gt; by the purest definition; and there are features and behaviors &lt;strong&gt;declared&lt;/strong&gt; without scattered commands controlling them from elsewhere.&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;
&lt;br&gt;
&lt;br&gt;
&lt;p&gt;&lt;/p&gt;
&lt;br&gt;


&lt;h3&gt;
  
  
  Conclusion (Imperative Functional Programming)
&lt;/h3&gt;

&lt;p&gt;The literal precise English definition of "imperative" is something that expresses a command. That is what these pure functions are doing in Haskell and other functional languages. This should already rest the argument.&lt;/p&gt;

&lt;p&gt;But even the less precise definitions of imperative programming focus on &lt;strong&gt;structural descriptions written in code&lt;/strong&gt; rather than execution details:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Imperative programming involves &lt;strong&gt;writing programs as sequences of explicit commands&lt;/strong&gt; that are executed in order from top to bottom." &lt;a href="https://builtin.com/articles/imperative-programming" rel="noopener noreferrer"&gt;https://builtin.com/articles/imperative-programming&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;"logic &lt;strong&gt;encoded&lt;/strong&gt; as a sequence of ordered operations" &lt;a href="https://en.wikipedia.org/wiki/Programming_language" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Programming_language&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;"Imperative programming &lt;strong&gt;focuses on describing&lt;/strong&gt; how a program operates step by step, rather than on high-level &lt;strong&gt;descriptions&lt;/strong&gt; of its expected results" &lt;a href="https://en.wikipedia.org/w/index.php?title=Imperative_programming" rel="noopener noreferrer"&gt;https://en.wikipedia.org/w/index.php?title=Imperative_programming&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;"With an imperative approach, a developer &lt;strong&gt;writes code that specifies the steps&lt;/strong&gt; that the computer must take to accomplish the goal." &lt;a href="https://learn.microsoft.com/en-us/dotnet/standard/linq/functional-vs-imperative-programming" rel="noopener noreferrer"&gt;https://learn.microsoft.com/en-us/dotnet/standard/linq/functional-vs-imperative-programming&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;"Im­per­a­tive pro­gram­ming languages are &lt;strong&gt;composed of step-by-step in­struc­tions (how)&lt;/strong&gt;... By contrast, in de­clar­a­tive pro­gram­ming, the desired result (what) is &lt;strong&gt;described&lt;/strong&gt; directly." &lt;a href="https://www.ionos.com/digitalguide/websites/web-development/imperative-programming/" rel="noopener noreferrer"&gt;https://www.ionos.com/digitalguide/websites/web-development/imperative-programming/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Imperative programming is a paradigm where you &lt;strong&gt;explicitly state&lt;/strong&gt; how the program should achieve the desired result. &lt;a href="https://octopus.com/devops/infrastructure-as-code/declarative-vs-imperative-programming/" rel="noopener noreferrer"&gt;https://octopus.com/devops/infrastructure-as-code/declarative-vs-imperative-programming/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's very clear that Haskell and functional programming languages are extremely cool with the flexibility they afford for all kinds of things, including the execution of side effects.&lt;/p&gt;

&lt;p&gt;But Haskell has features that enable writing literal imperative commands even with pure functions. This results in code that is structured imperatively: Explicit commands incrementally adding to behavior described elsewhere. The instant a single command appears, it completely takes away the declarative quality of describing the final result of something up-front. The imperative features of Haskell are not just &lt;em&gt;less&lt;/em&gt; declarative; they are completely anti-declarative.&lt;/p&gt;

&lt;p&gt;Functional programming &lt;em&gt;can&lt;/em&gt; be imperative.&lt;/p&gt;

&lt;h2&gt;
  
  
  Declarative Side-Effects
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fae9pvmixf8vw5k9gb2jt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fae9pvmixf8vw5k9gb2jt.png" alt="quadrants_only_br_opaque_br_question.svg" width="800" height="616"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  RxJS
&lt;/h3&gt;

&lt;p&gt;RxJS enables fully declarative code, despite latent side-effects.&lt;/p&gt;

&lt;p&gt;RxJS actually came from that Fran paper we looked at earlier, which proposed a way to turn this kind of Concurrent Haskell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;box&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;newEmptyMVar&lt;/span&gt;

&lt;span class="n"&gt;forkIO&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="kr"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;threadDelay&lt;/span&gt; &lt;span class="mi"&gt;1000000&lt;/span&gt;
  &lt;span class="n"&gt;putMVar&lt;/span&gt; &lt;span class="n"&gt;box&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;

&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;takeMVar&lt;/span&gt; &lt;span class="n"&gt;box&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;into this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;box&lt;/span&gt; &lt;span class="n"&gt;t0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;&lt;span class="n"&gt;untilB&lt;/span&gt;&lt;span class="p"&gt;`&lt;/span&gt;
    &lt;span class="n"&gt;predicate&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=*&lt;/span&gt; &lt;span class="n"&gt;t0&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;t0&lt;/span&gt;
      &lt;span class="o"&gt;-=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neither of these trigger side-effects, but the declarative version structures the code as a single description of a complete, final logical result (a behavior over time). The thing that made the first imperative and the second declarative is the &lt;em&gt;structure&lt;/em&gt; of the code, not the side-effect execution model. &lt;/p&gt;

&lt;p&gt;The same structural move can be made in side-effectful code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;withResolvers&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1000&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;lastValueFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nf"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;42&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;Both of these trigger side-effects when executed, but the declarative version structures the code as a single description of a complete, final logical result. The thing that made the first imperative and the second declarative is the &lt;em&gt;structure&lt;/em&gt; of the code, not the side-effect execution model. &lt;/p&gt;

&lt;p&gt;These four code snippets alone are enough to complete our four quadrants:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5wsk1y18dfeav7hbx88o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5wsk1y18dfeav7hbx88o.png" alt="good_quadrants_large_labels_no_axes_even_offset_code_centered_with_titles_rxjs_2021.svg" width="800" height="796"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But let's look at some more common declarative side-effects.&lt;/p&gt;

&lt;h3&gt;
  
  
  HTML
&lt;/h3&gt;

&lt;p&gt;"HTML is declarative" is often said. And it's mostly true (see above callout "Note on "more declarative" and monoparadigmatic dogma").&lt;/p&gt;

&lt;p&gt;Yet the entire point of HTML is a side-effect: You being able to look at beautiful interfaces like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F13yt6viayccxy1mkr6k1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F13yt6viayccxy1mkr6k1.png" alt="Old Webpage" width="800" height="601"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's not just the DOM that's a side effect though. The HTML rendered in the page can itself trigger other kinds of side effects, like network calls:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- ... --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://storage.googleapis.com/blog-images-backup/1*tY3o3UFtBaMQ103en48qxA.png"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;iframe&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://www.youtube.com/embed/dQw4w9WgXcQ"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Nondeterministic Declarations
&lt;/h3&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;Math.random&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;Math.random()&lt;/code&gt; technically produces a side effect because it relies on and mutates a hidden global internal state (the seed or PRNG algorithm pointer) inside the runtime environment to generate its next value.&lt;/p&gt;

&lt;p&gt;But this is still totally declarative:&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;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;code&gt;Date.now()&lt;/code&gt;, &lt;code&gt;crypto.randomUUID()&lt;/code&gt;, &lt;code&gt;process.memoryUsage()&lt;/code&gt;, etc...
&lt;/h4&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;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&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;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&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;perfNow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&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;randomBytes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRandomValues&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Uint32Array&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;uuid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;randomUUID&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;hrtime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hrtime&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;uptime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;uptime&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;memoryUsage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;memoryUsage&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;freeMemory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freemem&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;battery&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBattery&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;windowWidth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerWidth&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;visibility&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;visibilityState&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;online&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onLine&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All of these are completely declarative. They are declarations of final results, and no subsequent step-by-step (or any) imperative code is involved.&lt;/p&gt;

&lt;p&gt;But they are not pure functions. They don't have side effects, but they have side causes, so they still are not functional. So while they aren't examples of declarative code that causes side effects, they are examples of declarative code that break rules of functional programming, showing that these are independent dimensions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Declarative "Pure" Functions with Side-Effects
&lt;/h3&gt;

&lt;h4&gt;
  
  
  CPU
&lt;/h4&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;fib&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;fib&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;fib&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;2&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;fib&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything here looks pure as the driven snow, and it's definitely declarative.&lt;/p&gt;

&lt;p&gt;No side effects at all, right?&lt;/p&gt;

&lt;p&gt;In fact, it triggers 40,730,022,147 calls, which means that its side effects are so severe that I really don't recommend pasting that into dev tools and running it. You think jQuery has interesting side effects by reaching into the DOM and changing the behavior of random things, but this will change the behavior of everything on the page. Namely, it eliminates it because it locks up the CPU. &lt;/p&gt;

&lt;h4&gt;
  
  
  Memory
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No side effects here, right? It's declarative, at least.&lt;/p&gt;

&lt;p&gt;However, this might get compiled into assembly code that looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mov     rdi, 8589934592
call    malloc

mov     rcx, 1073741824
mov     rdi, rax
xor     eax, eax
rep stosq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is a huge side-effect in this code: &lt;code&gt;call malloc&lt;/code&gt; requests &lt;code&gt;8589934592&lt;/code&gt; = (2 ** 30) × 8 bytes = 1,073,741,824 × 8 bytes ≈ &lt;strong&gt;8 GiB&lt;/strong&gt; of memory.&lt;/p&gt;

&lt;p&gt;There may be guardrails against creating arrays this big. I didn't feel like testing it. But there is a variation that may not be prevented:&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="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="nx"&gt;_000_000&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This time each inner array has only 1 million elements, but there are 1000 of them, so 1,000,000,000 total elements.&lt;/p&gt;

&lt;p&gt;Here are some possible side-effects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The page or Node.js process becomes unresponsive while the runtime tries to allocate and initialize the array&lt;/li&gt;
&lt;li&gt;In a severe case, the browser tab crashes because it exceeds its memory limit.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And yet, it's still declarative.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion (Declarative Side-Effects)
&lt;/h3&gt;

&lt;p&gt;Declarative and functional are not synonyms. Declarative code is about &lt;em&gt;how a computation is structured&lt;/em&gt;: describing a result rather than spelling out a sequence of commands to get there.&lt;/p&gt;

&lt;p&gt;Functional purity is about &lt;em&gt;what that computation depends on and affects&lt;/em&gt;. A declaration can trigger network requests, consume CPU and memory, observe clocks and runtime state, or depend on hidden mutable state without becoming imperative.&lt;/p&gt;

&lt;p&gt;These are separate dimensions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The point of separating these dimensions is not to win a pointless terminology argument. It is to make better engineering decisions while AI is applying incredible pressure on our architectural patterns.&lt;/p&gt;

&lt;p&gt;If we collapse &lt;strong&gt;functional&lt;/strong&gt; into &lt;strong&gt;declarative&lt;/strong&gt;, we lose the ability to talk precisely about what code is doing. Pure code can still be structured imperatively. Declarative code can still observe mutable state, trigger I/O, allocate absurd amounts of memory, or otherwise affect the world.&lt;/p&gt;

&lt;p&gt;Structure and purity are independent properties of code that sometimes align, but &lt;em&gt;DO NOT HAVE TO&lt;/em&gt;!&lt;/p&gt;

&lt;p&gt;If the problem is hidden state, surprising effects, or difficulty reasoning about dependencies, functional programming can help with its explicit inputs, immutable values, pure transformations, effect isolation. And although I love functional programming, in my experience, most apps genuinely will never see significant consequences for not being purely functional. &lt;/p&gt;

&lt;p&gt;However, most apps I have seen have suffered severely from being imperative: It always scatters control, with commands reaching across a system (spaghetti code), or behavior that can only be understood by mentally executing twenty steps across multiple contexts. Declarative code fixes this. Functional programming does not.&lt;/p&gt;

&lt;p&gt;I am sick of saying I like declarative code and being told to juST UsE ELm or HASkElL.&lt;/p&gt;

&lt;p&gt;People can't even understand the problem because they don't have the words to discuss it properly.&lt;/p&gt;

&lt;p&gt;Now throw AI into this cross-talking mix of contradictions, and this is what we can expect:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fljikqwosmna3pdofj63o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fljikqwosmna3pdofj63o.png" alt="Spaghetti Nuclear Explosion.png" width="800" height="641"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This looks delicious, but can we please try to avoid it anyway?&lt;/p&gt;

&lt;p&gt;Let's fix our vocabulary so we can learn real things about imperative code and &lt;a href="https://dev.to/playfulprogramming/5-reasons-to-avoid-imperative-code-e09"&gt;steer humans and AI away from it.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>imperative</category>
      <category>declarative</category>
      <category>haskell</category>
    </item>
    <item>
      <title>OpenRouter: One API Key to Rule Them All 🔑</title>
      <dc:creator>Domenico Tenace</dc:creator>
      <pubDate>Wed, 12 Aug 2026 07:20:51 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/openrouter-one-api-key-to-rule-them-all-304b</link>
      <guid>https://dev.to/playfulprogramming/openrouter-one-api-key-to-rule-them-all-304b</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;Hey everyone 👋&lt;/p&gt;

&lt;p&gt;Managing AI models in 2026 has gotten ridiculous. Anthropic key here, OpenAI key there, a separate billing account for Google, another for Mistral, and if you want to try DeepSeek you're adding yet another dashboard to the pile. It's chaos.&lt;/p&gt;

&lt;p&gt;OpenRouter fixes this. One API key, one credit balance, 300+ models. I've been using it as the backbone of my AI setup for a while now, and recently I wired it directly into OpenCode, which made the whole workflow click into place.&lt;/p&gt;

&lt;p&gt;Let me explain how it all works. Let's dive in! 🤙&lt;/p&gt;




&lt;h2&gt;
  
  
  What Is OpenRouter? 🤔
&lt;/h2&gt;

&lt;p&gt;OpenRouter is a unified API gateway that sits between your application and the underlying LLM providers. You send a request to OpenRouter, it forwards it to the model you specified, and returns the response in a normalized OpenAI-compatible format.&lt;/p&gt;

&lt;p&gt;The catalog currently covers 300+ models from every major provider: Anthropic, OpenAI, Google, Meta, Mistral, xAI, DeepSeek, Qwen, NVIDIA, and dozens of smaller ones. You switch models by changing a single parameter in your request. No code changes, no new integrations, no new billing accounts.&lt;/p&gt;

&lt;p&gt;It's also OpenAI SDK-compatible, which means if you're already using the OpenAI client in your code, you change the base URL and the API key, and everything else works unchanged.&lt;/p&gt;




&lt;h2&gt;
  
  
  How It Works 🔧
&lt;/h2&gt;

&lt;p&gt;The setup is three steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create a free account at openrouter.ai&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add credits via credit card or crypto (no minimum purchase, no expiration)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Generate an API key and use it across all your tools&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;From that point on, switching models is just changing a string. If you were calling Claude Sonnet directly through Anthropic and want to test Gemini Flash or DeepSeek for the same task, you change one line. That's it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Provider Routing and Fallbacks
&lt;/h3&gt;

&lt;p&gt;One of OpenRouter's strongest practical features is automatic provider fallback. Many popular models are served by multiple infrastructure providers. If one returns an error or hits capacity, OpenRouter silently routes to an alternative and your request succeeds. You don't write retry logic for this, it just works.&lt;/p&gt;

&lt;p&gt;There's also an auto-router mode: set the model to &lt;code&gt;openrouter/free&lt;/code&gt; and OpenRouter selects the best available free model for your request based on what it needs, structured output, tool calling, image understanding, and so on.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Free Tier
&lt;/h3&gt;

&lt;p&gt;OpenRouter offers around 29 free models at any given time, including Llama 3, Gemma 4, DeepSeek Flash, Qwen3, and others. Free accounts get 50 requests per day without adding credits, and 1,000 per day after a first top-up.&lt;/p&gt;

&lt;p&gt;The free model lineup shifts as providers change their policies, so treat it as a useful resource for prototyping, not a guaranteed production tier.&lt;/p&gt;




&lt;h2&gt;
  
  
  Pricing: What You Actually Pay 💰
&lt;/h2&gt;

&lt;p&gt;This changed significantly in 2025. OpenRouter used to add per-token markups on top of provider pricing. That model is gone.&lt;/p&gt;

&lt;p&gt;The current structure is straightforward: a flat 5.5% fee on credit purchases, and provider token prices passed through at cost. So if Claude Sonnet 4.6 is $3/$15 per million tokens at Anthropic, you pay $3/$15 on OpenRouter. The only overhead is the 5.5% you paid when you loaded credits.&lt;/p&gt;

&lt;p&gt;The one additional charge: if you bring your own provider API keys (BYOK) and exceed 1 million requests per month, there's a 5% fee on usage beyond that threshold. Below 1M requests it's free to route through your own keys.&lt;/p&gt;

&lt;p&gt;To put it concretely: loading $100 in credits costs $105.50. Everything you buy with those credits is at direct provider rates.&lt;/p&gt;

&lt;p&gt;For hobbyists and developers running multiple models, this is genuinely competitive. For enterprises burning millions of tokens per day, negotiated direct rates might beat it, but you'd have to be at serious scale.&lt;/p&gt;




&lt;h2&gt;
  
  
  OpenRouter + OpenCode 🔗
&lt;/h2&gt;

&lt;p&gt;This is the combination I've been running, and it's become my default setup.&lt;/p&gt;

&lt;p&gt;OpenCode supports any OpenAI-compatible endpoint, which OpenRouter is. You point OpenCode at OpenRouter, set your API key, and from that moment you can use any model in OpenCode's model selector without managing separate credentials for each provider.&lt;/p&gt;

&lt;p&gt;The practical benefit is flexibility without friction. When I want to try Qwen3 Coder for a refactoring task, I switch the model in OpenCode. When I need Claude Opus for something that requires stronger reasoning, I switch back. One balance covers everything.&lt;/p&gt;

&lt;p&gt;It also means I'm not locked into any single provider's availability. If Anthropic has downtime, I route through Gemini or DeepSeek without touching my workflow. OpenRouter's provider fallback does the heavy lifting.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Pros 👍
&lt;/h2&gt;

&lt;p&gt;One API key and one billing account replace every separate provider integration you'd otherwise manage. For teams or individual developers using more than two models regularly, that alone justifies the overhead.&lt;/p&gt;

&lt;p&gt;The OpenAI-compatible API means zero migration cost if you're already using the OpenAI SDK. Change the base URL, change the key, done.&lt;/p&gt;

&lt;p&gt;Provider fallback is genuinely useful in production. You stop worrying about individual provider outages because OpenRouter handles the retry layer for you.&lt;/p&gt;

&lt;p&gt;The free model catalog gives you a real prototyping environment at zero cost. Qwen3 Coder Free and DeepSeek Flash Free are capable enough for a lot of development tasks.&lt;/p&gt;

&lt;p&gt;Transparent pricing with no hidden per-token markups. The 5.5% credit fee is upfront and easy to account for.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Cons 👎
&lt;/h2&gt;

&lt;p&gt;The 5.5% credit fee is real money at scale. If you're running high-volume production workloads, that overhead adds up. Direct provider APIs will be cheaper once you're large enough to negotiate rates.&lt;/p&gt;

&lt;p&gt;Credits don't expire, but they also aren't refundable. You're committing capital upfront even if your usage patterns shift.&lt;/p&gt;

&lt;p&gt;Free model availability is unstable. Providers can remove free-tier access at any time and OpenRouter has no control over it. Don't build a production workflow that depends on a specific free model being there next month.&lt;/p&gt;

&lt;p&gt;Enterprise teams needing RBAC, per-team budgets, audit logs, and VPC-native routing will hit a ceiling. OpenRouter is primarily a routing and billing layer, not a governance platform. For stricter compliance needs, something like LiteLLM self-hosted or Portkey might be more appropriate.&lt;/p&gt;

&lt;p&gt;The auto-router mode (&lt;code&gt;openrouter/free&lt;/code&gt;) is convenient, but the model selection varies between requests. If you need consistent output style across sessions, pin a specific model ID instead.&lt;/p&gt;




&lt;h2&gt;
  
  
  Who Should Use OpenRouter? 🎯
&lt;/h2&gt;

&lt;p&gt;OpenRouter is the obvious choice if you're using more than one or two AI models regularly and don't want to manage the overhead of multiple accounts and billing setups. For individual developers, it removes a real operational annoyance.&lt;/p&gt;

&lt;p&gt;It's also the right call for tools like OpenCode that support BYOK or custom endpoints but don't manage multi-provider routing themselves. OpenRouter becomes the infrastructure layer your tool sits on top of.&lt;/p&gt;

&lt;p&gt;Where it makes less sense: pure Anthropic shops that only need Claude, or enterprises with compliance requirements that need on-premise routing and audit trails. For those cases, the flexibility isn't worth the trade-offs.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts 🌟
&lt;/h2&gt;

&lt;p&gt;OpenRouter started as a scrappy model aggregator with 30 models. In 2026 it's become the most important middleware layer in the independent developer's AI stack, and the pricing reform that eliminated per-token markups made it significantly more honest to use.&lt;/p&gt;

&lt;p&gt;The combination with OpenCode is what made it click for me. Instead of managing Anthropic and Google credentials separately, I load credits into OpenRouter once and switch models from OpenCode's interface as needed. It's the kind of setup that removes decisions you don't want to be making mid-task.&lt;/p&gt;

&lt;p&gt;One key, one balance, hundreds of models. For how messy the provider landscape has gotten, that's a genuinely useful simplification.&lt;/p&gt;

&lt;p&gt;Happy coding! ✨&lt;/p&gt;




&lt;p&gt;Hi 👋🏻&lt;br&gt;&lt;br&gt;
My name is Domenico, software developer passionate of Open Source, I write article about it for share my knowledge and experience.&lt;br&gt;&lt;br&gt;
Don't forget to visit my social links to discover my links and to check out Domenico Tenace Open Labs for my open-source projects! 🫰🏻&lt;/p&gt;

&lt;p&gt;🌲 Links: &lt;a href="https://links.domenicotenace.dev/" rel="noopener noreferrer"&gt;https://links.domenicotenace.dev/&lt;/a&gt;&lt;br&gt;&lt;br&gt;
🐙 Domenico Tenace Open Labs: &lt;a href="https://github.com/Domenico-Tenace-Open-Labs" rel="noopener noreferrer"&gt;https://github.com/Domenico-Tenace-Open-Labs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you like my content or want to support my work, you can support me with a small donation. I would be grateful 🥹&lt;/p&gt;

&lt;p&gt;☕ Buy me a Coffee: &lt;a href="https://buymeacoffee.com/domenicotenace" rel="noopener noreferrer"&gt;https://buymeacoffee.com/domenicotenace&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://zyvop.com/openrouter-one-api-key-to-rule-them-all-917xc" rel="noopener noreferrer"&gt;ZyVOP&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;💡 For more articles like this, &lt;a href="https://zyvop.com/newsletter" rel="noopener noreferrer"&gt;subscribe to the ZyVOP newsletter&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>machinelearning</category>
      <category>developers</category>
    </item>
    <item>
      <title>OpenCode: The Open Source Coding Agent That Doesn't Lock You In 🔓</title>
      <dc:creator>Domenico Tenace</dc:creator>
      <pubDate>Wed, 05 Aug 2026 08:00:00 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/opencode-the-open-source-coding-agent-that-doesnt-lock-you-in-pn3</link>
      <guid>https://dev.to/playfulprogramming/opencode-the-open-source-coding-agent-that-doesnt-lock-you-in-pn3</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;Hey everyone 👋&lt;/p&gt;

&lt;p&gt;If you've ever hit your Claude Code token limits mid-task, wondered what's happening under the hood of a closed-source agent, or just wanted to plug in a different model without switching tools entirely, OpenCode might be exactly what you were looking for.&lt;/p&gt;

&lt;p&gt;It's the open source alternative that took the terminal agent concept and made it model-agnostic, and by mid-2026 it had already surpassed Claude Code on GitHub stars. That's not a coincidence.&lt;/p&gt;

&lt;p&gt;Let me break it down. Let's dive in! 🤙&lt;/p&gt;




&lt;h2&gt;
  
  
  What Is OpenCode? 🤔
&lt;/h2&gt;

&lt;p&gt;OpenCode is an open source AI coding agent built in Go that runs in the terminal, desktop, and IDE. Its thesis is simple: you bring the model, OpenCode brings the agent. It supports 75+ LLM providers, from Claude and GPT to local models via Ollama, doesn't store your code, doesn't charge a subscription, and over 7.5 million developers use it monthly.&lt;/p&gt;

&lt;p&gt;It was built by the SST team, the same people behind the popular serverless framework. The design is a client/server architecture, not a single CLI binary, so one backend drives a terminal TUI, a desktop app, and IDE extensions for VS Code and Cursor.&lt;/p&gt;

&lt;p&gt;OpenCode surpassed Claude Code on GitHub stars (160K+ vs 122K+) and is now the most starred open source coding agent. It does what Claude Code does, but lets you plug in any model from 75+ providers, including local models at zero API cost.&lt;/p&gt;




&lt;h2&gt;
  
  
  How It Works 🔧
&lt;/h2&gt;

&lt;p&gt;Installing OpenCode takes about 30 seconds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://opencode.ai/install | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You land in a polished TUI with two modes, Build and Plan. Build mode executes tasks directly. Plan mode is read-only, it lets the agent analyze your codebase and propose an approach before touching a single file. This is the separation of intent and execution that Claude Code doesn't make as explicit.&lt;/p&gt;

&lt;p&gt;The design choice that matters most is the one in the name. OpenCode separates the agent harness from the model. Claude Code is tuned end to end around Anthropic's models and talks to them and only them. OpenCode connects to 75+ providers through Models.dev, including Anthropic, OpenAI, Google, Moonshot, Z.ai, local runtimes through Ollama, and any OpenAI-compatible endpoint you hand it.&lt;/p&gt;

&lt;p&gt;You can switch models mid-session without restarting. That alone is a feature Claude Code doesn't have.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Pricing Reality 💰
&lt;/h2&gt;

&lt;p&gt;This is where OpenCode makes its strongest argument. There's no subscription for the software itself, you pay for model access directly.&lt;/p&gt;

&lt;p&gt;The options as of mid-2026:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bring your own key&lt;/strong&gt;: pay the provider directly at their posted rates. Full flexibility, full cost visibility.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OpenCode Zen&lt;/strong&gt;: a pay-as-you-go hosted gateway with access to many models.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OpenCode Go&lt;/strong&gt;: $5 for the first month, then $10/month. Includes access to capable open models like GLM, Kimi K2, Qwen, DeepSeek, and MiniMax with generous per-session request limits.&lt;/p&gt;

&lt;p&gt;Compare that to Claude Code's $20/month Pro, $100/month Max 5x, or $200/month Max 20x plans. For individual developers or small teams watching their AI spend, the math is clear.&lt;/p&gt;

&lt;p&gt;The caveat: cost visibility helps when you are counting. Once you settle onto a flat Max plan, the math changes. If you're a power user who hits their limits constantly, Claude Code's flat rate might actually be cheaper per task.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Anthropic Block: What Happened and Where It Stands 🚧
&lt;/h2&gt;

&lt;p&gt;This is the part of the story that redefined what OpenCode actually is.&lt;/p&gt;

&lt;p&gt;On January 9, 2026, Anthropic changed its OAuth policy to block third-party applications from authenticating users through Claude.ai accounts. OpenCode was the primary casualty: users who relied on their Claude Pro login lost access overnight. The official reason was "security and ToS compliance."&lt;/p&gt;

&lt;p&gt;The January block made that choice less about saving money and more about philosophy. You are no longer choosing a cheaper way to run Claude. You are choosing whether you want a managed product or an open one.&lt;/p&gt;

&lt;p&gt;Where it stands today: you can still use Claude models in OpenCode, but only through an Anthropic API key, not your Claude.ai subscription credentials. The more lasting impact was reputational: it accelerated many users migrating to Gemini as their default backend.&lt;/p&gt;


&lt;h2&gt;
  
  
  OpenCode vs Claude Code: The Real Differences 🥊
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Terminal experience
&lt;/h3&gt;

&lt;p&gt;OpenCode tends to win here, and it wins on feel. The TUI is the repeated favorite in nearly every comparison thread. The terminal does not flicker on each update, sections scroll independently, and planning prompts are easy to answer. OpenCode also ships a standalone Tauri desktop app for macOS, Windows, and Linux, something Claude Code doesn't have.&lt;/p&gt;
&lt;h3&gt;
  
  
  Autonomy features
&lt;/h3&gt;

&lt;p&gt;Claude Code has a wider toolset: Agent View for fleet management, /goal for fire-and-forget autonomous runs, instant rewind via double-Esc, and background monitoring. OpenCode has background subagents and sessions that survive a terminal close, but lacks the orchestration depth.&lt;/p&gt;
&lt;h3&gt;
  
  
  Output quality
&lt;/h3&gt;

&lt;p&gt;A controlled benchmark found Claude Code faster and OpenCode more thorough using the same model. The summary: "Claude Code is built for speed. OpenCode is built for thoroughness."&lt;/p&gt;

&lt;p&gt;One practical issue to know about: multiple testers reported that OpenCode, across all tested models, reformats existing code without authorization. On mature codebases with established style guides, this is a trust issue. There's an open GitHub issue tracking this, and it's the most common complaint in real-world use.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Pros 👍
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;True model freedom.&lt;/strong&gt; No other terminal agent lets you swap between Claude, Gemini, DeepSeek, Qwen, or a local Ollama model mid-session. This is OpenCode's defining advantage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Open source and inspectable.&lt;/strong&gt; You can read the codebase, fork it, self-host it, and know exactly what the agent is doing with your code. Claude Code is closed source.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Better terminal UX.&lt;/strong&gt; The TUI is genuinely nicer. Non-flickering updates, scrollable sections, a dedicated desktop app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cost control.&lt;/strong&gt; Bring your own key, use local models at zero cost, or pay $10/month for the Go tier. The ceiling is much lower than Claude Code's $200/month Max plan.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Data compliance.&lt;/strong&gt; Teams with strict data requirements can point OpenCode at a local or self-hosted model so code never leaves their network.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Cons 👎
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The code reformatting issue.&lt;/strong&gt; OpenCode has a known tendency to reformat existing code without being asked. On mature codebases this creates noisy diffs and erodes trust in the agent's edits. Not a dealbreaker, but worth knowing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Thinner plugin ecosystem.&lt;/strong&gt; Claude Code has a more mature skills, hooks, and plugin marketplace. OpenCode's extension catalog is catching up, but it's not there yet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No subscription path for Claude.&lt;/strong&gt; If you're paying for Claude Pro or Max, you can't use that credit in OpenCode. You need a separate API key, which means paying again.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fewer autonomous orchestration features.&lt;/strong&gt; /goal mode, Agent View, instant rewind, and worktree isolation are Claude Code exclusives. For complex multi-agent workflows, Claude Code is still ahead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Broad permissions by default.&lt;/strong&gt; Several developers flag that OpenCode's agent permissions are broad by default. Check opencode.json before you point it at anything sensitive.&lt;/p&gt;


&lt;h2&gt;
  
  
  Who Should Use OpenCode? 🎯
&lt;/h2&gt;

&lt;p&gt;OpenCode is the right choice if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You want model flexibility and don't want to be locked into Anthropic's roadmap&lt;/li&gt;
&lt;li&gt;Budget control matters and you want to use cheaper or local models&lt;/li&gt;
&lt;li&gt;You prefer an open source tool you can inspect, fork, and trust&lt;/li&gt;
&lt;li&gt;Your team has compliance requirements that require on-premise model inference&lt;/li&gt;
&lt;li&gt;You find Claude Code's terminal UX annoying and want something nicer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Stay with Claude Code if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You need the strongest possible instruction-following on hard tasks&lt;/li&gt;
&lt;li&gt;You use Agent View, /goal, or other orchestration features heavily&lt;/li&gt;
&lt;li&gt;You want a managed product that "just works" without configuration&lt;/li&gt;
&lt;li&gt;You're already paying for Max and want to get full value from it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And honestly, plenty of people run both. OpenCode for day-to-day work with flexible models, Claude Code for the heavy debugging sessions where Opus is worth it.&lt;/p&gt;


&lt;h2&gt;
  
  
  My Honest Take 💭
&lt;/h2&gt;

&lt;p&gt;OpenCode is a serious tool, not a hobby alternative. 178,000 GitHub stars and 7.5 million monthly users don't lie. The model-agnostic design is genuinely useful, and the terminal UX is objectively better than Claude Code's.&lt;/p&gt;

&lt;p&gt;But the January block revealed something important: the moment you depend on Claude's quality and want to pay less, you're in Anthropic's crosshairs. OpenCode solved the tooling problem, not the model dependency problem. If you're using it with Claude via API key, you're still paying Anthropic rates.&lt;/p&gt;

&lt;p&gt;The real freedom comes when you combine OpenCode's harness with open or local models. That's the combination that makes the cost argument actually land, and that's where the project's future clearly points.&lt;/p&gt;

&lt;p&gt;Managed product or open tool? The answer depends on who you want to be as a developer.&lt;/p&gt;

&lt;p&gt;Happy coding! ✨&lt;/p&gt;



&lt;p&gt;Hi 👋🏻&lt;br&gt;
My name is Domenico, software developer passionate of Open Source, I write article about it for share my knowledge and experience.&lt;br&gt;
Don't forget to visit my Linktree to discover my links and to check out Domenico Tenace Open Labs for my open-source projects! 🫰🏻&lt;/p&gt;

&lt;p&gt;🌲 Linktree: &lt;a href="https://linktr.ee/domenicotenace" rel="noopener noreferrer"&gt;https://linktr.ee/domenicotenace&lt;/a&gt;&lt;br&gt;
🐙 Domenico Tenace Open Labs: &lt;a href="https://github.com/Domenico-Tenace-Open-Labs" rel="noopener noreferrer"&gt;https://github.com/Domenico-Tenace-Open-Labs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Follow me on dev.to for more articles 👇&lt;/p&gt;


&lt;div class="ltag__user ltag__user__id__985143"&gt;
    &lt;a href="/dvalin99" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media2.dev.to/dynamic/image/width=150,height=150,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F985143%2Fc4c372a7-0b38-4f9e-b206-7ed65597ea31.png" alt="dvalin99 image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/dvalin99"&gt;Domenico Tenace&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/dvalin99"&gt;Passionate about the IT world and everything related to it ✌🏻
Open Source enthusiastic 🦠&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;If you like my content or want to support my work, you can support me with a small donation. I would be grateful 🥹&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/domenicotenace" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb5vrzbmybu3q0sb5bzs1.png" alt="Buy Me A Coffee" width="545" height="153"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>programming</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Introducing Argus: The Code Security Colleague Your Team Doesn't Have</title>
      <dc:creator>Davide Imola</dc:creator>
      <pubDate>Thu, 30 Jul 2026 08:56:00 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/introducing-argus-the-code-security-colleague-your-team-doesnt-have-5g81</link>
      <guid>https://dev.to/playfulprogramming/introducing-argus-the-code-security-colleague-your-team-doesnt-have-5g81</guid>
      <description>&lt;p&gt;Most development teams don't have a security engineer. Not because they don't want one. Security expertise is genuinely hard to find, expensive to keep, and most of us would rather ship features than spend an afternoon reading about deserialization gadget chains. So security becomes the thing you'll get to later, and later never comes.&lt;/p&gt;

&lt;p&gt;I've believed for a while that AI is going to change security, and not as a slogan. The reason is structural: there aren't enough people. The industry is short something like 4.8 million security professionals worldwide,&lt;sup id="fnref1"&gt;1&lt;/sup&gt; which is the gap from that first paragraph counted globally, and no hiring spree closes a hole that size. AI won't close it either, and I want to be honest about that. What it can do is make the gap hurt less: take the routine load off the few people who are there, and keep a small team, or a team of one, from being buried. Same as it did for my coding, where it didn't make me smarter, it just stopped the grunt work from being the bottleneck.&lt;/p&gt;

&lt;p&gt;A good model has read more security than most of us ever will: the best practices, the attack patterns, the bugs that hide in plain sight. Point it at code written by someone who isn't a security expert, which is most of us, and it genuinely lifts what they can ship safely. This isn't a spectator take for me either, it's what I spend my days on, building products that live right at that intersection. And the other side already gets it: attackers are using AI right now, so insisting defenders shouldn't is not caution, it's a handicap.&lt;/p&gt;

&lt;p&gt;Concretely, I already use AI for security review, enough that I'm building a talk around how to do it well: lean on the skills that already exist, write your own, and point them at the real tools you already have. Give a capable model the right context and it quietly does a lot of the work a tired reviewer skips under a deadline. What it doesn't do is stick around. Every session starts from zero, knows nothing about your last review, forgets what you told it yesterday.&lt;/p&gt;

&lt;p&gt;Then I started using &lt;a href="https://github.com/openclaw/openclaw" rel="noopener noreferrer"&gt;OpenClaw&lt;/a&gt;, and it reframed the problem for me. OpenClaw is an always-running agent with a SOUL, a memory, and enough context about you that talking to it feels less like prompting a chatbot and more like messaging a colleague. It remembers. It knows your setup. I used it for useful things and for completely useless ones, and I had a lot of fun. We've mostly stopped since, if I'm honest, but it worked, and somewhere in there the idea landed: what if that colleague did security?&lt;/p&gt;

&lt;p&gt;That's &lt;a href="https://github.com/argusappsec/argus" rel="noopener noreferrer"&gt;Argus&lt;/a&gt;: an open-source application security agent, written in Go, that I've been building with a few colleagues at &lt;a href="https://redcarbon.ai" rel="noopener noreferrer"&gt;RedCarbon&lt;/a&gt;. It's the project that quietly took the place of &lt;a href="https://dev.to/blog/i-built-a-tool-i-dont-use"&gt;Worky&lt;/a&gt;, the tool I built and then never used, except this one has a mission I actually care about, so I'm not going anywhere.&lt;/p&gt;

&lt;p&gt;Fair warning before you get excited: Argus is v0.2.0, and it's as much an idea as a tool. It's the thing I kept wishing existed, so I built a first version with people who actually do security for a living. I'm not sure I've got the shape right, but the shape is the part worth arguing about, and I'd rather do that in the open than sit on it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why security review needs a different shape
&lt;/h2&gt;

&lt;p&gt;I want to be clear here, because this is easy to misread. I'm not saying AI security review is a bad idea. It's a great idea. What I don't believe in is doing it with AI alone. Models hallucinate, and a confident, wrong answer about a vulnerability is worse than no answer at all. Lean the whole thing on a model and you get a tool that sounds authoritative while quietly missing the one finding that mattered.&lt;/p&gt;

&lt;p&gt;So the bet behind Argus isn't "point a model at your code". It's the union of three things that each cover for the others' blind spots: deterministic security tools that have been proven for years, a human kept firmly in the loop, and a model to tie it together and reason across the whole picture. Take any one of the three away and it falls over. Especially the human.&lt;/p&gt;

&lt;p&gt;Recognizing a security problem is not something you wing. Get a code suggestion wrong and it's annoying; get a security call wrong and it's a breach. So an agent you'd actually trust with this has to earn that trust in ways a coding assistant never has to. Its answers need to trace back to something real instead of a confident guess. Its memory, from the moment it has one, becomes a thing attackers will try to lie to, so who gets to shape it suddenly matters. And it has to understand your world in particular, not security in the abstract, because a good share of the problems that actually bite only make sense once you know how your systems fit together.&lt;/p&gt;

&lt;p&gt;None of these choices are settled. They're the ones I'd make today, pulled from the years I've spent around cybersecurity and filed down to the few details I think actually matter. I'm genuinely happy to have every one of them argued with. Here's the reasoning, a piece at a time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Structured tools, not a shell
&lt;/h2&gt;

&lt;p&gt;The default way to build a code agent in 2026 is to hand a model a shell and let it run. It works shockingly well for writing code. For security, I didn't want it.&lt;/p&gt;

&lt;p&gt;When an agent has a shell, two things are true at once: it can do anything, and you can't be sure what it did. In a security context that's backwards. You want the opposite. A small, known set of capabilities, each one auditable.&lt;/p&gt;

&lt;p&gt;So Argus doesn't get a shell. It gets tools. Under the hood there are real, boring, deterministic security scanners: &lt;a href="https://semgrep.dev" rel="noopener noreferrer"&gt;Semgrep&lt;/a&gt; for static analysis, &lt;a href="https://github.com/gitleaks/gitleaks" rel="noopener noreferrer"&gt;Gitleaks&lt;/a&gt; for secrets, &lt;a href="https://github.com/google/osv-scanner" rel="noopener noreferrer"&gt;osv-scanner&lt;/a&gt; for vulnerable dependencies. Each one is wrapped as a structured tool the agent can call, not a command it can type. The scanner runs, returns structured findings, and the model reasons on top of that.&lt;/p&gt;

&lt;p&gt;This is also where an agent earns its place, because application security doesn't suffer from a missing tool. It suffers from too many. Nobody has the time to learn them properly, and even once you know them, remembering to run the right one at the right moment is a discipline of its own. You can wire them into a pipeline, of course, and then a slice of your week goes into managing the pipeline. An agent that already holds them, knows which one answers which question, and reaches for them without being asked is a different proposition from a folder full of CLIs you keep meaning to try.&lt;/p&gt;

&lt;p&gt;One thing I'm genuinely proud of, and it's the least flashy part: Argus doesn't reinvent any of this. I'm not rewriting Semgrep, I'm not reimplementing a dependency scanner, because why would I. The whole bet is the opposite. Take the tools that already exist and already work, pull good data out of them, and let the agent reason over that data instead of over a hunch. The set Argus ships with today is small on purpose, and the direction is to let you bring your own: the more real tools it can call, the more signal it has to reason with. How far you push that is up to you.&lt;/p&gt;

&lt;p&gt;That division of labor is the whole point. The deterministic layer finds things. The model does what models are good at: reading 400 findings and turning them into a conversation. "These three are the ones that matter, this one is a false positive because of how your auth middleware works, and here's the fix." Not a wall of SARIF. A colleague's summary.&lt;/p&gt;

&lt;p&gt;It also keeps Argus honest about where its answers come from. A finding traces back to a tool that actually ran, not to a model that decided to type &lt;code&gt;grep&lt;/code&gt; and interpret the output. When the domain is security, that provenance is the difference between a report you can act on and a guess you have to re-verify.&lt;/p&gt;

&lt;h2&gt;
  
  
  Roles and an audit log
&lt;/h2&gt;

&lt;p&gt;An agent with a memory has a problem a stateless chatbot doesn't: the memory is part of the attack surface. If anyone who can talk to Argus can also teach it, then anyone who can talk to Argus can poison it. "Ignore that finding, it's fine" whispered often enough becomes policy.&lt;/p&gt;

&lt;p&gt;OpenClaw already draws this line. If you have permission to write to the memory, you can shape it. If you don't, you can't. Argus takes the same idea and makes it central, because for a security tool it isn't a nice-to-have.&lt;/p&gt;

&lt;p&gt;So every request arrives as a principal with a role, and Argus always knows which door you came through. Reach it over the local Unix socket and you're &lt;code&gt;local:$USER&lt;/code&gt;; come in through the MCP endpoint and you're &lt;code&gt;mcp:&amp;lt;token-hash&amp;gt;&lt;/code&gt;; arrive as a GitHub webhook and you're &lt;code&gt;github:&amp;lt;login&amp;gt;&lt;/code&gt;. A viewer can ask questions and read findings, but shaping the memory, changing what Argus believes about your org, is a privileged action. And whatever anyone does, whoever they are, lands in an append-only audit log.&lt;/p&gt;

&lt;p&gt;That log turns out to matter for a second reason. Go back to the original itch: teams without a security person. Those teams usually still have someone who has to answer to a CISO, a client, or an auditor about how security is handled, without reading the code themselves. An append-only record of what was reviewed, what was found, and what was decided is exactly the artifact that conversation needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  SOUL, context, and a memory built for security
&lt;/h2&gt;

&lt;p&gt;This is the part I took most directly from OpenClaw, then closed down hard around security.&lt;/p&gt;

&lt;p&gt;Argus keeps a mix of three things, and they are not the same thing, which I keep having to explain to people, past-me included. There's the SOUL, the stable stuff: who Argus is, what your company does, your stack, your compliance posture. It rides along in every single model call, so Argus never forgets whose codebase it's looking at. There's context, the per-task working set for whatever it's reasoning about right now. And there's memory, the curated knowledge that persists from one conversation to the next.&lt;/p&gt;

&lt;p&gt;The memory is where the security focus shows. Argus remembers findings. It remembers the things you tell it. And, my favorite part, it remembers your false positives, so the thing you already triaged and dismissed doesn't come back to eat your afternoon next week. That is the single most colleague-like behavior in the whole system. A good reviewer remembers what you already decided.&lt;/p&gt;

&lt;p&gt;Say &lt;code&gt;config.py&lt;/code&gt; in one of your repos only holds deploy-time placeholders that your secret manager swaps out at deploy. Tell Argus once, and it stops flagging them on that repo. The next review comes back clean, with a note explaining why, instead of the same false alarm you waved off last sprint.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwrp3bklpmabmti0obnwn.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwrp3bklpmabmti0obnwn.webp" alt="A later Argus review on the same repository reporting no new findings, noting that the config.py credentials are known deploy-time placeholders and not a vulnerability in this project" width="800" height="273"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The SOUL is what makes the reasoning fit your world instead of the abstract world of security-in-general. And the cross-session, cross-project knowledge is where I think this goes somewhere a single-repo tool can't follow. A coding agent pointed at one repository is blind to how that repository talks to the other twelve. Plenty of the security problems that actually hurt live in exactly that gap: the service that trusts input another service should have sanitized. Feed Argus enough of your world and it can start to reason across that boundary. It's early, but that's the direction.&lt;/p&gt;

&lt;p&gt;OpenClaw is a general assistant, open-ended by design. Argus is the opposite. It knows it's a security tool, and everything (the tools, the skills, the memory, the persona) is shaped for that one job. Narrower, but deeper.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Argus does today (v0.2)
&lt;/h2&gt;

&lt;p&gt;Enough philosophy. Here is what actually runs.&lt;/p&gt;

&lt;p&gt;One thing to set straight first, because the word "security" invites the wrong expectation. Argus doesn't watch your infrastructure, it doesn't sit in front of your traffic, and it is not a SOC. It reads code. That's the job it's built for, and the rest is somebody else's product.&lt;/p&gt;

&lt;p&gt;Argus is a daemon, &lt;code&gt;argusd&lt;/code&gt;, one shared instance per organization. Every way you talk to it (a terminal UI, the MCP endpoint, GitHub webhooks, and Slack soon) is a different door into the same process, sharing one memory, one tool registry, one audit log.&lt;/p&gt;

&lt;p&gt;The most visible thing it does is review pull requests. Connect it as a GitHub App and it turns up on the thread like any other reviewer, except this one only cares about security. When it flags something you can push back right there, "Argus, is this finding real?", and it answers in context instead of making you go and dig. That back-and-forth isn't a nicety, it's the design: Argus is meant to be argued with, not obeyed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fa8m1fou1bt4bt0nb9k2e.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fa8m1fou1bt4bt0nb9k2e.webp" alt="Argus posts a security review on a GitHub pull request, flagging hardcoded AWS credentials in config.py and a SQL injection in the /users endpoint, with two findings on the changed lines" width="800" height="298"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Because it's also an MCP server, the AI tools you already use can consult it as a colleague rather than a black box. This is the part I reach for most: I point at something I just wrote and ask whether it's safe. And I want to be fair about the alternative, because the tools you already have are good at this. Claude and friends ship security skills, people write their own, and they work. What none of them has is your company: the other twelve repos, how your services talk to each other, which of your systems actually holds the data worth stealing. Ask Argus whether a pattern is a problem and it answers for your world instead of for security in the abstract, because the SOUL and the memory are right there. And it runs skills, which is how security methodology gets baked in. It ships with a handful: &lt;code&gt;pr-quick-check&lt;/code&gt; for a fast pass over a diff, &lt;code&gt;authz-audit&lt;/code&gt; for hunting authorization flaws, &lt;code&gt;secret-rotation-plan&lt;/code&gt; for finding committed secrets and deciding what to rotate first, and &lt;code&gt;threat-modeling&lt;/code&gt; for a STRIDE pass. You write your own the same way the built-ins are written, as a Markdown &lt;code&gt;SKILL.md&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Getting started is &lt;code&gt;./argus init&lt;/code&gt; to pick a provider and write your SOUL, &lt;code&gt;./argus doctor&lt;/code&gt; to check the scanners are wired up, &lt;code&gt;./argus codehost setup&lt;/code&gt; to connect GitHub, and plain &lt;code&gt;./argus&lt;/code&gt; to just chat with it. There's a container image on &lt;code&gt;ghcr.io&lt;/code&gt; with the scanners pre-bundled if you'd rather not install Semgrep and friends by hand.&lt;/p&gt;

&lt;p&gt;A word on which model runs all this, because it's a design choice and not an afterthought. Argus is built to run on the AI you already have and already trust, rather than the one a vendor picks for you. The provider layer sits behind an interface, and &lt;code&gt;argus init&lt;/code&gt; is where you choose. Today that choice is still narrow, with one provider implemented, and I won't dress that up as a feature. Support for any OpenAI-compatible endpoint is what I'm building right now, so depending on when you read this it may already be in. That's also the change that opens the door to local models, since most local runners speak the same API, and it matters for the teams I most want to reach: the ones who can't send their code to somebody else's API and don't have the budget to.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it's going
&lt;/h2&gt;

&lt;p&gt;The idea list is longer than the changelog, which is the correct ratio for a v0.&lt;/p&gt;

&lt;p&gt;The near stuff: Slack as a first-class channel, so Argus really is the colleague you message. Local models. More skills.&lt;/p&gt;

&lt;p&gt;The stuff I'm actually excited about: service and code discovery, so Argus builds its own map of your systems instead of waiting to be told, and a view of how your projects connect, because that cross-project graph is where the non-obvious problems hide.&lt;/p&gt;

&lt;p&gt;But I want to be careful, because I've made this mistake before. With &lt;a href="https://dev.to/blog/i-built-a-tool-i-dont-use"&gt;Worky&lt;/a&gt; I built a showcase site and full docs for a tool with zero users, then watched it drift because there was no real usage telling me what to build next. A roadmap without users is fiction. So I'm not going to pretend I know exactly what Argus needs. The roadmap comes from whoever picks it up.&lt;/p&gt;

&lt;p&gt;The difference from Worky, the reason I'm not worried this one ends up on the same shelf, is that I use Argus. It has a mission I care about. This is the tool I want to keep alive, and I get a vote in what it becomes precisely because I'm one of its users.&lt;/p&gt;

&lt;h2&gt;
  
  
  Come build in AI and security
&lt;/h2&gt;

&lt;p&gt;There's a bigger thing behind Argus, and it's the reason I'm writing this instead of just pushing a repo.&lt;/p&gt;

&lt;p&gt;AI and cybersecurity are converging fast, and most people are only watching one side of it. Back in June we ran a hackathon at RedCarbon: one day, tiny teams, AI pointed at security problems. I wrote about being on the jury in &lt;a href="https://dev.to/blog/i-built-a-tool-i-dont-use"&gt;the Worky retrospective&lt;/a&gt;, but the part I keep coming back to is the range. One team went after phishing aimed at non-technical family members. Another built for the SOC. Another attacked the security of AI models themselves. Same prompt, completely different directions, all of them real.&lt;/p&gt;

&lt;p&gt;Argus is just my direction, and it comes from something I actually live. I'm lucky here: I have security colleagues at RedCarbon who helped me shape it, pick the tools, and read what those tools are really saying. But they spend their days pointing our own AI agents at SOC problems, and none of them has time to sit behind our code's security posture every single day. So the developers have to, and Argus automates the exact work those colleagues would otherwise do by hand. And that job, it turns out, is increasingly buildable: models are getting good enough at security reasoning that the bottleneck is no longer the model, but whether someone shapes it into something trustworthy and useful.&lt;/p&gt;

&lt;p&gt;A while back I wrote that &lt;a href="https://dev.to/blog/ai-will-not-secure-your-codebase"&gt;AI will not secure your codebase&lt;/a&gt;, that it won't do the job for you but it can surface risk earlier, act as an early-warning system. Argus is me trying to make that concrete. Not a magic box that makes you secure, but a colleague who has read your whole codebase, remembers what you decided, and is awake at 2am when the PR lands.&lt;/p&gt;

&lt;p&gt;It's &lt;a href="https://github.com/argusappsec/argus" rel="noopener noreferrer"&gt;on GitHub&lt;/a&gt;, Apache 2.0, v0.2 and honest about it. If you do security, or you just want the security colleague you don't currently have, clone it, break it, write a skill, and tell me how you use it. Real usage is the one thing that turns a fun experiment into a tool that matters, and I learned that the expensive way.&lt;/p&gt;

&lt;p&gt;Worky has two stars and I made my peace with that. Argus I'd actually like you to star, because this is the one I'm keeping. And if you've been sitting on your own idea at the intersection of AI and security, stop sitting on it. The water's warm.&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;The 4.8 million figure is ISC2's estimate of the global cybersecurity workforce gap: the distance between the security professionals organizations say they need and the ones actually available to hire. Source: &lt;a href="https://www.isc2.org/Insights/2024/10/ISC2-2024-Cybersecurity-Workforce-Study" rel="noopener noreferrer"&gt;ISC2 2024 Cybersecurity Workforce Study&lt;/a&gt;.&amp;nbsp;↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>go</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Gemini 3.6 Flash: Google's Fastest Bet in a Crowded Race 🚀</title>
      <dc:creator>Domenico Tenace</dc:creator>
      <pubDate>Wed, 29 Jul 2026 08:33:15 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/gemini-36-flash-googles-fastest-bet-in-a-crowded-race-2a77</link>
      <guid>https://dev.to/playfulprogramming/gemini-36-flash-googles-fastest-bet-in-a-crowded-race-2a77</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;Hey everyone 👋&lt;/p&gt;

&lt;p&gt;Google dropped Gemini 3.6 Flash on July 21, 2026, and it's worth talking about. Not because it's a revolution, but because it quietly improves on almost everything from 3.5 Flash while getting cheaper and faster at the same time. That's a combination you don't see often.&lt;/p&gt;

&lt;p&gt;Let me break down what actually changed, how it stacks up against the competition, and whether you should care.&lt;/p&gt;

&lt;p&gt;Let's dive in! 🤙&lt;/p&gt;




&lt;h2&gt;
  
  
  What Is Gemini 3.6 Flash? 🤔
&lt;/h2&gt;

&lt;p&gt;Gemini 3.6 Flash is Google's workhorse model for developers, the go-to for agentic workflows, coding tasks, long-document reasoning, and multimodal work. It's not Google's most capable model (that's still the upcoming 3.5 Pro and eventually Gemini 4), but it's the one most developers will actually use day to day.&lt;/p&gt;

&lt;p&gt;It was released alongside two companion models: Gemini 3.5 Flash-Lite, designed for high-throughput and low-latency tasks like agentic search and document processing, and the limited-pilot Gemini 3.5 Flash Cyber for governments and trusted partners.&lt;/p&gt;

&lt;p&gt;The model is available in Google AI Studio, the Gemini API (model ID &lt;code&gt;gemini-3.6-flash&lt;/code&gt;), the Gemini app, Antigravity, Android Studio, and Vertex AI.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Numbers: What Actually Changed 📊
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Benchmarks
&lt;/h3&gt;

&lt;p&gt;Gemini 3.6 Flash improves on Gemini 3.5 Flash across the board: coding went from 55.1% to 58.7% on SWE-Bench Pro, long-context retrieval went from roughly 27% to 54.0%, and computer use went from 78.4% to 83% on OSWorld Verified.&lt;/p&gt;

&lt;p&gt;Average task time fell from 2.7 minutes to 1.3 minutes, while estimated task cost declined about 18 percent. That's not a minor tweak. That's a meaningfully faster agent in practice.&lt;/p&gt;

&lt;h3&gt;
  
  
  Speed
&lt;/h3&gt;

&lt;p&gt;It runs at about 280 tokens per second, which makes it one of the faster models in its class for interactive use. For agentic workflows where you're chaining multiple LLM calls, this compounds fast.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pricing
&lt;/h3&gt;

&lt;p&gt;Gemini 3.6 Flash costs $1.50 per million input tokens and $7.50 per million output tokens. Input pricing is unchanged from Gemini 3.5 Flash, but output dropped from $9.00 to $7.50 per million tokens.&lt;/p&gt;

&lt;h3&gt;
  
  
  Context Window and Knowledge Cutoff
&lt;/h3&gt;

&lt;p&gt;The model runs a 1 million-token context window with a 64,000-token output cap, and its knowledge cutoff is March 2026, up from January 2025 on Gemini 3.5 Flash. That's a 14-month jump, which matters more than it sounds. A model that knows about recent framework releases, pricing changes, and API updates needs less web retrieval to stay useful.&lt;/p&gt;

&lt;h3&gt;
  
  
  Token Efficiency
&lt;/h3&gt;

&lt;p&gt;The model takes fewer reasoning steps and tool calls to complete multi-step workflows, which is a large part of why it uses roughly 17 percent fewer output tokens than its predecessor. You're paying for less and getting more done. That's the ideal direction.&lt;/p&gt;




&lt;h2&gt;
  
  
  How It Compares to the Competition 🥊
&lt;/h2&gt;

&lt;h3&gt;
  
  
  vs. Claude Sonnet 5
&lt;/h3&gt;

&lt;p&gt;Claude Sonnet 5 outperforms on 3 benchmarks including SWE-Bench Pro and GDPval-AA, while Gemini 3.6 Flash wins on OSWorld-Verified and CharXiv-R. Claude Sonnet 5 has a slight edge in raw benchmark performance.&lt;/p&gt;

&lt;p&gt;But the cost story is different. Gemini 3.6 Flash is 25% cheaper on both input and output compared to Claude Sonnet 5. At 100,000 tasks per month with 5,000 input and 10,000 output tokens each, that's $2,750/month in savings. For cost-sensitive workloads, Gemini is the clear winner.&lt;/p&gt;

&lt;p&gt;Gemini 3.6 Flash also runs at 304 tokens per second compared to roughly 180 for Claude Sonnet 5. For agent workflows where latency matters, the speed difference is noticeable.&lt;/p&gt;

&lt;p&gt;My take: if code quality at any cost is the priority, Claude Sonnet 5 still wins on most coding benchmarks. If you're building high-volume agent pipelines or cost is a real constraint, Gemini 3.6 Flash makes a strong argument.&lt;/p&gt;

&lt;h3&gt;
  
  
  vs. GPT-5.6 Luna
&lt;/h3&gt;

&lt;p&gt;GPT-5.6 Luna remains cheaper than Gemini 3.6 Flash at public API rates, but Artificial Analysis measured Gemini at 304 output tokens per second compared to 190 for Luna. This creates a practical trade-off: Luna offers lower token rates, while Gemini produces output faster.&lt;/p&gt;

&lt;p&gt;Independent testers report Gemini 3.6 Flash loses most coding benchmarks and GDPVal to Grok 4.5 and GPT-5.6 Luna. So if pure coding benchmark numbers are what you're optimizing for, Google isn't at the top of that list right now.&lt;/p&gt;

&lt;h3&gt;
  
  
  vs. Gemini 3.5 Flash
&lt;/h3&gt;

&lt;p&gt;Both Gemini 3.6 Flash and Gemini 3.5 Flash currently score 50 on the Artificial Analysis Intelligence Index. Existing Gemini 3.5 Flash users have the clearest migration case, especially when latency and output volume drive costs.&lt;/p&gt;

&lt;p&gt;In other words: same intelligence, faster, cheaper, fresher knowledge cutoff. The upgrade is a no-brainer if you're already on 3.5 Flash.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Missing: The Elephant in the Room 🐘
&lt;/h2&gt;

&lt;p&gt;The most notable absence in this announcement is Gemini 3.5 Pro. Google originally said at I/O in May that 3.5 Pro would launch the following month. That deadline passed without a public release. Bloomberg reported on July 16 that the model was running months behind schedule, with Google spending extra time on its coding capabilities.&lt;/p&gt;

&lt;p&gt;Google did not release Gemini 3.5 Pro in this announcement. The company said the Pro model fell short of internal expectations on coding and complex reasoning, so its broader release was delayed.&lt;/p&gt;

&lt;p&gt;This is the real story. A delayed Pro model means that right now, Google's top available offering in the Flash tier competes on price and speed but not on raw reasoning against Claude Opus or GPT-5.6. Google also confirmed that pre-training has begun on Gemini 4, which the team described as its most ambitious pre-training run yet. So the roadmap is clearly ambitious, but the present gap is real.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Pros 👍
&lt;/h2&gt;

&lt;p&gt;Cost efficiency is excellent. Roughly half the output price of Claude Sonnet 5 at production scale is meaningful money. For startups or anyone watching API bills closely, this matters.&lt;/p&gt;

&lt;p&gt;Speed is genuinely impressive. At 304 tokens per second, it's 1.7x faster than Claude Sonnet 5 for agent workflows where latency matters.&lt;/p&gt;

&lt;p&gt;Multimodal support is broad. Gemini 3.6 Flash supports voice, video processing, images, PDFs, and audio as input. Claude Sonnet 5 doesn't support voice or video. For multimodal applications, Gemini is the stronger choice.&lt;/p&gt;

&lt;p&gt;The knowledge cutoff jump is significant. Going from January 2025 to March 2026 in one model generation means you're working with a model that actually knows about tools and frameworks released in the past year and a half.&lt;/p&gt;

&lt;p&gt;Token efficiency means lower costs in practice. Fewer output tokens for the same quality work, combined with a lower output price, compounds into real savings at volume.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Cons 👎
&lt;/h2&gt;

&lt;p&gt;The Pro model is still missing. For developers who need the strongest possible reasoning and coding quality today, Google's delays leave a gap that Claude Opus and GPT-5.6 are filling.&lt;/p&gt;

&lt;p&gt;Raw coding benchmark scores lag behind top competitors. On the benchmarks that matter most to developers, Grok 4.5, GPT-5.6 Luna, and Claude Opus 4.8 still outperform Gemini 3.6 Flash. Speed and cost don't compensate for quality when you're debugging something complex.&lt;/p&gt;

&lt;p&gt;Intelligence Index hasn't moved. Gemini 3.6 Flash and Gemini 3.5 Flash both score 50 on the Artificial Analysis Intelligence Index. Faster and cheaper is great, but it's not smarter. If you were hoping for a reasoning leap, this isn't it.&lt;/p&gt;

&lt;p&gt;Gemini 4 uncertainty. Google teasing their next major model while 3.5 Pro is still delayed creates uncertainty for teams planning their model strategy. Do you build on 3.6 Flash now, or wait?&lt;/p&gt;




&lt;h2&gt;
  
  
  Who Should Use Gemini 3.6 Flash? 🎯
&lt;/h2&gt;

&lt;p&gt;Existing Gemini 3.5 Flash users. The migration is a pure upgrade: same intelligence, faster, cheaper, better knowledge cutoff. No reason not to switch.&lt;/p&gt;

&lt;p&gt;Cost-sensitive teams building agents. If you're running thousands or millions of API calls, the pricing advantage compounds fast. At scale, Gemini 3.6 Flash is the most efficient option in its class.&lt;/p&gt;

&lt;p&gt;Multimodal applications. Voice, video, images, audio all in one model with a 1M token context window. If your use case touches multiple modalities, this is the most capable option at this price point.&lt;/p&gt;

&lt;p&gt;Developers already in the Google ecosystem. Antigravity, AI Studio, Vertex AI, Android Studio. If you're already in these tools, the integration is seamless.&lt;/p&gt;

&lt;p&gt;Who should look elsewhere: if you need the strongest possible code generation today and budget is secondary, Claude Opus 4.8 or GPT-5.6 Luna are stronger choices on raw coding benchmarks.&lt;/p&gt;




&lt;h2&gt;
  
  
  My Take 💭
&lt;/h2&gt;

&lt;p&gt;Gemini 3.6 Flash is a solid, honest upgrade. Google didn't promise a revolution and didn't deliver one. What they delivered is a faster, cheaper, more efficient model with a dramatically improved knowledge cutoff. For most agentic workloads, that's exactly what you need.&lt;/p&gt;

&lt;p&gt;The absence of 3.5 Pro is frustrating, and the coding benchmark gap against the top tier is real. But if you're building cost-sensitive pipelines, working with multimodal content, or already deep in Google's ecosystem, 3.6 Flash makes a compelling case.&lt;/p&gt;

&lt;p&gt;The question isn't "is this the best model?" It's "is this the best model for what I'm building?" For a lot of teams, the answer is yes.&lt;/p&gt;

&lt;p&gt;Happy coding! ✨&lt;/p&gt;




&lt;p&gt;Hi 👋🏻&lt;br&gt;
My name is Domenico, software developer passionate of Open Source, I write article about it for share my knowledge and experience.&lt;br&gt;
Don't forget to visit my Linktree to discover my links and to check out Domenico Tenace Open Labs for my open-source projects! 🫰🏻&lt;/p&gt;

&lt;p&gt;🌲 Linktree: &lt;a href="https://linktr.ee/domenicotenace" rel="noopener noreferrer"&gt;https://linktr.ee/domenicotenace&lt;/a&gt;&lt;br&gt;
🐙 Domenico Tenace Open Labs: &lt;a href="https://github.com/Domenico-Tenace-Open-Labs" rel="noopener noreferrer"&gt;https://github.com/Domenico-Tenace-Open-Labs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Follow me on dev.to for more articles 👇&lt;/p&gt;


&lt;div class="ltag__user ltag__user__id__985143"&gt;
    &lt;a href="/dvalin99" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media2.dev.to/dynamic/image/width=150,height=150,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F985143%2Fc4c372a7-0b38-4f9e-b206-7ed65597ea31.png" alt="dvalin99 image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/dvalin99"&gt;Domenico Tenace&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/dvalin99"&gt;Passionate about the IT world and everything related to it ✌🏻
Open Source enthusiastic 🦠&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;If you like my content or want to support my work, you can support me with a small donation. I would be grateful 🥹&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/domenicotenace" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb5vrzbmybu3q0sb5bzs1.png" alt="Buy Me A Coffee" width="545" height="153"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>google</category>
      <category>gemini</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Automating my Codemotion Badge with Antigravity</title>
      <dc:creator>Luca Del Puppo</dc:creator>
      <pubDate>Wed, 08 Jul 2026 05:50:52 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/automating-my-codemotion-badge-with-antigravity-4gpo</link>
      <guid>https://dev.to/playfulprogramming/automating-my-codemotion-badge-with-antigravity-4gpo</guid>
      <description>&lt;p&gt;Today, I wanna show you how to set up your devices with Antigravity using only the agentic mode, without touching any code.&lt;/p&gt;

&lt;p&gt;At the last CodeMotion Rome, I got my special badge. A &lt;a href="https://www.cmnode.it/en/" rel="noopener noreferrer"&gt;CM Node&lt;/a&gt;, a special hardware board, that you can customise for your conferences.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm6q63fq326znwdh88mvn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm6q63fq326znwdh88mvn.png" width="800" height="584"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'm not a super nerd for this kind of stuff, so I decided to use Antigravity and all its capabilities to build and flash the best board ever for my future conferences.&lt;/p&gt;

&lt;h2&gt;
  
  
  Small intro about the board
&lt;/h2&gt;

&lt;p&gt;This board has been delivered with a &lt;a href="https://github.com/Codemotion-Official/CMNode" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt; to understand how to flash it and how it works. In Rome, I saw different attendees with awesome badges. For instance, Soumaya had built a badge with a small plastic hand that used a sensor when someone was near her; it started waving to say hi.&lt;br&gt;&lt;br&gt;
Since that day, I have been thinking about what I can build to have a cool badge. Nothing has come to my mind, so today, with this blog, we will build my badge together, and thanks to Antigravity, we will create the best version possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Antigravity
&lt;/h2&gt;

&lt;p&gt;If you don't know &lt;a href="https://antigravity.google/" rel="noopener noreferrer"&gt;Antigravity&lt;/a&gt;. Antigravity is a set of tools built by Google. We have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://antigravity.google/product/antigravity-2" rel="noopener noreferrer"&gt;Antigravity 2.0&lt;/a&gt;: is a dedicated platform to work with agents. Orchestrate multiple autonomous agents working in parallel across independent projects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://antigravity.google/product/antigravity-cli" rel="noopener noreferrer"&gt;Antigravity CLI&lt;/a&gt;: terminal-first surface to interact with Antigravity agents. Stay in your flow without context switching&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://antigravity.google/product/antigravity-ide" rel="noopener noreferrer"&gt;Antigravity IDE&lt;/a&gt;: editor view offers tab autocompletion, natural language code commands, and a configurable, and context-aware configurable agent&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://antigravity.google/product/antigravity-sdk" rel="noopener noreferrer"&gt;Antigravity SDK&lt;/a&gt;: build AI agents that autonomously read files, run commands, edit code, and more. The Agent SDK gives you the same tools, agent loop, and context management that power Google Antigravity, programmable in Python.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Today, in this blog post, we will use Antigravity 2.0 to set up the board. You can use this tool to orchestrate many projects from a unique UI. This tool is fully agentic; using natural language, you can spawn agents, plan, and work on your projects. If you want to check the codebase in detail, you must use the Antigravity IDE. I’m not a fan of this decision, I’d prefer one tool for both, but this is what we have, and we must use it as it is.&lt;/p&gt;

&lt;h3&gt;
  
  
  Let’s start cooking
&lt;/h3&gt;

&lt;p&gt;Okay, after this introduction, let’s see what we can do with Antigravity and the CodeMotion Board.&lt;/p&gt;

&lt;p&gt;So, I’m dumb about this board right now, and I want to use Antigravity to figure out what I can do with it and get an idea of what my badge might look like.&lt;/p&gt;

&lt;p&gt;I open the Antigravity app, and from the UI, I start a new project, and in the prompt, I type&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I want to set up my Codemotion Badge.&lt;br&gt;&lt;br&gt;
It's a CMNode v0 &lt;a href="https://www.cmnode.it/en/" rel="noopener noreferrer"&gt;https://www.cmnode.it/en/&lt;/a&gt;, and it can be programmed.&lt;br&gt;&lt;br&gt;
I want to create two different screens: the first a classic one with name, surname, heading, and company, and a QR code linking to my website.&lt;br&gt;&lt;br&gt;
The second one must be fantastic, and I want different options to choose from you.&lt;/p&gt;

&lt;p&gt;I have this repository as an example to set up the badge &lt;a href="https://github.com/Codemotion-Official/CMNode" rel="noopener noreferrer"&gt;https://github.com/Codemotion-Official/CMNode&lt;/a&gt;; you can use it as an example to create my badge.&lt;br&gt;&lt;br&gt;
Lastly, I don't want to flash the ROM every time, so I'd like a small web page I can access via Wi-Fi to update the information.&lt;/p&gt;

&lt;p&gt;Can you plan the work to do it?&lt;br&gt;&lt;br&gt;
Include also two or three possible ideas for the second screen. It must be cool and fancy!&lt;/p&gt;

&lt;p&gt;The badge is already connected to the laptop in case you want to deploy the result.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, I press enter and let’s see the result and what it will cook.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;h1&gt;
  
  
  &lt;strong&gt;CMNode v0 WiFi Configuration &amp;amp; Dual Screen Setup&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;The goal of this task is to upgrade your CMNode v0 badge by replacing the serial-based configuration with a Wi-Fi-based web interface. We will also save the configured data to flash memory so it persists across reboots, and implement two different display layouts: a "Classic" screen and a "Fantastic" screen.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;User Review Required&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;IMPORTANT&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Please review the proposed ideas for the "Fantastic" screen below. Let me know which one you prefer, or if you'd like to combine elements from different ideas!&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Ideas for the "Fantastic" Second Screen:&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The "Hacker Terminal"&lt;/strong&gt; : A retro command-line interface aesthetic. The screen features a black background with white text, simulating a terminal session (e.g., &lt;code&gt;&amp;gt; user@cmnode:~$ whoami&lt;/code&gt;, followed by your details). We can use monospace fonts and add some faux hex-dumps or ASCII elements.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The "RPG Stats / Gamer Card"&lt;/strong&gt; : Your badge becomes a character stat sheet. It will display you as a "Level 99 Developer" with stats like "INT: 99", "COFFEE: 100%", an energy bar, and your details integrated into a game-like UI.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The "Minimalist Cyberpunk"&lt;/strong&gt; : A bold, modern, and high-contrast design. It uses large vertical typography for your name, heavy geometric shapes, thick red accent lines, and a large barcode aesthetic alongside your QR code.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Let me know which of these three ideas (or a mix!) you want me to build for the second screen.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Proposed Changes&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;We will modify the firmware to support a captive-like Wi-Fi Access Point and Web Server.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Core Logic Updates&lt;/strong&gt;
&lt;/h3&gt;
&lt;h4&gt;
  
  
  &lt;strong&gt;[MODIFY]&lt;/strong&gt; &lt;code&gt;src/main.cpp&lt;/code&gt; &lt;strong&gt;(or&lt;/strong&gt; &lt;code&gt;NodeV0.ino&lt;/code&gt;&lt;strong&gt;)&lt;/strong&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Wi-Fi Access Point&lt;/strong&gt; : The ESP32-C3 will broadcast an SSID (e.g., &lt;code&gt;CMNode-Config&lt;/code&gt;). You can connect to it with your phone or laptop.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Web Server&lt;/strong&gt; : A built-in web server will serve a simple, mobile-friendly HTML configuration page at &lt;a href="http://192.168.4.1" rel="noopener noreferrer"&gt;&lt;code&gt;http://192.168.4.1&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Form Submission&lt;/strong&gt; : The webpage will contain a form to update your Name, Surname, Role, Company, QR Link, and a dropdown to select the active screen layout (Classic vs Fantastic).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Persistent Storage&lt;/strong&gt; : Integrate the &lt;code&gt;Preferences&lt;/code&gt; library to save your data to the ESP32's non-volatile storage (NVS). This ensures your badge remembers your details even after turning off.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Display Pipeline&lt;/strong&gt; : Refactor the &lt;code&gt;drawContent()&lt;/code&gt; function to support rendering two completely different layouts based on your selection.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Verification Plan&lt;/strong&gt;
&lt;/h2&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Manual Verification&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;I will write the updated code and you will flash it to your badge via PlatformIO or Arduino IDE.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We will verify that the badge broadcasts the &lt;code&gt;CMNode-Config&lt;/code&gt; Wi-Fi network.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We will connect to it, open the web page, submit new data, and verify that the E-paper display updates immediately.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We will reboot the badge to confirm the data is preserved.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We will toggle between the Classic and Fantastic screens to verify the layouts.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;I commented on the plan, deciding to go with option one and asked for an example design.&lt;br&gt;&lt;br&gt;
Antigravity has started reviewing the plan and updated it in this way&lt;/p&gt;

&lt;blockquote&gt;
&lt;h1&gt;
  
  
  &lt;strong&gt;CMNode v0 WiFi Configuration &amp;amp; Dual Screen Setup&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;The goal of this task is to upgrade your CMNode v0 badge by replacing the serial-based configuration with a Wi-Fi-based web interface. We will also save the configured data to flash memory so it persists across reboots, and implement two different display layouts: a "Classic" screen and a "Fantastic" screen.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Design Choice: "Hacker Terminal"&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;You've selected the &lt;strong&gt;Hacker Terminal&lt;/strong&gt; idea for the second screen. This layout will simulate a retro command-line interface on the E-ink display:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Background&lt;/strong&gt; : Black (inverted).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Text&lt;/strong&gt; : Monospace white font, simulating terminal output (&lt;code&gt;root@cmnode:~$ whoami&lt;/code&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Data&lt;/strong&gt; : Your name, surname, role, and company will be displayed as the "output" of the terminal command.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Accents&lt;/strong&gt; : Faux hex-dumps or system logs on the side, and a right-aligned QR code.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is a mockup of the design:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvlr4ibd3u9ajetq95uiy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvlr4ibd3u9ajetq95uiy.png" alt="Hacker Terminal Mockup" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Does this mockup and the updated plan look good to you? If so, I will proceed with the implementation!&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Proposed Changes&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;We will modify the firmware to support a captive-like Wi-Fi Access Point and Web Server.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Core Logic Updates&lt;/strong&gt;
&lt;/h3&gt;
&lt;h4&gt;
  
  
  &lt;strong&gt;[MODIFY]&lt;/strong&gt; &lt;code&gt;src/main.cpp&lt;/code&gt; &lt;strong&gt;(or&lt;/strong&gt; &lt;code&gt;NodeV0.ino&lt;/code&gt;&lt;strong&gt;)&lt;/strong&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Wi-Fi Access Point&lt;/strong&gt; : The ESP32-C3 will broadcast an SSID (e.g., &lt;code&gt;CMNode-Config&lt;/code&gt;). You can connect to it with your phone or laptop.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Web Server&lt;/strong&gt; : A built-in web server will serve a simple, mobile-friendly HTML configuration page at &lt;a href="http://192.168.4.1" rel="noopener noreferrer"&gt;&lt;code&gt;http://192.168.4.1&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Form Submission&lt;/strong&gt; : The webpage will contain a form to update your Name, Surname, Role, Company, QR Link, and a dropdown to select the active screen layout (Classic vs Fantastic).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Persistent Storage&lt;/strong&gt; : Integrate the &lt;code&gt;Preferences&lt;/code&gt; library to save your data to the ESP32's non-volatile storage (NVS). This ensures your badge remembers your details even after turning off.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Display Pipeline&lt;/strong&gt; : Refactor the &lt;code&gt;drawContent()&lt;/code&gt; function to support rendering two completely different layouts based on your selection.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Verification Plan&lt;/strong&gt;
&lt;/h2&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Manual Verification&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;I will write the updated code and you will flash it to your badge via PlatformIO or Arduino IDE.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We will verify that the badge broadcasts the &lt;code&gt;CMNode-Config&lt;/code&gt; Wi-Fi network.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We will connect to it, open the web page, submit new data, and verify that the E-paper display updates immediately.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We will reboot the badge to confirm the data is preserved.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We will toggle between the Classic and Fantastic screens to verify the layouts.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;As you can see, we now have a clear idea of how the second screen should look and a plan to implement everything, but before spawning the agent work, I'd also like to have a design of the first screen of the badge, so using the chat, I ask to include it also in the plan.&lt;br&gt;&lt;br&gt;
After two iterations of the prompt, this is the result&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fekeo6h4eg4w6ca64owdw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fekeo6h4eg4w6ca64owdw.png" width="800" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The implementation
&lt;/h3&gt;

&lt;p&gt;To implement the plan, we just need to press the Proceed button and wait&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F91zg60zwkqr2r24ughdg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F91zg60zwkqr2r24ughdg.png" width="799" height="176"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;During the implementation, we can check what is happening through the UI&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm7lais4obiea9cy8kvtl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm7lais4obiea9cy8kvtl.png" width="800" height="587"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And if we notice something weird, we can stop the agent and type a new prompt to drive it again on the right path.&lt;br&gt;&lt;br&gt;
If you, like me, prefer to get confirmation before running commands or editing files, you must also approve these actions through the UI.&lt;/p&gt;

&lt;p&gt;After 2 minutes, this is the result.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F56rjqczbk93xqy75up3x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F56rjqczbk93xqy75up3x.png" width="800" height="645"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And if I connect my laptop to the badge Wi-Fi, I can configure my badge.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fovtot820jj87ux346wlo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fovtot820jj87ux346wlo.png" width="800" height="474"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The refine
&lt;/h3&gt;

&lt;p&gt;Now we have a badge working, but we want to improve it a bit: first, I want to change the screen by pressing the button on the back without connecting to the badge's Wi-Fi, and I want to set the Wi-Fi password via Environment Variables.&lt;br&gt;&lt;br&gt;
So I can prompt this&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Can we also change the screen view using the button on the rear of the badge without connecting to the badge's Wi-Fi?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And after a minute, the result is ready, and my badge has been flashed.&lt;br&gt;&lt;br&gt;
And lastly, I can ask not to hard-code the password but use an environment variable,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;use an environment variable for the wifi password&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;same here, after one minute and a couple of approvals, the result is again ready and in my badge.&lt;/p&gt;

&lt;p&gt;To complete, I want to change the layout by using one of the buttons on the back of the badge. So again I ask Antigravity to do it for me.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Can we change the screen view also by using the button in the rear of the badge without connecting to the badge wifi?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and same here, after some minutes, sometimes the result is happier in the badge.&lt;/p&gt;

&lt;p&gt;And the final result is this one&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd9r92nf2e97kqp6ez3pr.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd9r92nf2e97kqp6ez3pr.jpg" width="800" height="1067"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and this one&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F63zj0c26tiy8mki4hohl.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F63zj0c26tiy8mki4hohl.jpg" width="800" height="1067"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;It's time to wrap up!&lt;br&gt;&lt;br&gt;
So my experience with Antigravity has been great! I love to use it to build new things, or as a teammate to learn new technology, or just to prototype a pet project like this one.&lt;/p&gt;

&lt;p&gt;If you are in the agentic development, this tool can be a good one for you!&lt;br&gt;&lt;br&gt;
The experience is great, and if you want to have control over different projects or streams, it can be really helpful. The only pain point for me is the fact that if you want to check the code, you must install another tool, the Antigravity IDE, to check it.&lt;/p&gt;

&lt;p&gt;In this era of agent development, what I find great is the ability to plan and review the changes before the agent implements them! This is the game-changer for me in this moment, and then a lot and a lot of code review!&lt;/p&gt;

&lt;p&gt;Okay, that's it! I hope you enjoy this introduction to Antigravity and that you now want to test it for your project.&lt;/p&gt;

&lt;p&gt;I hope you also like my new super badge 🚀&lt;/p&gt;

&lt;p&gt;&lt;em&gt;p.s. to check the code result, you can navigate to this&lt;/em&gt; &lt;a href="https://github.com/Puppo/codemotion-badge" rel="noopener noreferrer"&gt;&lt;em&gt;repository&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Google Cloud credits are provided for this project.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>agenticarchitect</category>
      <category>googleantigravity</category>
    </item>
    <item>
      <title>Daily Prompt Is Out. Long Live Spellbook of Prompt 🧙🏻‍♂️</title>
      <dc:creator>Domenico Tenace</dc:creator>
      <pubDate>Mon, 06 Jul 2026 07:00:00 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/daily-prompt-is-out-long-live-spellbook-of-prompt-4353</link>
      <guid>https://dev.to/playfulprogramming/daily-prompt-is-out-long-live-spellbook-of-prompt-4353</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;Hey everyone 👋&lt;/p&gt;

&lt;p&gt;Some projects start as a quick idea and slowly grow into something you actually want to take seriously. That's exactly what happened with Daily Prompt, a small collection of prompts I put together for personal use that at some point became messy, inconsistent, and honestly a bit embarrassing to share.&lt;/p&gt;

&lt;p&gt;So I restarted from scratch. New name, new structure, new look. Meet &lt;a href="https://github.com/Domenico-Tenace-Open-Labs/spellbook-of-prompt" rel="noopener noreferrer"&gt;&lt;strong&gt;Spellbook of Prompt&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let's dive in! 🤙&lt;/p&gt;




&lt;h2&gt;
  
  
  What Was Daily Prompt? 🤔
&lt;/h2&gt;

&lt;p&gt;Daily Prompt was exactly what the name suggests: a daily collection of prompts. The idea was fine, a place to gather useful prompt templates to use with ChatGPT, Claude, Gemini, and whatever else was around. But the execution had problems.&lt;/p&gt;

&lt;p&gt;The prompts were scattered with no real organization. There was no clear logic behind the categories. The visual side was the default Starlight theme with zero customization. It felt like a dumping ground more than an actual project.&lt;/p&gt;

&lt;p&gt;And the name itself was limiting. "Daily" implied a frequency I couldn't keep up with. It set the wrong expectations.&lt;/p&gt;

&lt;p&gt;At some point I looked at it and thought: this doesn't represent what I actually want it to be.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Rebrand? 💡
&lt;/h2&gt;

&lt;p&gt;Renaming a project isn't something I do lightly. It breaks URLs, confuses people who already know it, and requires updating everything.&lt;/p&gt;

&lt;p&gt;But sometimes a fresh start is the right call.&lt;/p&gt;

&lt;p&gt;The rebrand to &lt;strong&gt;Spellbook of Prompt&lt;/strong&gt; came from a simple realization: a spellbook is a perfect metaphor for what this is. It's a collection of incantations, each one carefully crafted, tested, and documented. You open it, find what you need, cast the spell (run the prompt), and get a result.&lt;/p&gt;

&lt;p&gt;It fits. And more importantly, it gives the project an identity worth building around.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Changed: The Structure 🏗️
&lt;/h2&gt;

&lt;p&gt;The biggest improvement is the organization. Daily Prompt was a flat list of prompts with loose labels. Spellbook of Prompt organizes everything by use case, so you can actually find what you need without scrolling forever.&lt;/p&gt;

&lt;p&gt;The categories cover the most common real-world scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Content Creation&lt;/strong&gt;: scripts, posts, articles, newsletters&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code Generation and Debugging&lt;/strong&gt;: boilerplate, reviews, refactoring&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Analysis and Reporting&lt;/strong&gt;: summaries, structured output, comparisons&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Writing and Copywriting&lt;/strong&gt;: tone adjustments, persuasive copy, editing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Design and Creative Direction&lt;/strong&gt;: briefs, feedback loops, mood boards&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Learning and Education&lt;/strong&gt;: explanations, quizzes, study guides&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each prompt comes with a clear description, at least one input and output example, and notes on edge cases. The goal was to make every entry actually usable, not just a template you have to figure out yourself.&lt;/p&gt;

&lt;p&gt;The documentation is built with Astro and Starlight, which makes browsing fast and the content easy to read. MDX gives us enough flexibility to add interactive examples down the line without switching tools.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Changed: The Look 🎨
&lt;/h2&gt;

&lt;p&gt;This is where I spent more time than I expected.&lt;/p&gt;

&lt;p&gt;The old project was visually generic. Default colors, default fonts, nothing that connected it to anything else I build. It could have belonged to anyone.&lt;/p&gt;

&lt;p&gt;For Spellbook of Prompt I brought in my brand colors and made it feel like part of the same ecosystem as my personal site and other projects under Domenico Tenace Open Labs. It's a small thing, but it matters. When you open the docs, you immediately get a sense that someone cared about this, not just about the content but about how it looks.&lt;/p&gt;

&lt;p&gt;Consistency across projects builds trust. And building trust was part of the point.&lt;/p&gt;




&lt;h2&gt;
  
  
  Model-Agnostic by Design 🌍
&lt;/h2&gt;

&lt;p&gt;One thing I wanted to be clear about from the start: Spellbook of Prompt is not tied to any specific AI model.&lt;/p&gt;

&lt;p&gt;Most prompts here work across ChatGPT, Claude, Gemini, and any other LLM you're using. Where there are differences in behavior across models, the documentation mentions it. The collection is validated across at least two different models before anything gets merged.&lt;/p&gt;

&lt;p&gt;This matters because the AI landscape changes fast. Tying a prompt collection to a specific model would make half of it obsolete every few months.&lt;/p&gt;




&lt;h2&gt;
  
  
  It's Open Source and You Can Contribute 🤝
&lt;/h2&gt;

&lt;p&gt;Spellbook of Prompt is fully open source under MIT, and contributions are very welcome.&lt;/p&gt;

&lt;p&gt;If you have a prompt that works well and you've tested it properly, opening a PR is straightforward. The guidelines are in CONTRIBUTING.md and they're simple: keep prompts concise, include at least one example, validate across multiple models, and don't include sensitive data.&lt;/p&gt;

&lt;p&gt;The bar isn't high. The point is quality over quantity. I'd rather have 50 excellent prompts than 500 mediocre ones.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Next 🚀
&lt;/h2&gt;

&lt;p&gt;There's still a lot to add. The categories are in place but some of them are thin. The live documentation site is up and running at &lt;a href="https://spellbook-of-prompt.netlify.app" rel="noopener noreferrer"&gt;spellbook-of-prompt.netlify.app&lt;/a&gt;, and I'll keep adding prompts regularly.&lt;/p&gt;

&lt;p&gt;A few things on the roadmap:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Interactive prompt examples directly in the docs&lt;/li&gt;
&lt;li&gt;A tagging system for filtering by LLM compatibility&lt;/li&gt;
&lt;li&gt;More prompts for developer workflows (CI/CD explanations, commit messages, PR descriptions)&lt;/li&gt;
&lt;li&gt;Better search across the full collection&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Final Thoughts 🌟
&lt;/h2&gt;

&lt;p&gt;Sometimes a project needs to die to become something better. Daily Prompt served its purpose, but it had hit a ceiling. Spellbook of Prompt is what it should have been from the beginning, cleaner, more organized, and actually worth sharing.&lt;/p&gt;

&lt;p&gt;If you work with AI tools regularly and you keep writing the same prompts from scratch every time, this might save you some time. Go browse the collection, grab what's useful, and if you have something good to add, open a PR.&lt;/p&gt;

&lt;p&gt;The spellbook is open. 🔥&lt;/p&gt;

&lt;p&gt;Happy coding! ✨&lt;/p&gt;




&lt;p&gt;Hi 👋🏻&lt;br&gt;
My name is Domenico, software developer passionate of Open Source, I write article about it for share my knowledge and experience.&lt;br&gt;
Don't forget to visit my Linktree to discover my links and to check out Domenico Tenace Open Labs for my open-source projects! 🫰🏻&lt;/p&gt;

&lt;p&gt;🌲 Linktree: &lt;a href="https://linktr.ee/domenicotenace" rel="noopener noreferrer"&gt;https://linktr.ee/domenicotenace&lt;/a&gt;&lt;br&gt;
🐙 Domenico Tenace Open Labs: &lt;a href="https://github.com/Domenico-Tenace-Open-Labs" rel="noopener noreferrer"&gt;https://github.com/Domenico-Tenace-Open-Labs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Follow me on dev.to for more articles 👇&lt;/p&gt;


&lt;div class="ltag__user ltag__user__id__985143"&gt;
    &lt;a href="/dvalin99" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media2.dev.to/dynamic/image/width=150,height=150,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F985143%2Fc4c372a7-0b38-4f9e-b206-7ed65597ea31.png" alt="dvalin99 image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/dvalin99"&gt;Domenico Tenace&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/dvalin99"&gt;Passionate about the IT world and everything related to it ✌🏻
Open Source enthusiastic 🦠&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;If you like my content or want to support my work, you can support me with a small donation. I would be grateful 🥹&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/domenicotenace" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb5vrzbmybu3q0sb5bzs1.png" alt="Buy Me A Coffee" width="545" height="153"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>astro</category>
      <category>productivity</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Pasting Code into AI? Here’s Why Your Legal Team is Sweating</title>
      <dc:creator>Hayk Sargsyan</dc:creator>
      <pubDate>Sun, 28 Jun 2026 19:13:25 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/pasting-code-into-ai-heres-why-your-legal-team-is-sweating-49i8</link>
      <guid>https://dev.to/playfulprogramming/pasting-code-into-ai-heres-why-your-legal-team-is-sweating-49i8</guid>
      <description>&lt;p&gt;The integration of Large Language Models (LLMs) like OpenAI’s GPT-5, Anthropic’s Claude, and Google’s Gemini has fundamentally shifted the engineering landscape. For developers, these tools offer unprecedented velocity. However, blind reliance on public AI models &lt;strong&gt;introduces severe legal, financial, and architectural liabilities&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Understanding these legal pitfalls is no longer optional-it is a core engineering competency.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Core Legal Risks of AI in Development
&lt;/h2&gt;

&lt;p&gt;Using AI tools without guardrails exposes your organization to three primary legal vectors: &lt;strong&gt;Intellectual Property (IP) leakage, copyright infringement, and breach of contract&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Intellectual Property (IP) Leakage&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you paste proprietary code, business logic, or internal database schemas into a public LLM, you may forfeit trade secret protections. Many standard consumer-grade AI terms of service grant the provider the right to use your inputs to train future models. This means your proprietary algorithms could theoretically be generated for a competitor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Copyright Infringement &amp;amp; "Copyleft" Contamination&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;LLMs are trained on massive datasets, including open-source repositories with varying licenses (e.g., GPL, AGPL, MIT).&lt;/p&gt;

&lt;p&gt;An LLM might output a block of code that verbatim matches a copyleft-licensed project (like GPL). If that code is integrated into a commercial product, your organization could legally be forced to open-source its entire codebase.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Breach of Client Contracts and NDAs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Most enterprise software contracts include strict Non-Disclosure Agreements (NDAs) and data-handling clauses. Pasting client code into third-party AI models without explicit authorization directly violates these agreements, risking litigation and immediate contract termination.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu9jlme6706hoglh0k609.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu9jlme6706hoglh0k609.jpg" alt="LLM description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Photo by &lt;a href="https://www.pexels.com/@googledeepmind/" rel="noopener noreferrer"&gt;Google DeepMind&lt;/a&gt; on &lt;a href="https://www.pexels.com/photo/an-artist-s-illustration-of-artificial-intelligence-ai-this-illustration-depicts-language-models-which-generate-text-it-was-created-by-wes-cockx-as-part-of-the-visualising-ai-project-l-18069697/" rel="noopener noreferrer"&gt;Pexels&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why "Blind Copy-Pasting" is a High-Risk Practice
&lt;/h2&gt;

&lt;p&gt;Copying and pasting entire business snippets, complex modules, or sensitive data dumps into tools like Claude or ChatGPT creates distinct liabilities. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pasting entire files often inadvertently includes proprietary APIs, security tokens, internal domain names, and unique business logic.&lt;/li&gt;
&lt;li&gt;Free or standard consumer tiers of Anthropic, OpenAI, and Google retain history by default. Even if you delete the chat, the data may remain on third-party servers for compliance auditing or system optimization.&lt;/li&gt;
&lt;li&gt;When an AI refactors an entire proprietary snippet, it mixes your IP with its statistical training weights. If the output mimics protected code, proving original ownership in a patent or copyright dispute becomes incredibly difficult.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnsfbi5cdw2taguyc3vug.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnsfbi5cdw2taguyc3vug.jpg" alt="Mistakes Image" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Photo by &lt;a href="https://www.pexels.com/@eye4dtail/" rel="noopener noreferrer"&gt;George Becker&lt;/a&gt; on &lt;a href="https://www.pexels.com/photo/1-1-3-374916/" rel="noopener noreferrer"&gt;Pexels&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Paths to Solve the AI Risk Problem
&lt;/h2&gt;

&lt;p&gt;Organizations must move away from ad-hoc AI usage and implement structural, engineered guardrails.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enterprise API Tiers and Zero-Data Retention (ZDR)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Consumer interfaces (like the free web chats) are unsafe for corporate IP&lt;/strong&gt;. Businesses must mandate the use of Enterprise platforms or direct API integrations. Major providers guarantee via enterprise contracts that inputs and outputs are never used for model training and are deleted within a fixed window (typically 30 days).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Self-Hosted and Local LLMs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For highly sensitive core IP, companies should completely cut off third-party network dependencies. Data never leaves the corporate firewall, entirely eliminating third-party data leakage risks. Implement automated safety checks in the CI/CD pipeline. Use tools like GitHub Copilot’s built-in duplication filters or standalone scanners (e.g., Snyk, SonarQube) to catch AI-generated code that matches public repositories before it merges into production.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Developers must treat LLMs as untrusted, highly competent junior interns.&lt;/strong&gt; You guide them, verify their work, and never hand them the keys to the vault.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Never paste real business logic. Replace proprietary class names, variable names, and internal APIs with generic equivalents (e.g., convert &lt;code&gt;calculateCorporateTaxBracket()&lt;/code&gt; to &lt;code&gt;processNumbers())&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use AI to generate architectural patterns, algorithmic logic, or regex patterns rather than copy-pasting entire production files.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Treat AI-generated code with higher skepticism than human code. Review it for security vulnerabilities, licensing compliance, and optimization.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Always verify whether your organization utilizes enterprise-grade agreements with providers like Anthropic or OpenAI before utilizing their web interfaces.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fts1oybjhd889ukh5fjib.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fts1oybjhd889ukh5fjib.jpg" alt="Correct Road" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Photo by &lt;a href="https://www.pexels.com/@christina99999/" rel="noopener noreferrer"&gt;Christina &amp;amp; Peter&lt;/a&gt; on &lt;a href="https://www.pexels.com/photo/path-in-forest-20749988/" rel="noopener noreferrer"&gt;Pexels&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;AI is not going anywhere, and trying to ban its use in development is a losing battle.&lt;/strong&gt; The key to staying competitive as a developer isn't avoiding LLMs - it's mastering the guardrails around them. By treating AI as an untrusted third-party service, sanitizing your inputs, and pushing for enterprise-grade infrastructure, you can leverage the full velocity of generative AI without compromising your company's intellectual property.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>openai</category>
      <category>development</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Web MCP: give some tools to your agent</title>
      <dc:creator>Nicolas Frizzarin</dc:creator>
      <pubDate>Thu, 11 Jun 2026 15:50:17 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/web-mcp-give-some-tools-to-your-agent-23o2</link>
      <guid>https://dev.to/playfulprogramming/web-mcp-give-some-tools-to-your-agent-23o2</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Nowadays, AI agents are becoming increasingly powerful at assisting users in their daily web activities. However, we cannot yet allow them to act completely autonomously—there is still a risk of them clicking on the wrong elements, for instance.&lt;/p&gt;

&lt;p&gt;In theory, these agents are capable of performing impressive tasks, provided they are guided step-by-step through the interface. The challenge here is not a lack of intelligence in the model, nor a shortage of web APIs to expose data to the agent. The core issue lies in the fact that the agent must currently "guess" its way through applications that were designed exclusively for humans.&lt;/p&gt;

&lt;p&gt;This is precisely the problem that WebMCP is here to solve.&lt;/p&gt;

&lt;p&gt;It is important to note that these are not intended to replace standard APIs as access points for an application. Instead, they provide a structured way for a web application to "instruct" the AI agent used in the browser on how to navigate its interface. This results in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fewer misplaced clicks.&lt;/li&gt;
&lt;li&gt;Less trial-and-error when interacting with the UI.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When utilized to their full potential, WebMCPs could redefine the user experience in the coming years.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is WEBMCP?
&lt;/h2&gt;

&lt;p&gt;As you may have guessed, WebMCP is a browser-side "guide/standard" for exposing tools to an AI agent directly from an active web page.&lt;/p&gt;

&lt;p&gt;During Google I/O, this new feature was introduced as a way for web applications to describe how a page functions—and what actions can be performed—to various AI agents. As a result, agents can execute these described actions faster, more efficiently, and with greater precision.&lt;/p&gt;

&lt;p&gt;Unsurprisingly, the syntax for creating these descriptions relies on JavaScript functions. These functions take natural language descriptions as parameters, along with structured schemas directly exposed from the web page.&lt;/p&gt;

&lt;p&gt;This is exactly where the power of WebMCP lies.&lt;/p&gt;

&lt;p&gt;Today, while we have Playwright (designed for end-to-end testing of web applications) and Playwright MCP (which extends this model to LLMs), WebMCP sits right at the intersection. It allows a page to effectively communicate to the agent: "Here are the actions you can perform on this page, how it works, and how you can trigger them."&lt;/p&gt;

&lt;h2&gt;
  
  
  Difference between WebMCP | MCP | Automation
&lt;/h2&gt;

&lt;p&gt;At first glance, it may seem like all these approaches are similar and perform the same functions. In reality, each serves a well defined purpose, and they are highly complementary. To better understand the distinctions between them, let’s look at things from an AI integration perspective.&lt;/p&gt;

&lt;h3&gt;
  
  
  Backend MCP
&lt;/h3&gt;

&lt;p&gt;At its core, an MCP server acts as a specialized bridge between AI models and external systems. It functions by providing a direct connection to APIs, effectively removing the friction typically involved in integrating new tools. By establishing a structured framework for data access, it ensures that the information exposed to the agent is organized, predictable, and secure. This architecture makes it an ideal solution for executing data-driven actions, allowing AI agents to perform complex, precise tasks with the reliability required for production grade applications.&lt;/p&gt;

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

&lt;p&gt;Traditional automation concepts rely on mimicking user behavior to interact with the web. They reproduce human-like interactions, such as clicking buttons or scrolling through pages, and can access any element within the UI by targeting it directly in the DOM. A key characteristic of these methods is that they do not require a predefined data structure, as they operate by observing the visual state of the application. However, because they are so tightly coupled to the underlying HTML structure, the main flow can be quite brittle; even minor UI changes often cause the automation to break, requiring constant maintenance.&lt;/p&gt;

&lt;h3&gt;
  
  
  WebMCP
&lt;/h3&gt;

&lt;p&gt;By design, it shares the current application context directly with the AI, moving beyond what is merely visible on the screen. It structures and describes UI actions, providing the agent with a clear map of what is possible rather than forcing it to guess. This results in a highly reliable, context-aware interaction model that significantly reduces errors. Furthermore, the architecture is designed with human-in-the-loop capabilities at its core, ensuring that users maintain oversight and can intervene whenever necessary for sensitive or complex workflows.&lt;/p&gt;

&lt;h3&gt;
  
  
  When to use what: rules to apply.
&lt;/h3&gt;

&lt;p&gt;To ensure your AI agent performs at its best, it is important to select the right integration strategy based on your specific requirements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When an agent requires direct, structured access to data without interacting with a live web page, an MCP server is the ideal solution.&lt;/li&gt;
&lt;li&gt;When you need to interact with a web interface exactly like a human would—whether for automated testing, task execution, or full application usage—browser automation is the right choice.&lt;/li&gt;
&lt;li&gt;When a user is already actively navigating your web application and requires an agent that can interact with the entire page with high precision, WebMCP is the optimal path forward.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Different layers, different jobs.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use WEBMCP
&lt;/h2&gt;

&lt;p&gt;It is worth noting that, for now, WebMCP is only available in Chrome starting from version 149 (with a strong drive to integrate this feature into the Baseline movement).&lt;/p&gt;

&lt;p&gt;To enable this functionality in Chrome today, you need to use a feature flag:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to &lt;em&gt;chrome://flags&lt;/em&gt; in your browser.&lt;/li&gt;
&lt;li&gt;Search for and enable the &lt;em&gt;enable-webmcp-testing flag&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Relaunch your browser to apply the changes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There are two primary ways to utilize the WebMCP APIs to configure the tools exposed by your page:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Declarative API&lt;/strong&gt;: This method enables you to create WebMCP tools simply by adding annotations to your standard HTML forms, making the integration process more streamlined and semantic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Imperative API:&lt;/strong&gt; This approach allows you to define custom tools such as form submission, navigation, or other specialized actions directly using standard JavaScript functions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Defining tools using the Imperative API
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;modelContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;registerTool&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;search_product&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;search product based on a user search input&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="na"&gt;inputSchema&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;"&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;search&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nl"&gt;required&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="s1"&gt;search&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nl"&gt;outputSchema&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;List of products corresponding to the search&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; 
  &lt;span class="nl"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;search&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;search&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;products&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;?search=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;search&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;json&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;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;products&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;h3&gt;
  
  
  Defining Form tool with the Declarative API
&lt;/h3&gt;

&lt;p&gt;As previously mentioned, the Declarative API allows you to create form-based tools using annotations. More specifically, it leverages standard HTML attributes on your forms to define and manage how the tool is created.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;toolname=&lt;/span&gt;&lt;span class="s"&gt;"supportRequestTool"&lt;/span&gt;
  &lt;span class="na"&gt;tooldescription=&lt;/span&gt;&lt;span class="s"&gt;"Submit a request for support."&lt;/span&gt;
  &lt;span class="na"&gt;action=&lt;/span&gt;&lt;span class="s"&gt;"/submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;First Name&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;firstName&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"lastName"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Last Name&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;lastName&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;select&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"select"&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt; 
    &lt;span class="na"&gt;toolparamdescription=&lt;/span&gt;&lt;span class="s"&gt;"Determines what team this request is routed to."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"Customer happiness team"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Return my purchase.&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"Distribution team"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Check where my package is.&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"Website support team"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Get help on the website.&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/select&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;submit&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Submit&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The declaration process relies on specific attributes to define your tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;toolname&lt;/code&gt;: Used to assign a specific name to your tool, reflecting its purpose.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tooldescription&lt;/code&gt;: Used to provide a clear explanation of the action the tool performs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In practice, when the agent invokes the &lt;code&gt;supportRequestTool&lt;/code&gt;, the browser brings the corresponding form to the foreground and fills out the fields while keeping the form visible to the user. Note that if you remove either the &lt;code&gt;toolname&lt;/code&gt; or &lt;code&gt;tooldescription&lt;/code&gt; attribute, the tool will be automatically unregistered and become inaccessible to the agent.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;toolparamdescription&lt;/code&gt;: This optional attribute allows you to map a specific element to a detailed description. If this attribute is omitted, the agent will default to using the field's label as the description.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Security
&lt;/h2&gt;

&lt;p&gt;As a reminder, LLMs process all text—including instructions and user data—as a single sequence of tokens. Consequently, once your application implements the WebMCP feature, it becomes susceptible to indirect prompt injection, where malicious instructions can be hidden within the content.&lt;/p&gt;

&lt;p&gt;To mitigate these risks, here are several security recommendations for implementing WebMCP:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;untrustedContentHint&lt;/code&gt;: Use this attribute to signal to the agent that the data originates from an external source, prompting it to exercise greater vigilance.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;readOnlyHint&lt;/code&gt;: Apply this attribute to tools that should not modify data states, ensuring they require explicit agent confirmation before execution.&lt;/li&gt;
&lt;li&gt;Character budgets: Define strict character limits for your tool names and descriptions to prevent prompt-injection attempts via long, malicious strings.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;exposedTo&lt;/code&gt;: Use this property to restrict access to your tools, limiting them to specific, trusted domains.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is important to remember that by default, tools are only exposed to the AI agent and are not accessible to other websites or iframes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;WebMCP represents a fundamental shift in how AI agents interact with the web. We are moving beyond the era of "computer-use stunts" where agents must guess intent from messy interfaces toward a model of direct, structured cooperation between sites and assistants.&lt;/p&gt;

&lt;p&gt;By exposing structured actions and context, WebMCP allows the browser to share what it already knows: the current page, the user's session, and the precise moment help is needed. While backend integrations remain the best fit for bulk data processing, WebMCP is the optimal path for sites that want to provide a reliable, context-aware experience during live navigation.&lt;/p&gt;

&lt;p&gt;We have only scratched the surface. In our next article, we will move from theory to practice by diving deep into implementation join us as we explore how to seamlessly integrate WebMCP into Angular applications.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>web</category>
      <category>ai</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Google AI Studio: The Playground Every Developer Should Know About 🎮</title>
      <dc:creator>Domenico Tenace</dc:creator>
      <pubDate>Fri, 05 Jun 2026 07:00:00 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/google-ai-studio-the-playground-every-developer-should-know-about-19bd</link>
      <guid>https://dev.to/playfulprogramming/google-ai-studio-the-playground-every-developer-should-know-about-19bd</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;Hey everyone 👋&lt;/p&gt;

&lt;p&gt;If you've ever wanted to experiment with Gemini models, build AI-powered features, or grab an API key without going through a complex setup, &lt;strong&gt;Google AI Studio&lt;/strong&gt; is the tool you're looking for.&lt;/p&gt;

&lt;p&gt;It's free, it's browser-based, and it's probably the fastest way to go from "I have an idea" to "I have working code." Today I'll walk you through what it is, what you can actually do with it, and why it belongs in every developer's toolkit.&lt;/p&gt;

&lt;p&gt;Let's dive in! 🤙&lt;/p&gt;




&lt;h2&gt;
  
  
  What Is Google AI Studio? 🤔
&lt;/h2&gt;

&lt;p&gt;Google AI Studio is a web-based platform where you can interact with Google's AI models, prototype ideas, fine-tune behavior, and export working code, all without writing a single line of infrastructure.&lt;/p&gt;

&lt;p&gt;Think of it as a sandbox. You can test prompts, switch between Gemini models, tweak parameters, and when something works, click "Get Code" to get a ready-to-use snippet in Python, JavaScript, or REST. No cloud setup, no billing configuration, no long onboarding. Just go to &lt;a href="https://aistudio.google.com" rel="noopener noreferrer"&gt;aistudio.google.com&lt;/a&gt;, sign in with your Google account, and you're in.&lt;/p&gt;

&lt;p&gt;It sits at the intersection of playground and development tool. Researchers use it to experiment. Developers use it to prototype. Teams use it to validate ideas before committing to a full integration.&lt;/p&gt;




&lt;h2&gt;
  
  
  What You Actually Need It For 💡
&lt;/h2&gt;

&lt;p&gt;There are a few scenarios where Google AI Studio becomes indispensable:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Getting a Gemini API Key:&lt;/strong&gt;&lt;br&gt;
This is often the first reason developers land on AI Studio. It's the official way to get a Gemini API key for free, which you then use in your own applications, in tools like Gemini CLI, Antigravity, or any custom integration. No credit card required for the free tier.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Testing Prompts Before Hardcoding Them:&lt;/strong&gt;&lt;br&gt;
Prompt engineering is trial and error. AI Studio gives you a fast feedback loop where you can iterate on prompts interactively, see the output, adjust, and repeat, before embedding anything in your codebase.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exploring Model Capabilities:&lt;/strong&gt;&lt;br&gt;
Not sure if Gemini can handle your specific use case? Test it directly. Upload images, audio, documents, or code and see how different models respond. The multimodal support is all accessible through the UI.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prototyping Features Quickly:&lt;/strong&gt;&lt;br&gt;
Even a small team can use it to create prototypes in days instead of weeks. The combination of interactive prompting and instant code export makes it genuinely fast to go from idea to proof of concept.&lt;/p&gt;


&lt;h2&gt;
  
  
  How It Works 🔧
&lt;/h2&gt;

&lt;p&gt;The interface is organized around a few core concepts:&lt;/p&gt;
&lt;h3&gt;
  
  
  Prompts and Conversations
&lt;/h3&gt;

&lt;p&gt;When you open AI Studio, you can start a new prompt immediately. You choose between three modes:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Chat Prompts:&lt;/strong&gt;&lt;br&gt;
Multi-turn conversations where you can test how the model handles back-and-forth dialogue. Perfect for chatbots, assistants, or any conversational feature.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stream Mode:&lt;/strong&gt;&lt;br&gt;
Designed for real-time interactivity, it includes webcam integration, screen sharing, and live guidance. This is the mode for live, low-latency applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Structured Output:&lt;/strong&gt;&lt;br&gt;
Force the model to respond in JSON format with a schema you define. Essential when you need predictable, parseable output to feed into your app.&lt;/p&gt;
&lt;h3&gt;
  
  
  Model Selection
&lt;/h3&gt;

&lt;p&gt;The platform features a multi-model playground allowing you to switch between models seamlessly while working. You can compare responses between Gemini 2.5 Pro, Gemini 2.5 Flash, and other variants side by side. Each model has different trade-offs between speed, cost, and reasoning depth, and AI Studio is the best place to understand those differences before committing to one.&lt;/p&gt;
&lt;h3&gt;
  
  
  System Instructions
&lt;/h3&gt;

&lt;p&gt;This is where it gets interesting for developers. You can set a system prompt that shapes the model's behavior, persona, and constraints for the entire session. This is exactly how you'd configure an AI assistant for your product, and you can refine it here until it behaves exactly how you want.&lt;/p&gt;
&lt;h3&gt;
  
  
  Parameters and Controls
&lt;/h3&gt;

&lt;p&gt;On every prompt, you have direct control over:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Temperature&lt;/strong&gt;: How creative or deterministic the output is&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Max output tokens&lt;/strong&gt;: Limit the response length&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Top-P and Top-K&lt;/strong&gt;: Fine-grained sampling controls&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Safety settings&lt;/strong&gt;: Adjust content filtering thresholds&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Changing these and seeing how responses shift in real time is one of the most educational things you can do as someone building with AI.&lt;/p&gt;
&lt;h3&gt;
  
  
  Get Code
&lt;/h3&gt;

&lt;p&gt;Once you have a prompt and configuration that works, you can click "Get Code" to instantly generate a working code snippet in Python, Node.js, or REST that you can use to integrate that functionality into your own application via the Gemini API.&lt;/p&gt;

&lt;p&gt;This is the feature that saves the most time. You iterate in the UI, then export the exact configuration as runnable code. No manual translation needed.&lt;/p&gt;


&lt;h2&gt;
  
  
  Multimodal: More Than Just Text 🌈
&lt;/h2&gt;

&lt;p&gt;One of AI Studio's strongest points is how naturally it handles multiple input types. You can drag and drop into a prompt:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Images (for visual analysis, OCR, layout understanding)&lt;/li&gt;
&lt;li&gt;PDFs and documents (for summarization, Q&amp;amp;A, data extraction)&lt;/li&gt;
&lt;li&gt;Audio files (for transcription or analysis)&lt;/li&gt;
&lt;li&gt;Videos (for content understanding with timestamps)&lt;/li&gt;
&lt;li&gt;URLs (for web content analysis directly)&lt;/li&gt;
&lt;li&gt;Code files (for explanation, review, or refactoring)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Generative Media Kit unlocks creative potential with tools for generating images, speech, music, and videos. This makes AI Studio useful well beyond pure text use cases.&lt;/p&gt;


&lt;h2&gt;
  
  
  Free vs. Paid: What's the Difference? 💰
&lt;/h2&gt;

&lt;p&gt;AI Studio has a generous free tier, but there are real differences worth knowing:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Free Tier:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Access to most Gemini models&lt;/li&gt;
&lt;li&gt;Rate-limited API calls (enough for prototyping and personal projects)&lt;/li&gt;
&lt;li&gt;Your prompts and data may be used to improve Google's models&lt;/li&gt;
&lt;li&gt;No charge, just a Google account&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Paid Tier (via Gemini API billing):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Higher rate limits and quotas&lt;/li&gt;
&lt;li&gt;Your data is not used for model training, which is a necessity for most commercial or sensitive applications&lt;/li&gt;
&lt;li&gt;Access to advanced features like caching and batch processing&lt;/li&gt;
&lt;li&gt;Suitable for production applications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For individual exploration, side projects, and prototyping, the free tier is more than enough. For anything you're shipping to users with sensitive data, upgrade before going live.&lt;/p&gt;


&lt;h2&gt;
  
  
  AI Studio vs. Vertex AI: Which One? 🤷
&lt;/h2&gt;

&lt;p&gt;A common question for developers already in the Google Cloud ecosystem. The short answer:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Google AI Studio&lt;/strong&gt; is for individuals, developers, and fast prototyping. Browser-based, simple setup, no infrastructure knowledge required.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vertex AI&lt;/strong&gt; is for teams, enterprises, and production-scale deployments. More powerful, more complex, integrates with the full Google Cloud stack, and requires GCP setup and billing configuration.&lt;/p&gt;

&lt;p&gt;If you're just getting started or working on a side project, AI Studio is the right choice. If you're building a production system that needs autoscaling, monitoring, and enterprise compliance, you'll eventually migrate to Vertex AI, but start in AI Studio first.&lt;/p&gt;


&lt;h2&gt;
  
  
  Practical Use Cases 🛠️
&lt;/h2&gt;

&lt;p&gt;Here's how I actually use Google AI Studio in my workflow:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Validating prompt ideas for Gemini CLI Skills:&lt;/strong&gt;&lt;br&gt;
Before writing a SKILL.md, I test the core instructions in AI Studio to see how the model responds. If it doesn't behave as expected there, it won't behave as expected in the terminal either.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Grabbing API keys for new projects:&lt;/strong&gt;&lt;br&gt;
Every time I start a new project that needs Gemini integration, AI Studio is where I go first to create a key.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Understanding model differences:&lt;/strong&gt;&lt;br&gt;
When deciding between Gemini 2.5 Pro and Flash for a specific task, I run the same prompt against both in AI Studio and compare speed vs. quality trade-offs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exporting prompt configurations:&lt;/strong&gt;&lt;br&gt;
When a prompt works well in AI Studio, I click "Get Code" and drop the exported snippet directly into my project as a starting point.&lt;/p&gt;


&lt;h2&gt;
  
  
  Final Thoughts 🌟
&lt;/h2&gt;

&lt;p&gt;Google AI Studio is the kind of tool that sounds simple until you realize how much time it saves. It's not trying to replace your IDE or your production infrastructure. It's the place you go to think, experiment, and validate before committing to anything.&lt;/p&gt;

&lt;p&gt;If you're building with Gemini, it's effectively mandatory. And even if you're just AI-curious and want to understand what these models can actually do, spending an hour in AI Studio will teach you more than reading documentation for days.&lt;/p&gt;

&lt;p&gt;Free, browser-based, no setup. There's really no reason not to try it.&lt;/p&gt;

&lt;p&gt;Happy coding! ✨&lt;/p&gt;



&lt;p&gt;Hi 👋🏻&lt;br&gt;
My name is Domenico, software developer passionate of Open Source, I write article about it for share my knowledge and experience.&lt;br&gt;
Don't forget to visit my Linktree to discover my links and to check out Domenico Tenace Open Labs for my open-source projects! 🫰🏻&lt;/p&gt;

&lt;p&gt;🌲 Linktree: &lt;a href="https://linktr.ee/domenicotenace" rel="noopener noreferrer"&gt;https://linktr.ee/domenicotenace&lt;/a&gt;&lt;br&gt;
🐙 Domenico Tenace Open Labs: &lt;a href="https://github.com/Domenico-Tenace-Open-Labs" rel="noopener noreferrer"&gt;https://github.com/Domenico-Tenace-Open-Labs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Follow me on dev.to for more articles 👇&lt;/p&gt;


&lt;div class="ltag__user ltag__user__id__985143"&gt;
    &lt;a href="/dvalin99" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media2.dev.to/dynamic/image/width=150,height=150,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F985143%2Fc4c372a7-0b38-4f9e-b206-7ed65597ea31.png" alt="dvalin99 image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/dvalin99"&gt;Domenico Tenace&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/dvalin99"&gt;Passionate about the IT world and everything related to it ✌🏻
Open Source enthusiastic 🦠&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;If you like my content or want to support my work, you can support me with a small donation. I would be grateful 🥹&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/domenicotenace" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb5vrzbmybu3q0sb5bzs1.png" alt="Buy Me A Coffee" width="545" height="153"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>google</category>
      <category>learngoogleaistudio</category>
    </item>
    <item>
      <title>Gemini CLI Skills: Teaching Your Terminal Agent How to Think 🧠</title>
      <dc:creator>Domenico Tenace</dc:creator>
      <pubDate>Tue, 26 May 2026 06:00:00 +0000</pubDate>
      <link>https://dev.to/playfulprogramming/gemini-cli-skills-teaching-your-terminal-agent-how-to-think-2541</link>
      <guid>https://dev.to/playfulprogramming/gemini-cli-skills-teaching-your-terminal-agent-how-to-think-2541</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;Hey everyone 👋&lt;/p&gt;

&lt;p&gt;If you've been using Gemini CLI for a while, you've probably noticed that the agent is great at general tasks but sometimes needs guidance for specific workflows. That's exactly what &lt;strong&gt;Skills&lt;/strong&gt; are for.&lt;/p&gt;

&lt;p&gt;Skills are one of the most underrated features of Gemini CLI, and once you start using them, you'll wonder how you ever managed without. Today I'll walk you through what they are, how to create them, and a real-world example you can steal immediately.&lt;/p&gt;

&lt;p&gt;Let's start! 🤙&lt;/p&gt;




&lt;h2&gt;
  
  
  Quick Note Before We Start 📢
&lt;/h2&gt;

&lt;p&gt;Google has announced that Gemini CLI will transition to &lt;strong&gt;Antigravity CLI&lt;/strong&gt; on June 18th for free tier and Google One users. The good news? Skills work the same way in both tools, so everything you learn here applies directly to Antigravity CLI. If you're already in the migration window, just replace "Gemini CLI" with "Antigravity CLI" in your head.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Are Skills? 🤔
&lt;/h2&gt;

&lt;p&gt;Think about the difference between a generalist and a specialist. A generalist knows a bit of everything but lacks deep expertise in any one area. A specialist has deep knowledge in their domain and knows exactly how to approach problems in that field.&lt;/p&gt;

&lt;p&gt;By default, Gemini CLI is a generalist. It knows a lot, but it doesn't know your specific project, your team's conventions, or the exact steps your deployment pipeline requires.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Skills turn the generalist into a specialist.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A Skill is a self-contained directory that packages specialized instructions and context into a discoverable capability. Unlike &lt;code&gt;GEMINI.md&lt;/code&gt; files that are always loaded into context, Skills are loaded &lt;strong&gt;on demand&lt;/strong&gt;, only when the agent determines they're relevant to your current task.&lt;/p&gt;

&lt;p&gt;This distinction matters a lot. If you put everything into &lt;code&gt;GEMINI.md&lt;/code&gt;, you quickly saturate the model's context window with information that's irrelevant to most tasks. Skills solve this with Progressive Disclosure, the agent sees a brief description of every skill, and only loads the full instructions when the skill is actually needed.&lt;/p&gt;

&lt;p&gt;The result: the right knowledge, at the right time, without cluttering the context.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Anatomy of a Skill 🏗️
&lt;/h2&gt;

&lt;p&gt;A Skill is just a folder with a specific structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.gemini/skills/
└── my-skill/
    ├── SKILL.md          # The main definition file (required)
    ├── examples/         # Reference implementations (optional)
    ├── resources/        # Templates and assets (optional)
    └── scripts/          # Helper scripts (optional)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The only required file is &lt;code&gt;SKILL.md&lt;/code&gt;. Everything else is supporting material that the agent can reference when the skill is activated.&lt;/p&gt;
&lt;h3&gt;
  
  
  The SKILL.md File
&lt;/h3&gt;

&lt;p&gt;This is the heart of every skill. It has two parts: a frontmatter header and a body with instructions.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;your-skill-name&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;What this skill does. Use when you need to...&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="gh"&gt;# Skill Title&lt;/span&gt;

Your instructions here.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The frontmatter is crucial. The &lt;code&gt;description&lt;/code&gt; field is what the agent reads at the start of every session to decide whether to load this skill. Write it clearly and specifically, a vague description will cause the skill to be activated at the wrong times (or never).&lt;/p&gt;

&lt;p&gt;Good description:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Reviews code changes for security vulnerabilities, performance issues, and adherence to project conventions. Use when reviewing PRs or checking code before merging."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Bad description:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Code review stuff."&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  Where to Put Your Skills 📁
&lt;/h2&gt;

&lt;p&gt;Gemini CLI discovers skills from two locations, and which one you use depends on scope:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Project Skills&lt;/strong&gt; (&lt;code&gt;.gemini/skills/&lt;/code&gt; in your repo):&lt;br&gt;
These are tied to a specific project. Commit them to version control and your whole team gets the same specialized behavior. Perfect for project-specific workflows like deployment steps, framework conventions, or codebase-specific review guidelines.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Global Skills&lt;/strong&gt; (&lt;code&gt;~/.gemini/skills/&lt;/code&gt; in your home directory):&lt;br&gt;
These work across all your projects. Perfect for personal workflows, general coding standards, or tools you use everywhere.&lt;/p&gt;

&lt;p&gt;The mental model: if a skill is useful for your team and the project, put it in the repo. If it's personal productivity, put it globally.&lt;/p&gt;


&lt;h2&gt;
  
  
  Creating Your First Skill: Step by Step 🔧
&lt;/h2&gt;

&lt;p&gt;Let's create a practical skill for code review. Here's the full process:&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 1: Create the Directory
&lt;/h3&gt;

&lt;p&gt;For a project skill:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; .gemini/skills/code-review
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;For a global skill:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; ~/.gemini/skills/code-review
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Step 2: Write the SKILL.md
&lt;/h3&gt;

&lt;p&gt;Create &lt;code&gt;.gemini/skills/code-review/SKILL.md&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;code-review&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Reviews code changes for bugs, security issues, performance problems, and style consistency. Use when reviewing PRs, checking diffs, or auditing code quality before merging.&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="gh"&gt;# Code Review Skill&lt;/span&gt;

You are an expert code reviewer. When reviewing code, follow this checklist systematically.

&lt;span class="gu"&gt;## Review Checklist&lt;/span&gt;

&lt;span class="gu"&gt;### Correctness&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Does the code do what it's supposed to do?
&lt;span class="p"&gt;-&lt;/span&gt; Are there logic errors or off-by-one mistakes?
&lt;span class="p"&gt;-&lt;/span&gt; Are all edge cases handled?

&lt;span class="gu"&gt;### Security&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Are inputs validated and sanitized?
&lt;span class="p"&gt;-&lt;/span&gt; Are there potential injection vulnerabilities?
&lt;span class="p"&gt;-&lt;/span&gt; Is sensitive data handled securely?

&lt;span class="gu"&gt;### Performance&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Are there unnecessary loops or redundant operations?
&lt;span class="p"&gt;-&lt;/span&gt; Are database queries optimized?
&lt;span class="p"&gt;-&lt;/span&gt; Are there memory leaks or heavy resource usage?

&lt;span class="gu"&gt;### Style and Conventions&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Does the code follow the project's naming conventions?
&lt;span class="p"&gt;-&lt;/span&gt; Is the code readable and well-structured?
&lt;span class="p"&gt;-&lt;/span&gt; Are functions small and single-responsibility?

&lt;span class="gu"&gt;## How to Provide Feedback&lt;/span&gt;

For each issue found:
&lt;span class="p"&gt;1.&lt;/span&gt; Specify the exact location (file and line number)
&lt;span class="p"&gt;2.&lt;/span&gt; Explain what the problem is and why it matters
&lt;span class="p"&gt;3.&lt;/span&gt; Suggest a concrete fix with a code example when possible

End the review with a summary: overall assessment (Approve / Request Changes / Needs Discussion) and a brief explanation.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Step 3: Verify the Skill Is Discovered
&lt;/h3&gt;

&lt;p&gt;Start Gemini CLI in your project directory and run:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/skills
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You should see your &lt;code&gt;code-review&lt;/code&gt; skill listed. If it's not there, double-check the directory structure and file naming.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 4: Use It
&lt;/h3&gt;

&lt;p&gt;Just work normally. When you ask for a code review:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Review the changes in auth.js before I merge this PR
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Gemini CLI sees the request, matches it against the skill description, loads the full &lt;code&gt;SKILL.md&lt;/code&gt;, and follows your checklist systematically. You don't need to explicitly invoke the skill, it happens automatically.&lt;/p&gt;


&lt;h2&gt;
  
  
  A Practical Example: Conventional Commits Skill 📝
&lt;/h2&gt;

&lt;p&gt;Let me share another skill I use constantly, one that enforces Conventional Commits format across all my projects.&lt;/p&gt;

&lt;p&gt;Create &lt;code&gt;.gemini/skills/conventional-commits/SKILL.md&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;conventional-commits&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Generates commit messages following the Conventional Commits specification. Use when creating, reviewing, or suggesting git commit messages.&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="gh"&gt;# Conventional Commits Skill&lt;/span&gt;

You are an expert at writing clear, structured commit messages following the Conventional Commits 1.0.0 specification.

&lt;span class="gu"&gt;## Format&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;type&amp;gt;&lt;/span&gt;(&lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;): &lt;span class="nt"&gt;&amp;lt;description&amp;gt;&lt;/span&gt;

[optional body]

[optional footer(s)] 

&lt;span class="gu"&gt;## Types&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; &lt;span class="gs"&gt;**feat**&lt;/span&gt;: A new feature
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**fix**&lt;/span&gt;: A bug fix
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**docs**&lt;/span&gt;: Documentation changes only
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**style**&lt;/span&gt;: Formatting changes (no code logic change)
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**refactor**&lt;/span&gt;: Code change that neither fixes a bug nor adds a feature
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**perf**&lt;/span&gt;: Performance improvement
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**test**&lt;/span&gt;: Adding or updating tests
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**chore**&lt;/span&gt;: Build process or auxiliary tool changes

&lt;span class="gu"&gt;## Rules&lt;/span&gt;
&lt;span class="p"&gt;
1.&lt;/span&gt; Use the imperative mood in the description ("add feature" not "added feature")
&lt;span class="p"&gt;2.&lt;/span&gt; Lowercase the entire first line
&lt;span class="p"&gt;3.&lt;/span&gt; No period at the end of the description
&lt;span class="p"&gt;4.&lt;/span&gt; Keep the description under 72 characters
&lt;span class="p"&gt;5.&lt;/span&gt; The body explains "what" and "why", not "how"
&lt;span class="p"&gt;6.&lt;/span&gt; Reference issue numbers in the footer: &lt;span class="sb"&gt;`Closes #123`&lt;/span&gt;

&lt;span class="gu"&gt;## Examples&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; feat(auth): add JWT token refresh logic
&lt;span class="p"&gt;-&lt;/span&gt; fix(api): handle null response from payment provider
&lt;span class="p"&gt;-&lt;/span&gt; docs: update README with pnpm installation steps
&lt;span class="p"&gt;-&lt;/span&gt; refactor(utils): extract string validation to dedicated module 

When suggesting a commit message, always explain your reasoning for the chosen type and scope.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now whenever you ask Gemini CLI to help with a commit:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Write a commit message for the changes I just made to the authentication module
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The agent loads the skill, understands the full convention, and generates a properly formatted message with the right type, scope, and description style.&lt;/p&gt;


&lt;h2&gt;
  
  
  Skills vs. GEMINI.md: When to Use What 🔄
&lt;/h2&gt;

&lt;p&gt;A common question: when should you put something in a Skill vs. in &lt;code&gt;GEMINI.md&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use GEMINI.md for:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Information the agent always needs (project name, tech stack, folder structure)&lt;/li&gt;
&lt;li&gt;General coding standards that apply to every task&lt;/li&gt;
&lt;li&gt;Critical context that should never be missing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Use a Skill for:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Specialized workflows that only run sometimes (deployments, code review, testing)&lt;/li&gt;
&lt;li&gt;Deep expertise for a specific domain (security auditing, accessibility checking)&lt;/li&gt;
&lt;li&gt;Complex checklists that would waste context when not needed&lt;/li&gt;
&lt;li&gt;Anything you only need occasionally but need deeply when you do&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The rule of thumb: if you'd be annoyed by the agent using this knowledge on unrelated tasks, it's a skill. If you'd be annoyed if the agent ever lacked this knowledge, it belongs in &lt;code&gt;GEMINI.md&lt;/code&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  Tips for Writing Good Skills 💡
&lt;/h2&gt;

&lt;p&gt;After creating several skills, here's what actually works:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Write narrow descriptions.&lt;/strong&gt; The description is how the agent decides whether to activate the skill. Narrow is better than broad. "Use when reviewing PRs or checking code quality" is better than "Use for coding tasks."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Add explicit "do not use" hints when needed.&lt;/strong&gt; If your skill might be over-activated, add clarity: "Do not use for general coding questions or feature implementation."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keep SKILL.md focused.&lt;/strong&gt; Put detailed examples and templates in the &lt;code&gt;examples/&lt;/code&gt; or &lt;code&gt;resources/&lt;/code&gt; subdirectories. The core &lt;code&gt;SKILL.md&lt;/code&gt; should be scannable and concise.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One skill, one responsibility.&lt;/strong&gt; Don't create a "general development" mega-skill. Create separate skills for deployment, testing, code review, etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test activation.&lt;/strong&gt; After creating a skill, try prompts that should and shouldn't activate it. If it activates when it shouldn't, tighten the description.&lt;/p&gt;


&lt;h2&gt;
  
  
  Final Thoughts 🌟
&lt;/h2&gt;

&lt;p&gt;Skills are a small investment with a big return. You spend 10-15 minutes writing a &lt;code&gt;SKILL.md&lt;/code&gt; once, and the agent follows your exact workflow consistently from that point on.&lt;/p&gt;

&lt;p&gt;The bigger picture: Skills are how you transform Gemini CLI (or Antigravity CLI) from a generic AI assistant into a tool that understands your team, your conventions, and your processes. The more skills you build, the more the agent feels like a teammate rather than a tool.&lt;/p&gt;

&lt;p&gt;Start small, maybe with a code review skill or a commit message skill, and build from there. You'll quickly start noticing the moments where the agent "just knows" what you need, and that's when it clicks.&lt;/p&gt;

&lt;p&gt;Happy coding! ✨&lt;/p&gt;



&lt;p&gt;Hi 👋🏻&lt;br&gt;
My name is Domenico, software developer passionate of Open Source, I write article about it for share my knowledge and experience.&lt;br&gt;
Don't forget to visit my Linktree to discover my links and to check out Domenico Tenace Open Labs for my open-source projects! 🫰🏻&lt;/p&gt;

&lt;p&gt;🌲 Linktree: &lt;a href="https://linktr.ee/domenicotenace" rel="noopener noreferrer"&gt;https://linktr.ee/domenicotenace&lt;/a&gt;&lt;br&gt;
🐙 Domenico Tenace Open Labs: &lt;a href="https://github.com/Domenico-Tenace-Open-Labs" rel="noopener noreferrer"&gt;https://github.com/Domenico-Tenace-Open-Labs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Follow me on dev.to for more articles 👇&lt;/p&gt;


&lt;div class="ltag__user ltag__user__id__985143"&gt;
    &lt;a href="/dvalin99" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media2.dev.to/dynamic/image/width=150,height=150,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F985143%2Fc4c372a7-0b38-4f9e-b206-7ed65597ea31.png" alt="dvalin99 image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/dvalin99"&gt;Domenico Tenace&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/dvalin99"&gt;Passionate about the IT world and everything related to it ✌🏻
Open Source enthusiastic 🦠&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;If you like my content or want to support my work, you can support me with a small donation. I would be grateful 🥹&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/domenicotenace" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb5vrzbmybu3q0sb5bzs1.png" alt="Buy Me A Coffee" width="545" height="153"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>google</category>
      <category>gemini</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
