<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Muhammad Niaz Ali</title>
    <description>The latest articles on Forem by Muhammad Niaz Ali (@muhammadniazali).</description>
    <link>https://forem.com/muhammadniazali</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%2F3894451%2Ff666c856-5891-4e21-975f-a41cb262ce52.jpeg</url>
      <title>Forem: Muhammad Niaz Ali</title>
      <link>https://forem.com/muhammadniazali</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/muhammadniazali"/>
    <language>en</language>
    <item>
      <title>I Delivered the Project. The Client Vanished. Here's the Framework I Built From That Experience.</title>
      <dc:creator>Muhammad Niaz Ali</dc:creator>
      <pubDate>Sun, 17 May 2026 03:45:52 +0000</pubDate>
      <link>https://forem.com/muhammadniazali/i-delivered-the-project-the-client-vanished-heres-the-framework-i-built-from-that-experience-3f69</link>
      <guid>https://forem.com/muhammadniazali/i-delivered-the-project-the-client-vanished-heres-the-framework-i-built-from-that-experience-3f69</guid>
      <description>&lt;p&gt;A practical guide for developers entering freelancing — written from real experience, not theory.&lt;/p&gt;

&lt;p&gt;There is a moment every freelance developer remembers.&lt;br&gt;
The moment you hit send on the final delivery — proud of what you built, relieved it's done — and then you wait.&lt;br&gt;
And wait.&lt;br&gt;
And wait.&lt;br&gt;
No response. No payment. No acknowledgment that the work even existed.&lt;br&gt;
I experienced this in my first year of freelancing as a full stack developer. A client reached out, gave me a clear requirement, I delivered on time — and then they completely disappeared.&lt;br&gt;
That experience cost me time, energy, and money. But it also forced me to build a client framework I still use on every single project today.&lt;br&gt;
This article is that framework. If you are just starting out in freelancing, read this before you take your first project.&lt;/p&gt;

&lt;p&gt;The Full Story&lt;br&gt;
The client contacted me out of nowhere. The requirement was straightforward — build a complete authentication and authorization system. Clear scope, or so I thought.&lt;br&gt;
I was new. I was eager. I said yes without asking a single qualifying question.&lt;br&gt;
No contract. No deposit. No written agreement. Just a verbal confirmation and my own excitement to prove myself.&lt;br&gt;
I built it. Tested it. Documented it. Delivered it.&lt;br&gt;
Then I followed up.&lt;br&gt;
Silence.&lt;br&gt;
Followed up again three days later.&lt;br&gt;
Still nothing.&lt;br&gt;
The client had vanished. The project sat on my machine, completed and useless. My account sat empty.&lt;br&gt;
This is not a rare story. This is one of the most common experiences in freelancing — especially for developers who are just starting out and operating from a place of fear rather than confidence.&lt;/p&gt;

&lt;p&gt;Why Beginners Are Vulnerable&lt;br&gt;
When you are new to freelancing, you carry a specific kind of fear.&lt;br&gt;
Fear of seeming difficult. Fear of losing the client before the project even starts. Fear of charging your actual rate. Fear of asking too many questions upfront.&lt;br&gt;
This fear creates a pattern of behavior that makes you an easy target for clients who never intended to pay.&lt;br&gt;
You skip the contract because you don't want to seem untrusting.&lt;br&gt;
You skip the deposit because you're afraid they'll go to someone else.&lt;br&gt;
You skip the scope definition because you just want to start working.&lt;br&gt;
Every one of these skips is a vulnerability. And experienced bad-faith clients can identify a new freelancer within the first five minutes of conversation.&lt;br&gt;
The solution is not cynicism. The solution is a professional system that protects both you and your client from the start.&lt;/p&gt;

&lt;p&gt;The Framework: 6 Things I Do Before Writing a Single Line of Code&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Qualify the Client Before Anything Else
Before discussing the project, I spend the first conversation understanding who I am dealing with.
Questions I always ask:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;What is the goal of this project?&lt;br&gt;
What is your timeline and budget?&lt;br&gt;
Have you worked with a developer before?&lt;br&gt;
What does success look like for you?&lt;/p&gt;

