<?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: IroncladDev</title>
    <description>The latest articles on DEV Community by IroncladDev (@ironcladdev).</description>
    <link>https://dev.to/ironcladdev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F541083%2F53c55576-0bd5-4a23-a0a9-c0850ce24375.png</url>
      <title>DEV Community: IroncladDev</title>
      <link>https://dev.to/ironcladdev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ironcladdev"/>
    <language>en</language>
    <item>
      <title>How NOT to behave in Open Source</title>
      <dc:creator>IroncladDev</dc:creator>
      <pubDate>Sat, 28 Feb 2026 15:12:35 +0000</pubDate>
      <link>https://dev.to/ironcladdev/how-not-to-behave-in-open-source-4n3n</link>
      <guid>https://dev.to/ironcladdev/how-not-to-behave-in-open-source-4n3n</guid>
      <description>&lt;p&gt;A Vegan walks into a smokehouse,&lt;br&gt;
walks up to the counter,&lt;br&gt;
asks to see the manager,&lt;br&gt;
demands that the restaurant offer vegan-friendly options,&lt;br&gt;
hands the manager a cookbook full of vegan-friendly recipes,&lt;br&gt;
gets rejected,&lt;br&gt;
walks out of the restaurant,&lt;br&gt;
and leaves a 1-star review.&lt;/p&gt;

&lt;p&gt;To the average human being, appeasing the specific demands of an individual who has no regard for your time, work, or budget sounds ridiculous. On the other hand, the average human being does not take into consideration someone else's time, work, or budget.&lt;/p&gt;

&lt;p&gt;As an open source maintainer myself, I have come to appreciate the strenuous work of the giants whose shoulders I stand on. I want to surface how much these people are doing, and I want to help you appreciate and contribute in as frictionless a way as possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who is this article for?
&lt;/h2&gt;

&lt;p&gt;Whether you are getting started in Open Source, a vibe coder, or an opencl*w instance, hopefully this article will do you some good.&lt;/p&gt;

&lt;p&gt;This article assumes you have a basic understanding of a version control system like git, and that you have some familiarity with a git hosting provider like Github or Gitlab.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to be a headache for Maintainers
&lt;/h2&gt;

&lt;p&gt;Let's talk about some ways you can be an absolute pain to open source maintainers. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Side effects may include getting bad publicity on social media, getting banned from the project, or just getting butthurt after your issue or pull request was rejected.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  How to get your Issue rejected
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Submit an extremely vague bug report&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Request a port to a different language/framework/operating system&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Pitch a large-scope feature request&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Open a vague PR for the sole purpose of trolling&lt;/strong&gt;&lt;/p&gt;

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

&lt;h3&gt;
  
  
  How to get your Pull Request rejected
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Vibe code a massive feature implementation&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Open a Pull Request that adds your name to README.md&lt;/strong&gt;&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Being a Civilized Contributor
&lt;/h2&gt;

&lt;p&gt;Now that you have a general idea of what not to do, let's go over some ways that will help you work more seamlessly with open source maintainers and contributors.&lt;/p&gt;

&lt;h3&gt;
  
  
  General Etiquette
&lt;/h3&gt;

&lt;p&gt;Applies to both issues and pull requests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Express your Gratitude&lt;/strong&gt; - Open Source Software may be free to use, but time isn't. If a project is important to you or has helped you, &lt;em&gt;express your gratitude to the maintainers, because &lt;strong&gt;that's what keeps them going&lt;/strong&gt;&lt;/em&gt;. If you can spare a few dollars, consider sponsoring the project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Search and Read&lt;/strong&gt; - Are there any duplicate issues similar to yours? Are there any workarounds? Has someone written a blog post to fix the exact issue you're dealing with? Finding an existing solution or a workaround is more valuable than getting a delayed response.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Be Verbose&lt;/strong&gt; - Provide as much information as possible. Cross-reference relevant issues and Pull Requests. Make it easier for the maintainer(s) to help you.&lt;/p&gt;

&lt;h3&gt;
  
  
  Issues
&lt;/h3&gt;

&lt;p&gt;Issues count as contributions on your github graph for a reason. Stop thinking of issues as customer support. Start thinking of issues as a way to &lt;strong&gt;positively contribute&lt;/strong&gt; to the project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before you open an issue&lt;/strong&gt;, take into consideration how much &lt;strong&gt;engineering effort&lt;/strong&gt; is available. How many active maintainers are there? When was the project owner last active? How many open issues are there?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Avoid introducing unnecessary overhead&lt;/strong&gt; - Will your issue provide a solution if completed, or just introduce more problems and overhead? For example, requesting Windows support for a Mac and Linux-only application will come with its own set of problems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Estimate the impact&lt;/strong&gt; - Does your issue describe something with a large impact that affects the majority of the consumer base, or is it very specific to you? Maybe a workaround, forking the repository, or a dependency patch will work better than waiting a few months for the next version to be released.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pull Requests
&lt;/h3&gt;

&lt;p&gt;When opening a pull request, it is important that you adhere to the style guides and conventions specified in the project as much as possible. &lt;/p&gt;

&lt;p&gt;Throwing code at a repository and hoping it gets accepted usually doesn't work. Taking the time to make a clean and beautiful Pull Request shows the maintainers that you really want it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Retain clean commit history&lt;/strong&gt; - Take 30 minutes to learn how to squash, describe, reorder, and rebase commits. Split your changes into small, very verbose commits that cross-reference other related issues and pull requests. Explain &lt;strong&gt;why&lt;/strong&gt; changes are being made, not just &lt;strong&gt;what&lt;/strong&gt; they do. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Automated Testing&lt;/strong&gt; - If there is a testing environment in the project you're contributing to, it doesn't hurt to write a unit/integration test to ensure correct behavior. &lt;/p&gt;

&lt;h3&gt;
  
  
  You as a Maintainer
&lt;/h3&gt;