&lt;p&gt;A client who cannot answer these questions clearly is either not ready to start or not serious about the project. Both are red flags worth noting before you invest any time.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Take an Upfront Deposit — Non Negotiable
Minimum 30% to 50% upfront before any work begins.
This is not about distrust. This is standard professional practice in every service industry. A serious client with a real project will never refuse a deposit. The clients who push back hard on this are almost always the ones who will disappear later.
The deposit also changes the psychological dynamic of the relationship. Once a client has money invested, they are far more likely to stay engaged and communicative throughout the project.&lt;/li&gt;
&lt;li&gt;Define Scope in Writing — Every Single Time
Verbal agreements do not exist in freelancing.
Before starting any project I send a written scope document that covers:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Exact features to be built&lt;br&gt;
What is explicitly not included&lt;br&gt;
Tech stack being used&lt;br&gt;
Number of revision rounds included&lt;br&gt;
Delivery format and handoff process&lt;/p&gt;

&lt;p&gt;This document protects you from scope creep — the situation where a client keeps adding requirements after the project has started with no additional payment. It happens constantly to developers who never defined the boundary clearly at the start.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Break the Project Into Paid Milestones
Never deliver 100% of the work before receiving 100% of the payment.
Structure every project in phases:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Phase 1 — Foundation and setup → Payment milestone&lt;br&gt;
Phase 2 — Core features → Payment milestone&lt;br&gt;
Phase 3 — Final delivery and handoff → Final payment&lt;/p&gt;

&lt;p&gt;This approach protects you at every stage. If a client stops responding mid-project, you have only lost the work from the current phase — not the entire project.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Set Communication Expectations From Day One
One of the biggest sources of freelancing problems is unclear communication expectations.
At the start of every project I establish:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Preferred communication channel&lt;br&gt;
Response time expectations from both sides&lt;br&gt;
How and when progress updates will be shared&lt;br&gt;
What happens if either party goes silent for more than 48 hours&lt;/p&gt;

&lt;p&gt;Clients who are serious about their project appreciate this level of professionalism. Clients who are not serious will reveal themselves quickly when you ask for this kind of structure.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Learn to Read Red Flags Before You Sign Anything
After enough client interactions you develop an instinct for this. But here are the concrete red flags I watch for now:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Vague or constantly changing requirements&lt;br&gt;
Resistance to any upfront payment&lt;br&gt;
Unrealistic deadlines with no flexibility&lt;br&gt;
Pressure to start immediately before terms are agreed&lt;br&gt;
Unwillingness to put anything in writing&lt;br&gt;
Overly aggressive negotiation on price before seeing your work&lt;/p&gt;

&lt;p&gt;Any one of these in isolation might be manageable. Multiple red flags in the first conversation? Walk away. The project you decline is sometimes more valuable than the one you take.&lt;/p&gt;

&lt;p&gt;The Technical Side Is the Easy Part&lt;br&gt;
Here is something nobody tells you when you are learning to code.&lt;br&gt;
The technical skills — React, Node.js, databases, APIs — these get you in the door. They are the entry requirement for freelancing, not the competitive advantage.&lt;br&gt;
The competitive advantage is how you run your business.&lt;br&gt;
Developers who communicate clearly, set professional boundaries, deliver on their promises, and know their worth — these are the developers who build sustainable freelancing careers.&lt;br&gt;
The ones who only focus on technical skills and ignore the business side end up being excellent developers working for terrible rates with clients who do not respect them.&lt;br&gt;
Both sides matter equally.&lt;/p&gt;