&lt;p&gt;Being a maintainer or project owner comes with a set of responsibilities. If you want to build a reliable piece of software for people to use, you should dedicate the time and effort to keeping it that way.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Accepting Contributions&lt;/strong&gt; - You as a maintainer should not blindly accept contributions from external contributors without testing and thorough review.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Be Transparent&lt;/strong&gt; - When accepting, rejecting, or commenting on contributions, let the contributor know &lt;strong&gt;why&lt;/strong&gt; you came to your decision.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Be Organized&lt;/strong&gt; - It is extremely important that you as a maintainer are organized in how you manage issues, pull requests, and write commits. Break changes into PRs and commits and describe them in detail. Cross-reference issues and pull requests. Don't close an issue as "completed" if it isn't completed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Being "nice" is not your focus&lt;/strong&gt; - It's okay to be blunt as long as you are verbose. Don't give external contributors the impression that you're going to accept their every contribution. Rejecting a contribution might hurt someone's feelings but won't hurt your project. It's okay to say "no".&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Delegate work when necessary&lt;/strong&gt; - It is unlikely that you can work on your project full-time, because OSS usually doesn't pay the bills. If a past contributor or someone who opened an issue expresses interest in your project, ask them to make a PR which you can later review.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Archiving&lt;/strong&gt; - if you can no longer work on an open source project of yours due to personal reasons, archive it to let people know that development has ceased.&lt;/p&gt;

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

&lt;p&gt;This article just scratches the surface of what all is in being an open source contributor and maintainer.&lt;/p&gt;

&lt;p&gt;If you got something out of the article, I hope you take the time to apply it and make the lives of open source contributors and maintainers easier.&lt;/p&gt;

&lt;p&gt;We're all in this together. Let's share the load.&lt;/p&gt;

</description>
      <category>opensource</category>
    </item>
    <item>
      <title>A Stalemate Between Software Jobs VS AI</title>
      <dc:creator>IroncladDev</dc:creator>
      <pubDate>Fri, 30 Jan 2026 19:07:34 +0000</pubDate>
      <link>https://dev.to/ironcladdev/a-stalemate-between-software-jobs-vs-ai-1l3k</link>
      <guid>https://dev.to/ironcladdev/a-stalemate-between-software-jobs-vs-ai-1l3k</guid>
      <description>&lt;p&gt;AI innovation - an unstoppable force, meets an immmovable object - software jobs. So many arguments. Endless predictions. Countless hours wasted. Neither side is winning.&lt;/p&gt;

&lt;p&gt;If you've read my previous articles and some of my &lt;a href="https://x.com/IroncladDev" rel="noopener noreferrer"&gt;tweets&lt;/a&gt;, I am very skeptical to AI and do not hold to the belief that software jobs will be replaced by it.&lt;/p&gt;

&lt;p&gt;However, the goal of this article is &lt;strong&gt;not&lt;/strong&gt; to win an argument, prove a point, or filter through the noise. I want to &lt;strong&gt;listen&lt;/strong&gt; to the noise, find &lt;strong&gt;where&lt;/strong&gt; it's coming from, and study &lt;strong&gt;why&lt;/strong&gt; the noise is being made.&lt;/p&gt;

&lt;h2&gt;
  
  
  Idle Observers
&lt;/h2&gt;

&lt;p&gt;I will start out by locating &lt;strong&gt;where&lt;/strong&gt; the noise is coming from.&lt;/p&gt;

&lt;p&gt;The majority of people who take part in the argument about AI and Software Jobs are what I refer to as &lt;strong&gt;idle observers&lt;/strong&gt; - people who cheer for their side without taking any course of action to back their beliefs.&lt;/p&gt;

&lt;p&gt;Those who hold to the belief that software will &lt;strong&gt;not be replaced by AI&lt;/strong&gt; are just &lt;strong&gt;sitting ducks&lt;/strong&gt;, waiting for the so-called "AI Bubble" to pop. Sitting idle and hoping to outlast the enemy without taking any course of action whatsoever is &lt;strong&gt;not winning&lt;/strong&gt;. The AI hype train has dragged on long enough to safely assume that there &lt;strong&gt;will be no rapture&lt;/strong&gt; for those who think they know how to code.&lt;/p&gt;

&lt;p&gt;On the other side, people who heavily use vibe coding tools as a means to acquire dopamine and clout while boldly making a claim backed by nothing isn't doing much either.&lt;/p&gt;

&lt;h2&gt;
  
  
  Binding Factors
&lt;/h2&gt;

&lt;p&gt;Now that we know &lt;strong&gt;where&lt;/strong&gt; the noise is coming from, let's talk about &lt;strong&gt;why&lt;/strong&gt; the noise is being made.&lt;/p&gt;

&lt;p&gt;In the ocean of opinions on this topic, I've found that the two primary factors in this argument are &lt;strong&gt;Value&lt;/strong&gt; and &lt;strong&gt;Risk&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Value
&lt;/h2&gt;

&lt;p&gt;Many people don't realize that the term "value" is &lt;strong&gt;subjective&lt;/strong&gt;. In the same sense that a diamond offers little to no value to a starving animal (eating a diamond may provide little relief to a very unintelligent organism), the best sorting algorithm implementation offers little to no value to the average end user.&lt;/p&gt;

&lt;p&gt;Since the argument of AI potentially replacing jobs revolves around the rapid generation of &lt;strong&gt;software projects&lt;/strong&gt;, I will take a moment to cover the &lt;strong&gt;value of software&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Value of Software
&lt;/h3&gt;

&lt;p&gt;In software, there are incompatibilities across operating systems, CPU architecture, and web browsers. A Windows-only application won't be of any value to a Mac user, and vice-versa.&lt;/p&gt;

&lt;p&gt;A content creator may find specific video editing software valuable enough to (God forbid) pay Adobe for it, while others look for alternatives or don't edit videos at all.&lt;/p&gt;

&lt;p&gt;If a software engineer finds a tool that drastically improves his workflow, chances are he probably won't tell his grandmother about it (or any non-technical people for that matter) because he knows it will be of no value to her.&lt;/p&gt;

&lt;p&gt;AI tools are extremely versatile and can provide immediate value to most individuals, espicially when it comes to generating code. Since AI tools can fit the needs of most individuals very closely, people who use them are more likely to share them with others. &lt;/p&gt;

&lt;p&gt;Sharing things that can potentially help others is an &lt;strong&gt;act of kindness&lt;/strong&gt;, and is not necessarily a bad thing. Unless that thing is an AI slop video generator.&lt;/p&gt;

&lt;p&gt;In conclusion, the reason why there is so much hype around AI is because &lt;strong&gt;people find value in it&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Risk
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Risk&lt;/strong&gt; pulls in the opposite direction of &lt;strong&gt;Value&lt;/strong&gt; when it comes to AI-generated code and is primarily what's keeping software jobs rooted in place.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Both humans and AI are unpredictable&lt;/strong&gt;. An employee could randomly choose to steal workplace equipment or commit fraud on the job. Likewise, an LLM may choose to make up something or refuse to tell you something it deems harmful.&lt;/p&gt;

&lt;p&gt;Most people would agree that hiring an experienced worker will result in less risk than hiring an intern. In fact, experienced workers are paid more than their inferior counterparts because of their ability &lt;strong&gt;and&lt;/strong&gt; the lower chance of risk.&lt;/p&gt;

&lt;p&gt;Risk cannot be measured, but it can be &lt;strong&gt;reduced&lt;/strong&gt; with &lt;strong&gt;incentives&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Incentives
&lt;/h3&gt;

&lt;p&gt;A soldier defending his country from the enemy is more likely to fight harder because &lt;strong&gt;he has something to fight for&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Likewise, employees are willing to work because of the &lt;strong&gt;incentive to get paid&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The reason why &lt;strong&gt;most&lt;/strong&gt; people don't play life-threatening practical jokes in the workplace or steal workplace equipment is because they want to &lt;strong&gt;continue&lt;/strong&gt; to get paid.&lt;/p&gt;

&lt;p&gt;Unlike employed humans, LLMs have nothing to lose. No matter how aggressively you form its instructions, it has &lt;strong&gt;no real incentives&lt;/strong&gt; to perform better.&lt;/p&gt;

&lt;p&gt;This is the same reason why communism doesn't work. If someone has all their basic needs met regardless of their contribution to society, there is no real motivation to contribute.&lt;/p&gt;

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

&lt;p&gt;I hope this article gives you a better understanding of both sides and gives you a topological view of how silly we are butting heads against each other whilst accomplishing nothing.&lt;/p&gt;

&lt;p&gt;I want to stop fighting about AI and software jobs. Let's be at peace with each other while we build great things.&lt;/p&gt;

&lt;p&gt;(This does not apply to Communists. I will not be at peace with Communists)&lt;/p&gt;




&lt;p&gt;Original Article Link: &lt;a href="https://x.com/IroncladDev/status/2017006861300494603" rel="noopener noreferrer"&gt;https://x.com/IroncladDev/status/2017006861300494603&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>career</category>
      <category>software</category>
    </item>
    <item>
      <title>It's hard to make money from software alone</title>
      <dc:creator>IroncladDev</dc:creator>
      <pubDate>Thu, 29 Jan 2026 23:03:36 +0000</pubDate>
      <link>https://dev.to/ironcladdev/its-hard-to-make-money-from-software-alone-53gp</link>
      <guid>https://dev.to/ironcladdev/its-hard-to-make-money-from-software-alone-53gp</guid>
      <description>&lt;p&gt;There is more money to be made in the &lt;strong&gt;real, physical world&lt;/strong&gt; than in the Software Industry. This is an &lt;strong&gt;undeniable&lt;/strong&gt; fact that will remain true until the end of time. I say this with confidence because you &lt;strong&gt;can't eat a computer program&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In 2020, I had dreams of owning a successful software business while working at a relaxed desk job. Fast-forward to the present day, and I'm having my doubts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Software as a Product
&lt;/h2&gt;

&lt;p&gt;Video games, desktop apps, mobile apps, streaming services, SaaS products, and Enterprise Software are some of the more &lt;strong&gt;prominent&lt;/strong&gt; digital products we are familiar with.&lt;/p&gt;

&lt;p&gt;Unlike &lt;strong&gt;physical&lt;/strong&gt; products, software is &lt;strong&gt;easy to clone and distribute&lt;/strong&gt;. In order to make a profit, software companies gate certain features of their software by using a &lt;strong&gt;paywall&lt;/strong&gt; and a &lt;strong&gt;database&lt;/strong&gt; to track customers. &lt;/p&gt;

&lt;p&gt;Failure to implement the necessary paywall measures usually results in &lt;strong&gt;piracy&lt;/strong&gt; and &lt;strong&gt;exploitation&lt;/strong&gt;. Piracy itself does not &lt;strong&gt;cost&lt;/strong&gt; the company anything since the cost to create and distribute a new copy of a program is virtually nothing for both parties. Exploitation, in terms of bypassing a paywall, can be different if paying users are permitted to use services that are more expensive to maintain. Both piracy and exploitation can result in a loss of sales and customers.&lt;/p&gt;

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

&lt;p&gt;The majority of software companies are usually closed-source to prevent people from cloning, running, re-distributing, or exploiting their software.&lt;/p&gt;

&lt;h2&gt;
  
  
  Indie Hacking
&lt;/h2&gt;

&lt;p&gt;Indie Hacking, also known as "Independent Hacking" or "Indian(s) Hacking", refers to selling a digital product as an &lt;strong&gt;individual&lt;/strong&gt; without relying on VC funding. I will never understand how the word "Hacking" got into the term, but it is what it is.&lt;/p&gt;

&lt;p&gt;To begin Indie Hacking, you must start a new &lt;strong&gt;side project&lt;/strong&gt;. To start a side project, you must first have &lt;strong&gt;time&lt;/strong&gt;. Mentioning that you are "working on a side project" implies that you either have an &lt;strong&gt;existing project&lt;/strong&gt; or are &lt;strong&gt;employed&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Most indie products end up in abandonment due to lack of sales, or lack of time to maintain it. A lot of people blame this outcome on "&lt;strong&gt;Marketing&lt;/strong&gt;".&lt;/p&gt;

&lt;p&gt;In reality, the success of an indie product is affected by a &lt;strong&gt;variety&lt;/strong&gt; of factors such as marketing, etc.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ideas
&lt;/h3&gt;

&lt;p&gt;The average person &lt;strong&gt;formulates&lt;/strong&gt; more ideas than he &lt;strong&gt;implements&lt;/strong&gt;, which is arguably a good thing.&lt;/p&gt;

&lt;p&gt;Sellers and builders in the software market tend to highlight that "the idea is what matters most". This is sadly true due to the fact that most end users simply hold to the excpectation that a digital product should &lt;strong&gt;work&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The market for &lt;strong&gt;physical&lt;/strong&gt; products is different, as most people would choose to buy goods from a brand renowned for its exceptional quality rather than a brand with mediocre quality.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ideas and AI Agents
&lt;/h3&gt;