&lt;p&gt;What I Would Tell Myself on Day One&lt;br&gt;
Stop being afraid of seeming professional.&lt;br&gt;
Asking for a deposit is professional. Having a written scope is professional. Setting communication expectations is professional.&lt;br&gt;
None of these things scare away good clients. They only scare away bad ones — which is exactly the point.&lt;br&gt;
Your skills have real value. The work you produce solves real problems for real businesses. Treat it with the same seriousness you expect from the people hiring you.&lt;br&gt;
The client who ghosted me after I delivered that project was the best thing that happened to my freelancing career. Not because it felt good — it didn't. But because it forced me to build a system that has protected every project I have taken since.&lt;br&gt;
Build your system early. You will thank yourself later.&lt;/p&gt;

&lt;p&gt;Quick Reference Checklist&lt;br&gt;
Before starting any freelancing project, run through this:&lt;/p&gt;

&lt;p&gt;Client qualified — clear requirements, realistic budget, serious intent&lt;br&gt;
 Upfront deposit received — minimum 30%&lt;br&gt;
 Scope document agreed in writing&lt;br&gt;
 Payment milestones defined&lt;br&gt;
 Communication expectations set&lt;br&gt;
 No major red flags identified&lt;/p&gt;

&lt;p&gt;If any of these boxes are unchecked, the project is not ready to start.&lt;/p&gt;

&lt;p&gt;Building something or navigating your first year of freelancing? Drop a comment — happy to share more from what I have learned on this path.&lt;/p&gt;

</description>
      <category>freelance</category>
      <category>fullstack</category>
      <category>fiverr</category>
      <category>webdev</category>
    </item>
    <item>
      <title>We Need to Talk About How We Design APIs</title>
      <dc:creator>Muhammad Niaz Ali</dc:creator>
      <pubDate>Wed, 13 May 2026 07:37:57 +0000</pubDate>
      <link>https://forem.com/muhammadniazali/we-need-to-talk-about-how-we-design-apis-2f6f</link>
      <guid>https://forem.com/muhammadniazali/we-need-to-talk-about-how-we-design-apis-2f6f</guid>
      <description>&lt;p&gt;I want to talk about something that costs development teams thousands of hours every year and almost never shows up in sprint planning, code reviews, or performance reviews. API design. Not API development. Not API security. Not API documentation. The design itself. The decisions you make before you open your code editor. I spent three days debugging a payment system for a client last year. Every single request came back 200 OK. Every order looked successful on the dashboard. Money was not moving. After three days I found it — the API was designed to return 200 for every response regardless of what actually happened. The developer who built it thought they were being helpful by normalizing the response format. What they actually did was make every failure invisible. That is not a code bug. That is a design decision with a real cost. The Invisible Cost of Inside-Out Design Most APIs I have encountered were designed from the database outward. The developer builds a schema, creates the tables, and then exposes that structure directly as endpoints. It feels efficient because you are not doing any extra transformation work. But what you are doing is forcing every API consumer to learn your internal data model. This matters because your internal model will change. Tables get split. Fields get renamed. Relationships get restructured. Every one of those changes becomes a potential breaking change for every consumer of your API. The APIs that developers genuinely enjoy using do the opposite. They start with what the developer needs to accomplish and then figure out how to provide that cleanly without leaking internal details. Stripe is the obvious example here. Their API is not praised because of the technology stack behind it. It is praised because every single endpoint was designed around what a developer is trying to do — not around how Stripe organizes its internal systems. That design decision is a large part of why they dominate their market. Five Things Every API Should Get Right Use Status Codes Like They Mean Something HTTP status codes exist as a shared communication protocol between your API and every client that will ever call it. When you return 200 for an error you are breaking that protocol and forcing every consumer to implement their own error detection layer inside the response body. That layer will have bugs. Those bugs will be difficult to trace because at the HTTP level everything looks fine. Meanwhile every HTTP library, every monitoring tool, and every developer on earth already knows how to handle a 400, a 404, a 422, and a 429 correctly if you use them. This is not advanced knowledge. Production APIs get it wrong constantly. Write Error Messages for the Person Who Has to Fix Them There are two kinds of error messages. Ones that describe what happened and ones that tell you what to do about it. validation_failed is the first kind. Expected a string for email, received null is the second kind. The second kind cuts debugging time significantly. When the error tells me exactly which field failed, what it received, and what it expected, I can fix it on the first try instead of the fifth. Good error responses are not documentation. They are part of the API contract. Version From Day One Every API will change. This is not pessimism — it is a guarantee. Business requirements evolve. Features get added. Fields get renamed. If there is no versioning strategy built in from the start, every change is a potential breaking change for every consumer in production. Adding versioning after the fact means running two parallel versions while migrating consumers. Building it in from the start costs almost nothing — a v1 in the URL path, a consistent pattern and gives you the freedom to evolve without forcing everyone downstream to react on your timeline. Make Write Operations Idempotent Networks fail in both directions. A request can time out after the server processed it but before the response was received. The client retries. Now you have a duplicate. For any endpoint that creates a resource or processes a transaction this is not an edge case. It is a predictable failure mode that happens in any real production environment. Idempotency keys solve this entirely. The client sends a unique key with each request. The server checks whether it has already processed a request with that key and returns the same result if it has without repeating the operation. Stripe and Shopify both implement this. Their developer experience is widely considered the industry benchmark that is not unrelated. Hide Your Implementation Details An API that mirrors your database schema is an API that will break whenever your schema changes. Your persistence layer is an internal concern. The developer on the other side of your endpoint should never need to understand how your data is stored to use what you are offering. This also prevents a common coupling problem: when the API shape and the database shape are the same thing, any refactoring of one requires changing the other. Separating them gives you room to evolve each independently. API Design Is a Skill Not a Side Effect API design sits at the intersection of system architecture, developer experience, and communication. It does not improve automatically as you write more code. It improves when you deliberately think about the person on the other side of your endpoint before you write it. I am a web developer. I think about this every day. Every API I ship is something another developer or a future version of me will have to integrate with. The time I spend on design before implementation is the most leveraged time in any project I work on. If you are building APIs or planning to build one, start with a single question. What does the developer using this actually need to accomplish, and how do I get them there without making them understand how my system works internally.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>architecture</category>
      <category>node</category>
    </item>
    <item>
      <title>Building VidDrop. What I learned about performance and user experience.</title>
      <dc:creator>Muhammad Niaz Ali</dc:creator>
      <pubDate>Fri, 24 Apr 2026 09:24:44 +0000</pubDate>
      <link>https://forem.com/muhammadniazali/building-viddrop-what-i-learned-about-performance-and-user-experience-3nbc</link>
      <guid>https://forem.com/muhammadniazali/building-viddrop-what-i-learned-about-performance-and-user-experience-3nbc</guid>
      <description>&lt;p&gt;I just finished building VidDrop. A video downloader tool that supports YouTube, Shorts, Vimeo, and Facebook videos.&lt;/p&gt;