&lt;p&gt;Thanks to AI Agents, non-technical people are now able to bring their ideas to life. This creates an uptick in the overall &lt;strong&gt;supply&lt;/strong&gt; of digital products, saturating the overall market as well as your search results.&lt;/p&gt;

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

&lt;p&gt;Selling a digital product without putting in the effort to build it sounds &lt;strong&gt;great&lt;/strong&gt; to most people. Combine that with the average end user who doesn't care about the quality of software, and you get """products""" and """businesses""" built &lt;strong&gt;for&lt;/strong&gt; end users, &lt;strong&gt;by&lt;/strong&gt; end users.&lt;/p&gt;

&lt;h3&gt;
  
  
  Marketing
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Marketing independently is hard&lt;/strong&gt;, especially if you're starting out. A lot of indie hackers think of marketing as advertising their products on social media in hopes of gathering interest and gaining a few potential customers.&lt;/p&gt;

&lt;p&gt;To understand &lt;strong&gt;marketing&lt;/strong&gt;, you must first understand the &lt;strong&gt;market&lt;/strong&gt;. I would recommend reading &lt;a href="https://en.wikipedia.org/wiki/Basic_Economics" rel="noopener noreferrer"&gt;Basic Economics by Thomas Sowell&lt;/a&gt; before trying to seduce someone to enter their credit card details with fancy screen.&lt;/p&gt;

&lt;p&gt;As I mentioned earlier, the &lt;strong&gt;supply&lt;/strong&gt; of digital products has been increasing at a rapid rate, partially due to &lt;strong&gt;Vibe Coding&lt;/strong&gt;. Your best luck is probably in &lt;strong&gt;meeting demand&lt;/strong&gt; instead of &lt;strong&gt;creating non-existent demand&lt;/strong&gt; or further saturating the market.&lt;/p&gt;

&lt;p&gt;I am not a marketer, and at the time of publishing this article, I am less than halfway through the &lt;strong&gt;largely thiccc&lt;/strong&gt; book of Basic Economics. I will refrain from giving any (poor) advice on marketing to avoid embarassing myself.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hosting
&lt;/h3&gt;

&lt;p&gt;Hosting is not a new challenge in indie hacking. &lt;/p&gt;

&lt;p&gt;It's &lt;strong&gt;surprising&lt;/strong&gt; how many people don't realize that &lt;strong&gt;hosting costs money&lt;/strong&gt;. Regardless of whether you are hosting a web application or hosting your app on an app store of some kind, you'll probably end up paying something.&lt;/p&gt;

&lt;p&gt;Larger companies such as Cloudflare, Vercel, and GitHub can afford to use their profits to host projects on a free plan to a certain extent. Even if you manage to make a profit off of your digital product on a free tier, the pain of migrating to another service will &lt;strong&gt;usually&lt;/strong&gt; keep you as a customer.&lt;/p&gt;

&lt;p&gt;Although you may get the impression that your code is living rent-free on a vercel subdomain, it is quite the opposite.&lt;/p&gt;

&lt;p&gt;You &lt;strong&gt;could&lt;/strong&gt; go for the alternative of hosting your code on your &lt;strong&gt;own machine&lt;/strong&gt;, but that leaves you vulnerable to spam attacks as well as a &lt;strong&gt;single point of failure&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Actually you should just use &lt;a href="https://www.hetzner.com/" rel="noopener noreferrer"&gt;Hetzner&lt;/a&gt;. I also recommend &lt;a href="https://www.heckler-koch.com/en" rel="noopener noreferrer"&gt;Heckler &amp;amp; Koch&lt;/a&gt;, another great german business like Hetzner. &lt;/p&gt;

&lt;h2&gt;
  
  
  Freelancing
&lt;/h2&gt;

&lt;p&gt;Freelancers include developers, designers, artists, and other people who &lt;strong&gt;produce digital products&lt;/strong&gt;. Freelancing takes more work because each customer usually has a unique request.&lt;/p&gt;

&lt;p&gt;Freelancing guarantees &lt;strong&gt;some&lt;/strong&gt; amount of profit as opposed to a standalone indie product because customers bring their demands &lt;strong&gt;directly&lt;/strong&gt; to the supplier/producer. The &lt;strong&gt;cost per unit of output&lt;/strong&gt; is usually higher than software that can be cloned and supplied with little effort.&lt;/p&gt;

&lt;h3&gt;
  
  
  Freelancing &amp;amp; AI
&lt;/h3&gt;

&lt;p&gt;Vibe Coding tools, image generation models, and video generation models have gotten good enough to satisfy &lt;strong&gt;most&lt;/strong&gt; people. Compute is &lt;strong&gt;cheap&lt;/strong&gt; compared to human labor. As a result, the market for freelancing has probably been affected in a similar manner to that of the Indie software market in terms of high supply and low demand.&lt;/p&gt;

&lt;p&gt;The only upside I see from this is that furry artists have probably experienced a loss in customers and sales. Unless AI somehow manages to drive them to extinction, I will hold to my opinion that AI is generally a bad thing for humanity as a whole.&lt;/p&gt;

&lt;h2&gt;
  
  
  Open Source
&lt;/h2&gt;

&lt;p&gt;The terms "Open Source" and "Money" don't really fit together. Most open sourcs projects are free to use.&lt;/p&gt;

&lt;p&gt;I will &lt;strong&gt;not&lt;/strong&gt; be covering public repositories that use a license preventing the unauthorized distribution of modified copies because they are weird, cringe, and shouldn't be public in the first place.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Sponsorships
&lt;/h3&gt;

&lt;p&gt;Most actively-maintained open source projects are upheld by &lt;strong&gt;sponsorships&lt;/strong&gt;, which are &lt;strong&gt;donations&lt;/strong&gt; from &lt;strong&gt;individuals&lt;/strong&gt; and/or &lt;strong&gt;companies&lt;/strong&gt;. Sponsorships, unlike contracts, can be cancelled at any time. Nobody is &lt;strong&gt;obligated&lt;/strong&gt; to sponsor an open source project even if they use it.&lt;/p&gt;

&lt;p&gt;As we have seen with Tailwind CSS, &lt;a href="https://x.com/adamwathan" rel="noopener noreferrer"&gt;Adam Wathan&lt;/a&gt; (the creator of tailwind) realized that sponsorships were not enough to support the development of the project at its current state. This resulted in a layoff of &lt;strong&gt;75%&lt;/strong&gt; of the engineering team. Thankfully, other tech companies flocked to support it with donations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Very few&lt;/strong&gt; open source projects have a large enough rate of adoption to even get sponsored. &lt;/p&gt;