&lt;p&gt;No registration. No premium tier. No hidden catches. Just a tool that works.&lt;/p&gt;

&lt;p&gt;The idea came from a simple frustration. Every video downloader website I found was full of pop ups, fake download buttons, and questionable security. Some would work. Most would not. The ones that worked looked like they were designed in 2005.&lt;/p&gt;

&lt;p&gt;So I decided to build my own.&lt;/p&gt;

&lt;p&gt;I wanted something clean. Something fast. Something that respects the user.&lt;/p&gt;

&lt;p&gt;This is what I built.&lt;/p&gt;

&lt;p&gt;The core feature is straightforward. You paste a link. The app detects the platform. You choose the format and quality. You download. But the simplicity on the surface took a lot of work underneath.&lt;/p&gt;

&lt;p&gt;Let me break down what actually went into this.&lt;/p&gt;

&lt;p&gt;First I needed a reliable backend for video processing. I chose yt-dlp. It is powerful. It supports almost every platform. But integrating it with Next.js was not trivial. I had to handle streaming responses, manage timeouts, and deal with rate limiting from video platforms.&lt;/p&gt;

&lt;p&gt;The biggest challenge was progress tracking. When someone downloads a large video file they want to know how much time is left. I implemented real time download progress with speed calculation and estimated time of arrival. Watching the numbers update in real time is surprisingly satisfying.&lt;/p&gt;

&lt;p&gt;Then I added smart format detection. The app reads metadata from the video and presents only the formats that actually work. No guesswork. No error messages saying format not available after waiting thirty seconds.&lt;/p&gt;

&lt;p&gt;The download history feature came later. I realized users often download multiple videos from the same channel or playlist. Saving the history locally means they can revisit past downloads without repasting links. Everything stays in the browser. Nothing gets sent to any server.&lt;/p&gt;

&lt;p&gt;For the visual side I went with glass morphism effects. A blurred background with subtle borders and soft shadows. It looks premium without being distracting. The user is here to download videos not admire animations.&lt;/p&gt;

&lt;p&gt;Dark and light theme support was a must. I respect system preferences but also provide a manual toggle. Some people want dark mode at noon. Some want light mode at midnight. I do not judge.&lt;/p&gt;

&lt;p&gt;I added canvas confetti for the moment a download completes. It sounds silly but it works. That little burst of celebration makes the process feel rewarding. Users have told me they intentionally download extra videos just to see the confetti.&lt;/p&gt;

&lt;p&gt;Everything is typed with TypeScript. The components. The API routes. The utility functions. No any types. No escape hatches. The type safety caught dozens of bugs before they reached production.&lt;/p&gt;

&lt;p&gt;The tech stack includes Next.js fourteen with the App Router. Tailwind CSS for styling. Yt-dlp for video processing. And canvas confetti for joy.&lt;/p&gt;

&lt;p&gt;The app is completely free. I am not collecting emails. I am not showing ads. I am not analyzing user behaviour. You paste a link. You click download. You leave. No strings attached.&lt;/p&gt;

&lt;p&gt;Now let me share what I learned.&lt;/p&gt;

&lt;p&gt;The first lesson is that performance matters more than features. Users do not care about fancy functionality if the page takes three seconds to load. I optimized the initial bundle. I deferred non critical scripts. I measured everything with Lighthouse. The result is a near perfect score on all metrics.&lt;/p&gt;

&lt;p&gt;The second lesson is that error messages need to be human readable. Instead of saying something went wrong I tell the user exactly what happened. Video not found. Unsupported platform. Network issue. Please try again. Specific errors help users fix their own problems.&lt;/p&gt;

&lt;p&gt;The third lesson is that local storage is underrated. I saved download history, user preferences, and recently used formats. No backend needed. No database. No privacy concerns. The data belongs to the user and stays with the user.&lt;/p&gt;

&lt;p&gt;The fourth lesson is that building for yourself first leads to better products. I built VidDrop because I wanted something that did not exist. I became my own first user. Every feature was something I personally wanted. That alignment kept the project focused and honest.&lt;/p&gt;

&lt;p&gt;The fifth lesson is that open source is powerful. The code is available on GitHub. Others have already contributed improvements. A better format detection algorithm. A fix for a broken platform. A performance optimization I did not think of. The community makes the project better than I ever could alone.&lt;/p&gt;

&lt;p&gt;I am not saying VidDrop is perfect. There are limitations. Some platforms change their APIs without warning. Occasionally a video fails to process. I fix issues as they come but I cannot guarantee twenty four seven uptime.&lt;/p&gt;

&lt;p&gt;Still I am proud of what I built.&lt;/p&gt;

&lt;p&gt;If you want to try it the link is in the comments.&lt;/p&gt;

&lt;p&gt;If you want to see the code the GitHub repo is also in the comments.&lt;/p&gt;

&lt;p&gt;I would love to hear your feedback. What features would you add. What platforms should I support next. What would make this tool useful for your workflow.&lt;/p&gt;