&lt;p&gt;Sponsorships are &lt;strong&gt;not a stable source of income&lt;/strong&gt; and should not be treated as such.&lt;/p&gt;

&lt;h2&gt;
  
  
  Employmment
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The job market is a steaming pile of garbage&lt;/strong&gt;. The demand for junior and entry-level roles is &lt;strong&gt;drastically&lt;/strong&gt; decreasing, and keeping your job is a challenge. Big tech companies perform layoffs on a regular basis, and everyone else usually avoids hiring for new roles.&lt;/p&gt;

&lt;p&gt;Having a full-time role as a software engineer is &lt;strong&gt;probably&lt;/strong&gt; the most stable form of income out of the above. If you have time to spare, you can leverage that time to build a side hustle at the cost of burnout.&lt;/p&gt;

&lt;p&gt;I don't have too much to cover on this particular topic. For those who manage to get hired, just &lt;strong&gt;try to stay where you are&lt;/strong&gt; or move up the ladder.&lt;/p&gt;

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

&lt;p&gt;I don't mean to be pessimistic, and I &lt;strong&gt;certainly&lt;/strong&gt; don't want to give the impression that I'm jealous/coping about the success of people like &lt;a href="https://x.com/levelsio" rel="noopener noreferrer"&gt;LevelsIO&lt;/a&gt; or the owners of successful tech companies. In fact, I'm &lt;strong&gt;happy&lt;/strong&gt; for their success and I would be happy for yours too. The cold, hard truth is that &lt;strong&gt;most&lt;/strong&gt; of the success stories you see are &lt;strong&gt;outliers&lt;/strong&gt; that offset the average.&lt;/p&gt;

&lt;p&gt;I &lt;strong&gt;love&lt;/strong&gt; programming and I hope it's something I can continue to do for the rest of my life. I would &lt;strong&gt;eventually&lt;/strong&gt; like to start and run a business while doing what I love best, but the current state of things doesn't look very promising.&lt;/p&gt;

&lt;p&gt;Maybe I'll pivot to work for a company whose primary source of revenue comes from physical products.&lt;/p&gt;

&lt;p&gt;Or I could just become a gunsmith who does farming and MMA on the side.&lt;/p&gt;




&lt;p&gt;Original Article URL: &lt;a href="https://x.com/IroncladDev/status/2011542744989077863" rel="noopener noreferrer"&gt;https://x.com/IroncladDev/status/2011542744989077863&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>software</category>
      <category>ai</category>
      <category>career</category>
    </item>
    <item>
      <title>The AI Movement is a Parasitic Cancer to the Software Industry</title>
      <dc:creator>IroncladDev</dc:creator>
      <pubDate>Tue, 27 Jan 2026 20:14:50 +0000</pubDate>
      <link>https://dev.to/ironcladdev/the-ai-movement-is-a-parasitic-cancer-to-the-software-industry-3kmd</link>
      <guid>https://dev.to/ironcladdev/the-ai-movement-is-a-parasitic-cancer-to-the-software-industry-3kmd</guid>
      <description>&lt;p&gt;It's been almost five years since I've posted on this site. I thought I'd start again by cross-posting my newer articles from my &lt;a href="https://x.com/IroncladDev/articles" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Original article link: &lt;a href="https://x.com/IroncladDev/status/1997120236777013271" rel="noopener noreferrer"&gt;https://x.com/IroncladDev/status/1997120236777013271&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hopefully you'll get something out of this one. Enjoy.&lt;/p&gt;




&lt;p&gt;Three years I've waited for AI to show its potential and practicality. Today, I watch in horror as it consumes and lays waste to the industry I know and love.&lt;/p&gt;

&lt;p&gt;With great compute comes great responsibility, and the people with the most compute are &lt;strong&gt;anything but&lt;/strong&gt; responsible.&lt;/p&gt;

&lt;h2&gt;
  
  
  An infection, not a bubble
&lt;/h2&gt;

&lt;p&gt;Some people refer to the AI hype as the "AI Bubble" due to its rapid rate of expansion. I instead prefer to describe it as an &lt;strong&gt;infection&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you paid attention during biology class, you will remember that parasites, viruses, and bacteria need a host to feed on before reproducing and spreading. The term "Bubble" seems inaccurate, because most bubbles are inflated with a single, external source.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Pictured: the AI bubble conspiracy theory illustrated by a flat earther&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqafdyrh1l4a0m8anxa4b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqafdyrh1l4a0m8anxa4b.png" alt="if you're unable to view this image, it's probably better if you don't" width="680" height="344"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Despite being a major cornerstone of the industry, NVIDIA itself isn't largely responsible for aggresively shoving AI into both consumer &lt;strong&gt;and&lt;/strong&gt; developer software.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Toll on the Software Industry
&lt;/h2&gt;

&lt;p&gt;You all have seen enough people glazing and sugar-coating AI, so I will &lt;strong&gt;not&lt;/strong&gt; be taking a moment to do so.&lt;/p&gt;

&lt;p&gt;Note that I use the term "Software Industry" instead of "Tech Industry". This is because I do not build rockets, solder electronic components, or work as a slave in a bauxite mine.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Job Market &amp;amp; Workplace
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Disclaimer: the following is my observation of people who work in software-related companies that advocate for and heavily use AI. This is not financial advice&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The most obvious and undeniable side effect of AI being made publicly available is the declining job market and workplace.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recruiters&lt;/strong&gt; have started to leverage AI for filtering out candidates with boring resume pages. To combat this, &lt;strong&gt;job applicants&lt;/strong&gt; started using AI to build their resumes. This back-and-forth quickly devolves into a tiresome battle of prompting on both ends. As a result, the bar for entry level software-related roles rises significantly higher.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lazy Employees&lt;/strong&gt; who try to divert their workload to LLMs eventually end up de-valuing and ousting themselves as a leech on a salary. In the eyes of the average corporate overseer, the only difference between a local prompter and a foreign bangladeshi prompter is that one costs 1/4th as much.&lt;/p&gt;

&lt;p&gt;When a &lt;strong&gt;Non-technical Manager&lt;/strong&gt; is paired with vibe coding tools, the result is usually a violent chemical reaction (dopamine overdose) that ends up with heavier workloads, people getting fired, and higher expectations.&lt;/p&gt;