&lt;p&gt;Thank you for reading.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
      <category>typescript</category>
    </item>
    <item>
      <title>What if AI is not accelerating us but keeping us exactly where we are</title>
      <dc:creator>Muhammad Niaz Ali</dc:creator>
      <pubDate>Thu, 23 Apr 2026 16:40:26 +0000</pubDate>
      <link>https://forem.com/muhammadniazali/what-if-ai-is-not-accelerating-us-but-keeping-us-exactly-where-we-are-1a14</link>
      <guid>https://forem.com/muhammadniazali/what-if-ai-is-not-accelerating-us-but-keeping-us-exactly-where-we-are-1a14</guid>
      <description>&lt;p&gt;I have been thinking about this for three months now.&lt;/p&gt;

&lt;p&gt;Not constantly but enough that it started affecting how I work. How I open my editor. How I reach for AI or decide not to.&lt;/p&gt;

&lt;p&gt;The question is simple but the answer scares me.&lt;/p&gt;

&lt;p&gt;Is artificial intelligence helping us build the future or is it just making us extremely efficient at staying in the present?&lt;/p&gt;

&lt;p&gt;Let me explain with something that happened last week.&lt;/p&gt;

&lt;p&gt;I needed to implement a file upload feature with drag and drop support. Nothing complicated. A few megabytes limit. Image preview. Progress indicator. Standard web stuff.&lt;/p&gt;

&lt;p&gt;I opened Copilot and wrote a comment saying implement file upload with drag drop and preview.&lt;/p&gt;

&lt;p&gt;Within seconds it gave me a complete component. React based. Using react-dropzone. Tailwind for styling. It worked on the first try.&lt;/p&gt;

&lt;p&gt;I felt good. Productive. Fast.&lt;/p&gt;

&lt;p&gt;Then I stopped and asked myself a question. Would I have written it the same way if AI did not exist?&lt;/p&gt;

&lt;p&gt;The answer was no.&lt;/p&gt;

&lt;p&gt;I would have thought about alternatives. Maybe vanilla JavaScript to keep dependencies low. Maybe a web component for reusability across projects. Maybe even a simple form with server side handling because the upload volume is low.&lt;/p&gt;

&lt;p&gt;But AI did not show me any of those options. It showed me the most common solution from its training data. React. React-dropzone. Tailwind. The path of least resistance.&lt;/p&gt;

&lt;p&gt;And I took it without questioning.&lt;/p&gt;

&lt;p&gt;That is when the thought really settled in. AI is not just helping me write code faster. It is quietly narrowing the range of solutions I consider.&lt;/p&gt;

&lt;p&gt;This matters more than we think because software development has always moved forward through friction.&lt;/p&gt;

&lt;p&gt;Think about the early days of jQuery. It solved real problems. Cross browser inconsistencies were a nightmare. jQuery made them go away. But then people started using jQuery for everything even when the native DOM API was perfectly fine. The friction was gone so the exploration stopped.&lt;/p&gt;

&lt;p&gt;The same thing happened with Bootstrap. Every site looked the same because it was easy. Not because it was the best choice for every project.&lt;/p&gt;

&lt;p&gt;We eventually moved past both. But it took years of friction and frustration to push people toward better alternatives.&lt;/p&gt;

&lt;p&gt;Now imagine that same dynamic but amplified by a thousand because AI can generate complete features in seconds. The cycle of comfort and stagnation could compress from years into months.&lt;/p&gt;

&lt;p&gt;I am not saying AI is bad. I use it daily and I would not want to go back. But I am noticing patterns in my own behaviour that make me uncomfortable.&lt;/p&gt;

&lt;p&gt;The first pattern is that I rarely search for documentation anymore. I just ask the AI. It gives me an answer and I move on. But here is the problem. When I read documentation I used to discover things I was not looking for. Alternative APIs. Deprecation warnings. Examples that sparked new ideas. That serendipity is completely gone.&lt;/p&gt;

&lt;p&gt;The second pattern is that I stopped reading error messages carefully. Before AI I would see an error and spend time understanding the stack trace. The state of my application. The root cause. Now I just paste the error into the chat and apply the fix. It works but I learn almost nothing from the experience.&lt;/p&gt;