&lt;p&gt;In the end, managers are essentially end users with elevated context and permissions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Marketers&lt;/strong&gt; have become addicted to using the term "AI". Failing to mention the term gives them the impression that their social media post or campaign won't appeal to the masses. It seems that most of them put more trust in a two-letter abbreviation they don't understand than their own marketing skills.&lt;/p&gt;

&lt;p&gt;You can also thank marketers for the increased number of advertisements crammed into every possible area in consumer software.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Decline in Software Quality
&lt;/h3&gt;

&lt;p&gt;The average quality of software is declining. The tools you once knew and loved reward you with ads and AI features you never asked for.&lt;/p&gt;

&lt;p&gt;"Software Quality" is subjective. Multiple factors such as implementation, code cleanliness, and ease of use come into play. There are also different kinds of software which I will try to cover here.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mainstream Consumer Software&lt;/strong&gt; is not by definition "good software" and will never be. The average consumer cares only that the software gets the job done. An intrusive AI banner is just another thing to complain about.&lt;/p&gt;

&lt;p&gt;There's no point in having hope for mainstream consumer software. No matter how advanced AI gets, I say with confidence that there will &lt;strong&gt;never&lt;/strong&gt; be a version of Windows that is considerably fast and doesn't crash all the time.&lt;/p&gt;

&lt;p&gt;Buckle up, it's only going to get worse.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enterprise Software&lt;/strong&gt; is a dumpster fire that is usually beyond saving. By the time a company starts offering services to businesses and organizations, it means that they weren't profitable from individual customers alone.&lt;/p&gt;

&lt;p&gt;After switching to a more profitable customer base (primarily consisting of micromanagers), enterprise software companies begin to taylor to them by adding a bunch of unnecessary low-impact features.&lt;/p&gt;

&lt;p&gt;One thing enterprise companies are very good at is adopting AI, which is not a good thing. People who work in enterprise companies are probably being bombarded by AI workflows, AI-generated demos, AI internal tools, and forced to work on AI features targeted to the customer base.&lt;/p&gt;

&lt;p&gt;Once an enterprise company pivots and makes AI a cornerstone of their service(s), it usually means they are about to do a round of layoffs and slowly die out.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiof6i3klu4w1un0gc7w3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiof6i3klu4w1un0gc7w3.png" alt="the slippery enterprise software slope" width="500" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;An example of this is &lt;a href="https://www.jetbrains.com/" rel="noopener noreferrer"&gt;JetBrains&lt;/a&gt;, a company that started out with a mission to build a good IDE. They pivoted to enterprise and ultimately ended up breeding AI Agents with the descendents of &lt;a href="https://www.jetbrains.com/idea/" rel="noopener noreferrer"&gt;IntelliJ Idea&lt;/a&gt;. The only legacy they left behind is &lt;a href="https://www.jetbrains.com/lp/mono/" rel="noopener noreferrer"&gt;JetBrains Mono&lt;/a&gt;; the best font for programming in &lt;a href="https://neovim.io/" rel="noopener noreferrer"&gt;Neovim&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Software Market&lt;/strong&gt; is completely saturated with vibe-coded slop. You can't scroll Hacker News, Product Hunt, or pretty much anything for that matter without running into something related to AI. Search engines are clogged to the brim with AI-generated websites gaming SEO. A lot of investors won't take interest in a project if "AI" or "Agents" doesn't appear in the landing page header.&lt;/p&gt;

&lt;p&gt;Large companies like Github and Vercel sort of fall in between consumer, developer, and enterprise software. They are very centralized, and try to use vendor lock-in techniques to keep you hooked.&lt;/p&gt;

&lt;p&gt;After the word "copilot" was trademarked by Microsoft, Github seems to have taken up the side gig of shoving it down peoples' throats via ad banners and inserting it into commonly-used UI elements. The team behind the &lt;a href="https://ziglang.org/" rel="noopener noreferrer"&gt;Zig Programming Language&lt;/a&gt; got fed up with all this tomfoolery and &lt;a href="https://ziglang.org/news/migrating-from-github-to-codeberg/" rel="noopener noreferrer"&gt;migrated to Codeberg for good&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Vercel platform itself isn't as aggressive when it comes to ad banners, probably because they realize the obvious fact that it turns people off. However, they are definitely leveraging their monopoly on Next.js and other open source projects towards vibe coding.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Parasitic Cancer
&lt;/h2&gt;

&lt;p&gt;Everyone hears about how AI can be used for empowering humanity, automation, and replacing difficult jobs. All I've seen is talk, hype, and big corporations taking interest without any promises kept.&lt;/p&gt;

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

&lt;p&gt;The entire existence of the AI movement revolves around &lt;strong&gt;mass adoption&lt;/strong&gt; and &lt;strong&gt;money&lt;/strong&gt;. The movement is exploiting the Software Industry for every last penny, and it will stop at nothing.&lt;/p&gt;

&lt;p&gt;The people pushing for AI do not strive to make better software. &lt;br&gt;
They do not care about the software engineers that they depend on.&lt;br&gt;
They even have the audacity to compare programmers to an LLM with write access and a shell, and are actively trying to replace them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vibe Coding
&lt;/h2&gt;

&lt;p&gt;Vibe Coding has spread across the entirety of tech like a wildfire and continues to assist humans spit out the most horrific code known to man.&lt;/p&gt;

&lt;p&gt;Chances are, if you're using an AI agent to scaffold something, you probably don't have the intention of building good software in mind.&lt;/p&gt;

&lt;p&gt;I don't really concern myself with programmers who do vibe code. I just won't review their code.&lt;/p&gt;

&lt;p&gt;I use the term &lt;strong&gt;Vibe Coders&lt;/strong&gt; to describe non-technical people who &lt;strong&gt;refuse&lt;/strong&gt; to learn how to code and use vibe coding tools to derive dopamine and clout. People who refuse to put in the blood, sweat, and tears it takes to do something really shows how dedicated they &lt;strong&gt;aren't&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;If you task someone who &lt;strong&gt;doesn't&lt;/strong&gt; code with vibe coding their dream SaaS startup, you will &lt;strong&gt;only&lt;/strong&gt; ever see them request new features, request UI changes, and fix bugs. The end result will be a bloated application that does a lot of different things poorly.&lt;/p&gt;

&lt;p&gt;Lastly, I am a strong believer that &lt;strong&gt;new programmers&lt;/strong&gt; should &lt;strong&gt;not&lt;/strong&gt; use vibe coding tools. I would encourage new programmers to read the manual, write down the examples, run them, and experiment with them. I also encourage using an AI chat to ask questions about how things work along the way if it's unclear.&lt;/p&gt;

&lt;h2&gt;
  
  
  What can you do?
&lt;/h2&gt;

&lt;p&gt;I want to conclude this article with a call to action instead of just dumping my thoughts out and calling it a day. Just by changing your mindset a bit, you can make a difference.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make it a goal to write good software that lasts for years to come&lt;/li&gt;
&lt;li&gt;Find a skill you're good at, refine it, and shoot to become the best. The backbone of software is upheld by people who do one thing well&lt;/li&gt;
&lt;li&gt;Share good software with others&lt;/li&gt;
&lt;li&gt;God gave you a unique mind that nobody can replicate. Use it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unfortunately, the AI slop will continue&lt;/p&gt;

&lt;p&gt;But well-written and well-maintained software will prevail&lt;/p&gt;

&lt;p&gt;And you. So will you.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>software</category>
      <category>programming</category>
    </item>
    <item>
      <title>Smooth Scrolling with React &amp; Framer Motion</title>
      <dc:creator>IroncladDev</dc:creator>
      <pubDate>Mon, 14 Aug 2023 20:57:34 +0000</pubDate>
      <link>https://dev.to/ironcladdev/smooth-scrolling-with-react-framer-motion-dih</link>
      <guid>https://dev.to/ironcladdev/smooth-scrolling-with-react-framer-motion-dih</guid>
      <description>&lt;p&gt;Scrolling through a website especially with a notched mouse wheel is typically jumpy and harder to navigate.&lt;/p&gt;

&lt;p&gt;Smooth Scrolling, or spring scrolling adds an animated touch to the traditional mouse scroll.&lt;/p&gt;

&lt;p&gt;If you've never experienced smooth scrolling before, try out the &lt;a href="https://framersmoothscroll.ironcladdev.repl.co/" rel="noopener noreferrer"&gt;Live Demo&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Concept
&lt;/h2&gt;

&lt;p&gt;Consider the viewport window.  When a bunch of HTML elements combine to a size taller than the window, it overflows and can be accessed when you scroll down.&lt;/p&gt;

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

&lt;p&gt;To override the default scroll, we need to wrap the content in a fixed element we can control.&lt;/p&gt;

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

&lt;p&gt;Finally, we will create an invisible spacer (div) equal to the &lt;strong&gt;scroll height&lt;/strong&gt; of the content.  This will trigger the browser's default scroll bar.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;p&gt;Create a &lt;a href="https://replit.com/@replit/React-TypeScript?v=1" rel="noopener noreferrer"&gt;React Typescript&lt;/a&gt; Repl on &lt;a href="https://replit.com" rel="noopener noreferrer"&gt;Replit&lt;/a&gt; to get started.&lt;/p&gt;

&lt;p&gt;Install &lt;a href="https://framer.com/motion" rel="noopener noreferrer"&gt;Framer Motion&lt;/a&gt; with &lt;code&gt;npm install framer-motion&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The  Component
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;&amp;lt;SmoothScroll/&amp;gt;&lt;/code&gt; Component will wrap all the HTML elements we want to incorporate in the Smooth Scrolling effect.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;SmoothScroll&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;children&lt;/span&gt;
&lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReactNode&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;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&amp;gt;&amp;lt;/&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Scroll &amp;amp; Spring Values
&lt;/h3&gt;

&lt;p&gt;Import the following hooks from &lt;code&gt;framer-motion&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useScroll&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useSpring&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useTransform&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;framer-motion&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;code&gt;SmoothScroll&lt;/code&gt; component, destructure &lt;code&gt;scrollYProgress&lt;/code&gt; from the &lt;code&gt;useScroll&lt;/code&gt; hook.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;scrollYProgress&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useScroll&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, use the &lt;code&gt;useSpring&lt;/code&gt; hook to apply the smooth effect to the &lt;code&gt;scrollYProgress&lt;/code&gt; value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;smoothProgress&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useSpring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scrollYProgress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;mass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Content &amp;amp; Spacer
&lt;/h3&gt;

&lt;p&gt;Add the &lt;code&gt;motion&lt;/code&gt; component to the existing import from &lt;code&gt;framer-motion&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;- import { useScroll, useSpring } from 'framer-motion';
&lt;/span&gt;&lt;span class="gi"&gt;+ import { motion, useScroll, useSpring } from 'framer-motion';
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Skip down to the component's &lt;code&gt;return&lt;/code&gt; statement.  Return an empty &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; element and a &lt;code&gt;&amp;lt;motion.div&amp;gt;&lt;/code&gt; element which renders the &lt;code&gt;children&lt;/code&gt; prop as a child.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;contentHeight&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;

  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;motion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;
    &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"scrollBody"&lt;/span&gt;
  &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;motion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a &lt;code&gt;contentRef&lt;/code&gt; react reference via the &lt;code&gt;useRef&lt;/code&gt; hook and a &lt;code&gt;contentHeight&lt;/code&gt; state with &lt;code&gt;useState&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useState, useRef } from 'react';

...

const contentRef = useRef&amp;lt;HTMLDivElement&amp;gt;(null);
const [contentHeight, setContentHeight] = useState(0);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Assign the content wrapper the &lt;code&gt;contentRef&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;motion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;
  &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"scrollBody"&lt;/span&gt;
  &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;contentRef&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;motion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use the &lt;code&gt;style&lt;/code&gt; prop to make the spacer have a height of &lt;code&gt;contentHeight&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;contentHeight&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Resize Handler
&lt;/h3&gt;

&lt;p&gt;When the window gets resized, the height of the content content is likely to change.  Since the &lt;code&gt;contentHeight&lt;/code&gt; value is a state, we will need to update it whenever the window resizes, and when the &lt;code&gt;contentRef&lt;/code&gt; reference updates.&lt;/p&gt;