&lt;p&gt;The third pattern is the most dangerous one. I noticed that my pull requests are becoming more similar to each other. Same patterns. Same abstractions. Same folder structures. The uniqueness is fading. My code is starting to look like everyone elses code.&lt;/p&gt;

&lt;p&gt;Some people would say that is a good thing. Consistency across teams. Lower cognitive load. Easier onboarding for new developers.&lt;/p&gt;

&lt;p&gt;But I wonder if we are losing something valuable. The weird solutions that turn out to be brilliant. The unconventional architecture that scales better than anyone expected. The mistakes that teach us more than the successes.&lt;/p&gt;

&lt;p&gt;These things do not come from taking the first answer AI gives you. They come from exploration. From trying something that might fail. From spending time in the discomfort of not knowing.&lt;/p&gt;

&lt;p&gt;The problem is that AI is so good at removing discomfort. And discomfort has always been the engine of progress.&lt;/p&gt;

&lt;p&gt;Let me go back to the 2011 example that Sylwia mentioned in her recent post because it fits perfectly here.&lt;/p&gt;

&lt;p&gt;Imagine you are a developer in 2011. You have access to an AI trained on all the web development knowledge that existed at that time. PHP templates. Server side rendering. Simple JavaScript. A bit of jQuery.&lt;/p&gt;

&lt;p&gt;You need to build a web application with real time updates. The AI gives you a solution using long polling. It works. It is stable. It matches the patterns in its training data.&lt;/p&gt;

&lt;p&gt;Would you ever push yourself toward WebSockets? Would you experiment with something that barely exists yet when the current approach already works?&lt;/p&gt;

&lt;p&gt;Probably not. You would ship the long polling solution and move on to the next task.&lt;/p&gt;

&lt;p&gt;And that is exactly the point. AI does not just give us answers. It gives us answers that are anchored in the past. It shows us what has worked not what could work.&lt;/p&gt;

&lt;p&gt;This becomes even more visible when you work with newer technologies.&lt;/p&gt;

&lt;p&gt;I recently tried to use AI for WebGPU development. The results were terrible. Wrong API names. Mixed up WGSL syntax. Complete confusion about memory management. I had to debug everything manually just like I did ten years ago.&lt;/p&gt;

&lt;p&gt;But here is what is interesting. As more people use WebGPU and more code appears on GitHub the AI will get better at it. Within a year or two it will generate clean WebGPU code just like it generates React components today.&lt;/p&gt;

&lt;p&gt;And when that happens developers will adopt WebGPU faster. Not because they explored it and found it superior but because the AI made it easy. The convenience came first. The adoption followed.&lt;/p&gt;

&lt;p&gt;Is that a problem? I am not sure.&lt;/p&gt;

&lt;p&gt;On one hand faster adoption of good technology is a win. On the other hand the reason for adoption becomes convenience rather than genuine need. We use things because they are easy not because they solve a real problem better than the alternatives.&lt;/p&gt;

&lt;p&gt;This is how trends are born and how they die. The same mechanism that popularised React could also keep it alive far longer than it should be. Not because React is still the best choice for every project but because AI keeps recommending it and developers keep accepting the recommendation.&lt;/p&gt;

&lt;p&gt;The feedback loop is powerful but subtle.&lt;/p&gt;

&lt;p&gt;AI learns from existing code. It recommends patterns from that code. Developers implement those patterns. Those implementations become new training data. The patterns get reinforced. Breaking out of the loop becomes harder over time.&lt;/p&gt;

&lt;p&gt;This is not a conspiracy. It is just statistics. The most common solution gets more common. The less common solution gets forgotten.&lt;/p&gt;

&lt;p&gt;Experienced developers might resist this pull. They have the context to know when AI is suggesting something suboptimal. They can push back and ask for alternatives.&lt;/p&gt;

&lt;p&gt;But junior developers do not have that context. They trust the AI because it has been right so many times before. They do not know when it is leading them toward a mediocre solution because the mediocre solution works well enough.&lt;/p&gt;

&lt;p&gt;This creates a generation of developers who are extremely productive at building standard things and completely lost when faced with novel problems.&lt;/p&gt;

&lt;p&gt;I have seen this happen with developers who started their careers after ChatGPT became mainstream. They are fast. Incredibly fast. But when something breaks in a non standard way they freeze. The AI cannot help because the pattern does not exist in its training data. And they never learned how to debug without AI because they never had to.&lt;/p&gt;

&lt;p&gt;This is the real risk in my opinion. Not that AI will replace us. But that it will change what competence looks like. The skills that made a great developer ten years ago are not the same skills that make a great developer today. And we have not yet figured out what the new skills should be.&lt;/p&gt;

&lt;p&gt;Is it prompting? Is it code review? Is it knowing when to ignore the AI? I do not have a clear answer.&lt;/p&gt;

&lt;p&gt;But I know that the developers who will thrive in the next five years are not the ones who use AI the most. They are the ones who use AI the smartest. Who know when to accept the suggestion and when to close the chat and think for themselves.&lt;/p&gt;

&lt;p&gt;That ability to choose between convenience and curiosity might end up being the most valuable skill of all.&lt;/p&gt;

&lt;p&gt;So back to the original question. If AI existed in 2011 would we have built the modern web faster or would we still be sitting comfortably in index dot php.&lt;/p&gt;

&lt;p&gt;I think the answer depends on how many developers would have had the courage to ignore the AI and explore anyway.&lt;/p&gt;

&lt;p&gt;And that number might be smaller than we want to admit.&lt;/p&gt;

&lt;p&gt;What do you think. Would you have been the one to close the chat and try something new or would you have shipped the PHP solution and called it a day.&lt;/p&gt;

&lt;p&gt;AI is not just making us faster. It is narrowing the range of solutions we consider. The convenience removes the friction that has always driven innovation. Junior developers are especially at risk because they trust AI outputs without having the context to question them. The real skill of the future is knowing when to ignore the AI and think for yourself.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>ai</category>
    </item>
    <item>
      <title>One useState or seven Not the real question The real question is are you modeling states or just flipping booleans</title>
      <dc:creator>Muhammad Niaz Ali</dc:creator>
      <pubDate>Thu, 23 Apr 2026 14:11:52 +0000</pubDate>
      <link>https://forem.com/muhammadniazali/one-usestate-or-seven-not-the-real-question-the-real-question-is-are-you-modeling-states-or-just-33h2</link>
      <guid>https://forem.com/muhammadniazali/one-usestate-or-seven-not-the-real-question-the-real-question-is-are-you-modeling-states-or-just-33h2</guid>
      <description>&lt;p&gt;I see this everywhere in production codebases&lt;/p&gt;

&lt;p&gt;Four separate states loading error data success gives you sixteen possible combinations Half of them are impossible like loading true and error not null at the same time But JavaScript doesn’t care about impossible states It just renders garbage on screen&lt;/p&gt;

&lt;p&gt;Here is why this happens because developers think in booleans like is it loading is there error instead of thinking in states like what stage is the async process in right now&lt;/p&gt;

&lt;p&gt;Here is how you fix it Use a discriminated union One object with a status field that can be idle loading success or error TypeScript then won’t let you render data unless status is success Zero invalid states Zero bugs from impossible combinations&lt;/p&gt;

&lt;p&gt;Here is when to use what For simple stuff like dark mode just use useState For async state without caching like form submit use discriminated union with useReducer For server state with caching and background refetch use React Query For complex related state like a filter panel use useReducer&lt;/p&gt;

&lt;p&gt;React Query is great for server state But using it for a modal submit button is overkill Using seven separate useStates for a simple fetch is asking for bugs&lt;/p&gt;

&lt;p&gt;Maturity is knowing the difference&lt;/p&gt;

&lt;p&gt;What is your go to pattern for async state in React&lt;/p&gt;

</description>
      <category>codequality</category>
      <category>javascript</category>
      <category>react</category>
      <category>typescript</category>
    </item>
  </channel>
</rss>