&lt;p&gt;Start by importing the &lt;code&gt;useEffect&lt;/code&gt; hook from &lt;code&gt;react&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;- import { useState, useRef } from 'react';
&lt;/span&gt;&lt;span class="gi"&gt;+ import { useEffect, useState, useRef } from 'react';
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Within the useEffect hook, create and call a handler to set the &lt;code&gt;contentHeight&lt;/code&gt; value to &lt;code&gt;contentRef.current.scrollHeight&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Add &lt;code&gt;contentRef&lt;/code&gt; to the dependency array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;useEffect&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleResize&lt;/span&gt; &lt;span class="o"&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="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="nx"&gt;contentRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;setContentHeight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contentRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scrollHeight&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;span class="nf"&gt;handleResize&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;span class="nx"&gt;contentRef&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, add a &lt;code&gt;resize&lt;/code&gt; event listener to &lt;code&gt;window&lt;/code&gt; in the useEffect hook, and return a disposer function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;useEffect&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="p"&gt;...&lt;/span&gt;

  &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;resize&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleResize&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;resize&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleResize&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;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;contentRef&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Put it all together
&lt;/h2&gt;

&lt;p&gt;Import the &lt;code&gt;useTransform&lt;/code&gt; hook from &lt;code&gt;framer-motion&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;- import { motion, useScroll, useSpring } from 'framer-motion';
&lt;/span&gt;&lt;span class="gi"&gt;+ import { useTransform, motion, useScroll, useSpring } from 'framer-motion';
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a constant &lt;code&gt;y&lt;/code&gt; and set it to the &lt;code&gt;useTransform&lt;/code&gt; hook with &lt;code&gt;smoothProgress&lt;/code&gt; as the initial value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useTransform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;smoothProgress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&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;return&lt;/span&gt; &lt;span class="nx"&gt;value&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;Visualizing how to calculate the scroll, we will be subtracting the &lt;strong&gt;viewport height&lt;/strong&gt; from the content container's &lt;strong&gt;scroll height&lt;/strong&gt;, multiplying it by -1, and then by &lt;code&gt;value&lt;/code&gt;.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useTransform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;smoothProgress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&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;return&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contentHeight&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;innerHeight&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;Use the &lt;code&gt;y&lt;/code&gt; transformed value in the content container.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&amp;lt;motion.div
  className="scrollBody"
  style={{ y }}
  ref={contentRef}
&lt;span class="gi"&gt;&amp;gt;
&lt;/span&gt;  {children}
&amp;lt;/motion.div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Styles
&lt;/h2&gt;

&lt;p&gt;I already fought CSS so you won't have to.  Simply copy and paste the bare minimum CSS over and the scroll component will be ready to roll.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.scrollBody&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100vw&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;fixed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;column&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;h2&gt;
  
  
  Complete 🎉
&lt;/h2&gt;

&lt;p&gt;That's it!  All you have to do is add a bunch of HTML elements within the &lt;code&gt;&amp;lt;SmoothScroll /&amp;gt;&lt;/code&gt; component.&lt;/p&gt;

&lt;p&gt;Nothing better than fifty &lt;code&gt;&amp;lt;h1&amp;gt;Lorem Ipsum&amp;lt;/h1&amp;gt;&lt;/code&gt;s in your codebase.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Source Code: &lt;a href="https://replit.com/@IroncladDev/FramerSmoothScroll?v=1" rel="noopener noreferrer"&gt;https://replit.com/@IroncladDev/FramerSmoothScroll?v=1&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Live Demo: &lt;a href="https://framersmoothscroll.ironcladdev.repl.co" rel="noopener noreferrer"&gt;https://framersmoothscroll.ironcladdev.repl.co&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Thanks for reading.  If you have any feedback or recommendations for this article, I'd love to hear it in the comments.&lt;/p&gt;

&lt;p&gt;Let's get in touch 🤝&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🐱 &lt;a href="https://github.com/Conner1115" rel="noopener noreferrer"&gt;Github&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🦜 &lt;a href="https://twitter.com/IroncladDev" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;⠕ &lt;a href="https://replit.com/@IroncladDev" rel="noopener noreferrer"&gt;Replit&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🌐 &lt;a href="https://www.connerow.dev" rel="noopener noreferrer"&gt;Website&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How to send Chrome / Browser Notifications</title>
      <dc:creator>IroncladDev</dc:creator>
      <pubDate>Tue, 16 Nov 2021 12:34:51 +0000</pubDate>
      <link>https://dev.to/ironcladdev/how-to-send-chrome-browser-notifications-28jg</link>
      <guid>https://dev.to/ironcladdev/how-to-send-chrome-browser-notifications-28jg</guid>
      <description>&lt;p&gt;It took me a while of looking around StackOverflow and such to find out how to send browser notifications, but it turns out to be really simple.  What I'm going to do here is walk you through a tutorial on making a simple notification-sending function.&lt;/p&gt;

&lt;p&gt;At first, when the function is called, it will have to ask for permission first, but after that, it will be able to send all sorts of notifications.&lt;/p&gt;

&lt;p&gt;Let's get started!!&lt;/p&gt;




&lt;p&gt;First, let's create the function.  It'll have three parameters.  One for the title, next for the message, and the last for the icon.&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;function&lt;/span&gt; &lt;span class="nf"&gt;sendNotif&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;icon&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;Next, just to be safe, let's make sure the browser supports notifications.&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="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="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Notification&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;warn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Your Browser does not support Chrome Notifications :(&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's chain onto the if statement with an &lt;code&gt;else if&lt;/code&gt;.  This statement tests if the notification status is granted or not.  If it is granted, it will send a notification.&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="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Notification&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;permission&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;granted&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="c1"&gt;// If it's okay let's create a notification&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;notif&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;Notification&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;text&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;Still, we'll chain onto the else-if statement.  Let's add another one.  This statement will request permission if it isn't granted or denied.&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="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Notification&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;permission&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;denied&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="c1"&gt;//request notification permission&lt;/span&gt;
  &lt;span class="nx"&gt;Notification&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;requestPermission&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;perm&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="c1"&gt;//save permission status&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="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;permission&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;Notification&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;Notification&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;permission&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;perm&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;//if granted, send a notification immediately&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;perm&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;granted&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;notif&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;Notification&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;text&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that should be it.  Your function should be working well.  Let's, for extra error handling, add an else statement at the end of the chain and log the current notification to the console if it isn't denied or allowed.&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="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;warn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Failed, Notification Permission is &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;Notification&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;permission&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Have fun and don't spam websites or users with notifications.&lt;br&gt;
Happy Coding.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
