<?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: Itamar Tati </title>
    <description>The latest articles on Forem by Itamar Tati  (@itamartati).</description>
    <link>https://forem.com/itamartati</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%2F1162293%2F4b7ac352-c115-44b0-8207-5fd0d49a5ee3.png</url>
      <title>Forem: Itamar Tati </title>
      <link>https://forem.com/itamartati</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/itamartati"/>
    <language>en</language>
    <item>
      <title>What is Apache Kafka, Why and When to use Kafka. Lesson 1</title>
      <dc:creator>Itamar Tati </dc:creator>
      <pubDate>Mon, 18 Aug 2025 20:53:28 +0000</pubDate>
      <link>https://forem.com/itamartati/what-is-apache-kafka-why-and-when-to-use-kafka-lesson-1-1gkd</link>
      <guid>https://forem.com/itamartati/what-is-apache-kafka-why-and-when-to-use-kafka-lesson-1-1gkd</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;To truly master a technology like Apache Kafka, we must first understand its purpose, origins, and practical applications. This article explores why Kafka exists, its history, the companies leveraging it, and the scenarios where it shines, drawing insights from the official Apache Kafka introduction (&lt;a href="https://kafka.apache.org/intro" rel="noopener noreferrer"&gt;https://kafka.apache.org/intro&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Apache Kafka?
&lt;/h2&gt;

&lt;p&gt;Apache Kafka is an open-source distributed event streaming platform designed for high-throughput, fault-tolerant, and scalable processing of real-time data feeds. As described on the official Kafka website, it allows systems to publish, subscribe to, store, and process streams of records with low latency. Kafka acts like a high-speed data pipeline, connecting producers (data sources) to consumers (data processors or storage systems) efficiently.&lt;/p&gt;

&lt;h2&gt;
  
  
  History of Kafka
&lt;/h2&gt;

&lt;p&gt;Kafka was created at LinkedIn in 2010 by Jay Kreps, Neha Narkhede, and Jun Rao to address the need for a unified system to handle massive real-time data streams, such as user activity and operational metrics. Traditional messaging systems couldn’t scale to meet LinkedIn’s demands, leading to Kafka’s development. It was open-sourced in 2011 under the Apache Software Foundation and has since become a cornerstone of modern data architectures, supported by a robust community and Confluent, a company founded by Kafka’s creators.&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%2Fhjmasj7ib2lx8fi50te1.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhjmasj7ib2lx8fi50te1.webp" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Who Uses Kafka?
&lt;/h2&gt;

&lt;p&gt;Kafka powers data-intensive operations at major companies, as highlighted on the Apache Kafka website. Notable users include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;LinkedIn&lt;/strong&gt;: Manages activity streams and metrics.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Netflix&lt;/strong&gt;: Powers real-time recommendations and system monitoring.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Uber&lt;/strong&gt;: Processes ride and driver data for analytics.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Airbnb&lt;/strong&gt;: Handles booking and user interaction events.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Walmart&lt;/strong&gt;: Supports real-time inventory and e-commerce transactions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Goldman Sachs&lt;/strong&gt;: Manages financial transactions and market data.
These organizations rely on Kafka’s ability to process billions of events daily with reliability and scale.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuj7q05fi4i0bhf2stqn3.jpeg" 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%2Fuj7q05fi4i0bhf2stqn3.jpeg" alt=" " width="800" height="526"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Use Kafka?
&lt;/h2&gt;

&lt;p&gt;Kafka’s design, as outlined on its official page, makes it ideal for real-time data streaming. Its key strengths include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt;: Kafka distributes data across clusters to handle massive volumes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Durability&lt;/strong&gt;: Persistent storage allows data replay and fault tolerance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Low Latency&lt;/strong&gt;: Enables real-time processing for time-sensitive applications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexibility&lt;/strong&gt;: Supports diverse use cases, from messaging to event-driven architectures.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When to Use Kafka
&lt;/h2&gt;

&lt;p&gt;Kafka excels in scenarios requiring real-time data streaming and processing. The Apache Kafka introduction page emphasizes its role in building real-time streaming data pipelines and applications. Key use cases include:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Real-Time Financial Transactions&lt;/strong&gt;: Processes payments and trades in stock exchanges, banks, and insurance firms with speed and reliability.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Logistics and Fleet Tracking&lt;/strong&gt;: Tracks vehicles, shipments, and fleets in real time for logistics and automotive industries.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IoT Data Processing&lt;/strong&gt;: Captures and analyzes sensor data from devices in factories or wind parks for predictive maintenance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customer Interaction Tracking&lt;/strong&gt;: Enables retail, hospitality, and mobile apps to collect and respond to customer orders instantly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Healthcare Monitoring&lt;/strong&gt;: Monitors patient data in hospitals to predict and address emergencies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enterprise Data Integration&lt;/strong&gt;: Connects data across company divisions for unified access and processing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Event-Driven Architectures&lt;/strong&gt;: Serves as the foundation for data platforms, microservices, and real-time analytics.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Apache Kafka, born at LinkedIn to solve large-scale data streaming challenges, is a powerful platform for real-time data processing, as evidenced by its adoption by companies like Netflix and Uber. Its scalability, durability, and flexibility make it ideal for use cases like financial transactions, IoT, and event-driven systems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reference&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
Apache Kafka. (2025). Introduction. Retrieved from &lt;a href="https://kafka.apache.org/intro" rel="noopener noreferrer"&gt;https://kafka.apache.org/intro&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kafka</category>
      <category>eventdriven</category>
    </item>
    <item>
      <title>Why Overworking Engineers Is a Sign of a Broken Business Model</title>
      <dc:creator>Itamar Tati </dc:creator>
      <pubDate>Sun, 13 Jul 2025 11:13:57 +0000</pubDate>
      <link>https://forem.com/itamartati/why-overworking-engineers-is-a-sign-of-a-broken-business-model-553j</link>
      <guid>https://forem.com/itamartati/why-overworking-engineers-is-a-sign-of-a-broken-business-model-553j</guid>
      <description>&lt;p&gt;The 40-hour work week wasn’t created arbitrarily—it wasn't introduced as a merciful limit and not a productivity benchmark to exceed. &lt;/p&gt;

&lt;p&gt;Henry Ford popularised the 40-hour week in the 1920s—not out of kindness, but because he discovered that reducing working hours &lt;strong&gt;increased productivity and profit&lt;/strong&gt;. Nearly a century later, the research still holds: consistent performance &lt;em&gt;drops&lt;/em&gt; after 40–50 hours per week. Beyond that, burnout sets in. Quality drops. Health suffers. And retention? Forget about it.&lt;/p&gt;

&lt;p&gt;So when a start-up expects engineers to routinely pull 60+ hour weeks, it’s not a sign of grit or innovation.&lt;/p&gt;

&lt;p&gt;It’s a sign the &lt;strong&gt;business model is broken&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚩 Why overwork signals a failing system:
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. You're not paying for performance — you're underpaying quietly
&lt;/h3&gt;

&lt;p&gt;If you’re paying an engineer 70K for 40 hours/week but they end up working 60 hours, their &lt;strong&gt;real hourly rate is 46.6K&lt;/strong&gt;. That’s not hustle. That’s a pay cut with extra steps.&lt;/p&gt;

&lt;p&gt;You’re squeezing more labour from fewer people, not by rewarding them, but by stretching their capacity until they snap.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. You don’t have enough money to run your company properly
&lt;/h3&gt;

&lt;p&gt;If you &lt;em&gt;need&lt;/em&gt; employees to work overtime just to survive, what that actually means is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can't afford to hire enough people&lt;/li&gt;
&lt;li&gt;You’re not making enough revenue&lt;/li&gt;
&lt;li&gt;Your customer base doesn’t value your product enough to support healthy operations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s not a staffing issue. That’s a &lt;strong&gt;lack of market validation&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. VC money hides the cracks
&lt;/h3&gt;

&lt;p&gt;Most early-stage start-ups don’t make money. That’s fine—&lt;strong&gt;if&lt;/strong&gt; you're validating your product and learning fast.&lt;/p&gt;

&lt;p&gt;But many start-ups rely on &lt;strong&gt;venture capital to survive&lt;/strong&gt;, not to grow. And under pressure to “scale,” they push their small teams to the edge. Long hours become the norm. But if your business only works when engineers grind 60+ hour weeks? That’s not scale. That’s desperation.&lt;/p&gt;

&lt;p&gt;No amount of caffeine-fuelled late nights will fix a product nobody wants.&lt;/p&gt;




&lt;h3&gt;
  
  
  4. Great companies optimize, they don’t overclock
&lt;/h3&gt;

&lt;p&gt;The best companies don’t win because their engineers work the most hours. They win because they:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Understand their market&lt;/li&gt;
&lt;li&gt;Solve real problems&lt;/li&gt;
&lt;li&gt;Compensate people fairly&lt;/li&gt;
&lt;li&gt;Focus on &lt;strong&gt;impact per hour&lt;/strong&gt;, not total hours&lt;/li&gt;
&lt;li&gt;Hire intentionally instead of burning out existing talent&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Scaling responsibly isn’t glamorous, but it works.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚠ TL;DR:
&lt;/h2&gt;

&lt;p&gt;A business that requires 60+ hour workweeks to function is &lt;strong&gt;not high-performing&lt;/strong&gt;. It’s under-capitalized, poorly validated, and unsustainable.&lt;/p&gt;

&lt;p&gt;The 40-hour work week isn’t a limit—it’s a baseline for performance, creativity, and human well-being. And if your start-up can’t function within that constraint? You don’t need harder-working engineers.&lt;br&gt;
You need a &lt;strong&gt;better business&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;✍️ &lt;em&gt;Let’s normalize calling out these patterns. If you’ve seen or experienced this kind of overwork culture, feel free to share your story below. Let's build better companies—together.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>startup</category>
      <category>productivity</category>
      <category>career</category>
      <category>programming</category>
    </item>
    <item>
      <title>Sandbox: bash deny(1) file-read-data Pods-App-frameworks.sh</title>
      <dc:creator>Itamar Tati </dc:creator>
      <pubDate>Sun, 01 Jun 2025 20:30:46 +0000</pubDate>
      <link>https://forem.com/itamartati/sandbox-bash-deny1-file-read-data-pods-app-frameworkssh-apo</link>
      <guid>https://forem.com/itamartati/sandbox-bash-deny1-file-read-data-pods-app-frameworkssh-apo</guid>
      <description>&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;If you're developing an Ionic iOS application and recently upgraded to macOS Sonoma 14.4.1 with Xcode 15.3, you may have encountered a frustrating sandbox error that prevents your project from building:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Sandbox: bash(2538) deny(1) file-read-data /Users/.../ios/App/Pods/Target Support Files/Pods-App/Pods-App-frameworks.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This error typically appears when Xcode's User Script Sandboxing feature blocks access to CocoaPods-generated scripts, preventing the build process from completing successfully.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding User Script Sandboxing
&lt;/h2&gt;

&lt;p&gt;User Script Sandboxing is a security feature introduced in recent versions of Xcode that restricts the file system access of build scripts. While this enhances security by limiting what scripts can access during the build process, it can interfere with legitimate build operations, particularly those involving CocoaPods and other dependency management tools.&lt;/p&gt;

&lt;p&gt;The sandboxing mechanism prevents scripts from accessing files outside their designated sandbox environment, which can break builds that rely on accessing pod-generated scripts and frameworks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Failed Solutions
&lt;/h2&gt;

&lt;p&gt;Before diving into the solution, it's worth noting that several common troubleshooting steps often fail to resolve this issue:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cleaning the build folder&lt;/strong&gt; - While always a good first step, this alone won't resolve sandboxing restrictions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Running CocoaPods commands&lt;/strong&gt; (&lt;code&gt;pod deintegrate&lt;/code&gt;, &lt;code&gt;pod clean&lt;/code&gt;, &lt;code&gt;pod install&lt;/code&gt;) - These commands can help with dependency issues but won't address sandboxing settings&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Upgrading CocoaPods&lt;/strong&gt; (&lt;code&gt;gem install cocoapods&lt;/code&gt;) - Version updates won't change Xcode's sandboxing behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Complete Solution
&lt;/h2&gt;

&lt;p&gt;The key to resolving this issue is understanding that Xcode has &lt;strong&gt;two separate&lt;/strong&gt; User Script Sandboxing settings that both need to be configured:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Disable User Script Sandboxing for the Target
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Open your project in Xcode&lt;/li&gt;
&lt;li&gt;Select your project in the Project Navigator&lt;/li&gt;
&lt;li&gt;Select your app target (usually named "App")&lt;/li&gt;
&lt;li&gt;Navigate to the "Build Settings" tab&lt;/li&gt;
&lt;li&gt;Search for "User Script Sandboxing"&lt;/li&gt;
&lt;li&gt;Change the setting from "Yes" to "No"&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 2: Disable User Script Sandboxing for the Project
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;While still in the Build Settings tab&lt;/li&gt;
&lt;li&gt;Make sure you're viewing the &lt;strong&gt;Project&lt;/strong&gt; settings (not just the Target)&lt;/li&gt;
&lt;li&gt;Look for the "User Script Sandboxing" setting at the project level&lt;/li&gt;
&lt;li&gt;Change this setting from "Yes" to "No" as well&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Why Both Settings Matter
&lt;/h2&gt;

&lt;p&gt;Many developers only change the target-level setting and wonder why the issue persists. Xcode inherits build settings from the project level to the target level, but both can have independent configurations. The sandboxing restriction can be enforced at either level, so both must be disabled to ensure scripts can access the necessary files.&lt;/p&gt;

&lt;h2&gt;
  
  
  Impact on CI/CD and App Store Builds
&lt;/h2&gt;

&lt;p&gt;If you're using continuous integration services like Ionic Appflow for App Store builds, you'll need to ensure these settings are committed to your repository. The build settings are stored in your &lt;code&gt;.xcodeproj&lt;/code&gt; file, so once you've made these changes locally, commit and push them to ensure your CI/CD pipeline uses the same configuration.&lt;/p&gt;

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

&lt;p&gt;Disabling User Script Sandboxing does reduce some security protections during the build process. However, for Ionic projects that rely heavily on CocoaPods and automated script execution, this is often necessary for functionality. The security impact is primarily during development and build time, not in the final application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Alternative Approaches
&lt;/h2&gt;

&lt;p&gt;If you prefer to keep sandboxing enabled, you might consider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Manual dependency management&lt;/strong&gt; - Avoiding CocoaPods entirely (though this significantly increases complexity)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom build phases&lt;/strong&gt; - Restructuring your build process to work within sandbox constraints&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Waiting for updates&lt;/strong&gt; - Future versions of CocoaPods or Xcode may resolve compatibility issues&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, for most development teams, disabling User Script Sandboxing remains the most practical solution.&lt;/p&gt;

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

&lt;p&gt;The User Script Sandboxing issue in Ionic iOS projects is a common problem that stems from Xcode's enhanced security measures conflicting with CocoaPods' build process. The solution requires disabling the sandboxing feature at both the project and target levels in Xcode's Build Settings.&lt;/p&gt;

&lt;p&gt;While this may seem like a simple fix once you know it, the dual-setting requirement often catches developers off guard, leading to continued build failures even after attempting the "obvious" solution. By ensuring both settings are configured correctly, you can restore your build process and continue developing your Ionic iOS application without interruption.&lt;/p&gt;

</description>
      <category>mobile</category>
      <category>ionic</category>
      <category>ios</category>
    </item>
    <item>
      <title>Understanding Authentication in Hybrid Mobile Apps: Cookies, WebViews, and Common Pitfalls</title>
      <dc:creator>Itamar Tati </dc:creator>
      <pubDate>Thu, 29 May 2025 19:12:15 +0000</pubDate>
      <link>https://forem.com/itamartati/understanding-authentication-in-hybrid-mobile-apps-cookies-webviews-and-common-pitfalls-3m8</link>
      <guid>https://forem.com/itamartati/understanding-authentication-in-hybrid-mobile-apps-cookies-webviews-and-common-pitfalls-3m8</guid>
      <description>&lt;h2&gt;
  
  
  Introduction to Hybrid App Authentication
&lt;/h2&gt;

&lt;p&gt;Hybrid mobile applications built with frameworks like Ionic (using Capacitor or Cordova) and React Native (using WebViews) combine web technologies with native app capabilities. While this approach offers many benefits, authentication—particularly cookie-based sessions—presents unique challenges that differ from both traditional web apps and fully native apps.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Cookies Work in WebView-Based Apps
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The WebView Cookie Jar
&lt;/h3&gt;

&lt;p&gt;When your hybrid app runs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;iOS WKWebView&lt;/strong&gt;: Uses a separate cookie storage from Safari&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Android WebView&lt;/strong&gt;: Behavior varies by OS version but generally isolates cookies&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Capacitor's WebView&lt;/strong&gt;: Implements a specialized cookie policy that differs from browsers&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Key Differences from Browser Behavior
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Browser Behavior&lt;/th&gt;
&lt;th&gt;WebView Behavior&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Cookie Persistence&lt;/td&gt;
&lt;td&gt;Normal&lt;/td&gt;
&lt;td&gt;Often reset on app restart&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SameSite Policy&lt;/td&gt;
&lt;td&gt;Standard&lt;/td&gt;
&lt;td&gt;Sometimes stricter&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storage Access&lt;/td&gt;
&lt;td&gt;Full&lt;/td&gt;
&lt;td&gt;May be limited&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  The Authentication Challenges I Faced
&lt;/h2&gt;

&lt;p&gt;In my Ionic/React app with Firebase authentication, several issues emerged:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;iOS Cookie Isolation&lt;/strong&gt;: The WKWebView wasn't properly persisting session cookies&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Token Synchronization&lt;/strong&gt;: Firebase tokens weren't syncing between native and web layers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Redirect Timing&lt;/strong&gt;: Authentication state changes weren't properly synchronized with routing&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Common Pitfalls in Hybrid Auth
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. WebView Cookie Limitations
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: Many developers assume WebViews handle cookies exactly like browsers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// For iOS, explicitly enable cookie storage&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;Capacitor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getPlatform&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ios&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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;CapacitorCookies&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setCookie&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://yourdomain.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;session&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Firebase Token Synchronization
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: Firebase tokens might not persist between app launches.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Use secure storage for tokens&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Preferences&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;@capacitor/preferences&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setAuthToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Preferences&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;authToken&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// Also set for WebView if needed&lt;/span&gt;
  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cookie&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`authToken=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;; path=/; Secure; SameSite=None`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Race Conditions in Auth Flow
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: The app might redirect before auth state is fully initialized.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;authReady&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setAuthReady&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&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;unsubscribe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;onAuthStateChanged&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&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;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getIdToken&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;setAuthToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;setAuthReady&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Only now allow routing&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;unsubscribe&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;h2&gt;
  
  
  Best Practices for Hybrid App Authentication
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Use Native Storage for Critical Tokens
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;SecureStorage&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;@capacitor-community/secure-storage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;storeToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;SecureStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;firebaseToken&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Implement Dual Storage Strategy
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;persistAuthState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;User&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;// Native storage&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Preferences&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;userData&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// Web storage (for WebView)&lt;/span&gt;
  &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

  &lt;span class="c1"&gt;// Cookies (for API calls)&lt;/span&gt;
  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cookie&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`auth=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;; path=/; Max-Age=604800`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Handle Platform-Specific Quirks
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;iOS Specific&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Capacitor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getPlatform&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ios&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;// Workaround for iOS cookie issues&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://yourdomain.com/set-cookie&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="na"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;include&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;&lt;strong&gt;Android Specific&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Capacitor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getPlatform&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;android&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;// Android WebView cookie workaround&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cookies&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;CapacitorCookies&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getCookies&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;cookies&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;CapacitorCookies&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setCookie&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://yourdomain.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;session&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;token&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;h2&gt;
  
  
  Debugging Hybrid Auth Issues
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. WebView Inspector Tools
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# For iOS&lt;/span&gt;
ionic capacitor run ios &lt;span class="nt"&gt;--external&lt;/span&gt; &lt;span class="nt"&gt;--consolelogs&lt;/span&gt;

&lt;span class="c"&gt;# For Android&lt;/span&gt;
chrome://inspect/#devices
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Network Request Monitoring
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Add this to your app initialization&lt;/span&gt;
&lt;span class="nx"&gt;Capacitor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Plugins&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;WebView&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setServerBasePath&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://localhost:8100&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;Capacitor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Plugins&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;WebView&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setWebViewListener&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;WebView event:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Cookie Debugging
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;checkCookies&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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;cookies&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cookie&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;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;WebView cookies:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cookies&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;Capacitor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getPlatform&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ios&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;const&lt;/span&gt; &lt;span class="nx"&gt;iosCookies&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;CapacitorCookies&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getCookies&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;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;iOS native cookies:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;iosCookies&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;h2&gt;
  
  
  Lessons Learned from My Login Issues
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Never Assume WebView = Browser&lt;/strong&gt;: The cookie behavior is subtly different&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Test Authentication Across States&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fresh install&lt;/li&gt;
&lt;li&gt;App restart&lt;/li&gt;
&lt;li&gt;Background/foreground transitions&lt;/li&gt;
&lt;li&gt;Network changes&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Implement Redundancy&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;   &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getAuthToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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;// Try WebView cookies first&lt;/span&gt;
     &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;webToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getCookie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;token&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

     &lt;span class="c1"&gt;// Fallback to native storage&lt;/span&gt;
     &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;webToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Preferences&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;token&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
       &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;value&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="nx"&gt;webToken&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;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Hybrid app authentication requires a nuanced approach that bridges web and native paradigms. By understanding WebView cookie behavior, implementing platform-specific workarounds, and building robust state synchronization, you can create authentication flows that are just as reliable as native implementations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Takeaways&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use both native storage and cookies redundantly&lt;/li&gt;
&lt;li&gt;Implement platform-specific authentication logic&lt;/li&gt;
&lt;li&gt;Add comprehensive logging for auth flows&lt;/li&gt;
&lt;li&gt;Test under various network and storage conditions&lt;/li&gt;
&lt;li&gt;Consider using dedicated auth plugins for complex scenarios&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Remember that hybrid frameworks are constantly evolving, so stay updated with the latest changes to WebView implementations on both iOS and Android platforms.&lt;/p&gt;

</description>
      <category>mobile</category>
      <category>ionic</category>
      <category>reactnative</category>
    </item>
    <item>
      <title>I Learnt C in 2 weeks but have been FAILING to Learn dutch for 5 years. What this Taught me About Learning.</title>
      <dc:creator>Itamar Tati </dc:creator>
      <pubDate>Sat, 03 May 2025 12:25:15 +0000</pubDate>
      <link>https://forem.com/itamartati/i-learnt-c-in-2-weeks-but-have-been-failing-to-learn-dutch-for-5-years-what-this-taught-me-about-4b68</link>
      <guid>https://forem.com/itamartati/i-learnt-c-in-2-weeks-but-have-been-failing-to-learn-dutch-for-5-years-what-this-taught-me-about-4b68</guid>
      <description>&lt;p&gt;"Learning is weird." &lt;/p&gt;

&lt;p&gt;That's my profound opening statement. Thank you for coming to my TED talk.&lt;/p&gt;

&lt;p&gt;But seriously, the stark contrast between my experiences learning a programming language versus a human language has taught me more about the learning process than either journey alone. Here's my tale of mastering C in two weeks while Dutch has remained my white whale for over half a decade.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Two-Week C Speedrun
&lt;/h2&gt;

&lt;p&gt;About a month ago, I decided I needed to add C to my programming toolkit. Not because I particularly wanted to manage my own memory or because I enjoy segmentation faults, but because I'm a masochist with a deadline.&lt;/p&gt;

&lt;p&gt;My approach was simple: build stuff and check the docs when stuck. No tutorials, no hand-holding, just me and the C documentation in an epic staring contest.&lt;/p&gt;

&lt;p&gt;Day 1: Created "Hello, World!" and felt absurdly proud. Look mom, I'm a real programmer now!&lt;/p&gt;

&lt;p&gt;Day 3: Built "BudgetTracker3000" – a command-line app that helped me realize I spend way too much money on coffee. The app was buggy, but so is my spending habit, so at least it was thematically consistent.&lt;/p&gt;

&lt;p&gt;Day 5: Discovered pointers. Proceeded to spend three hours debugging a problem that stemmed from me treating memory addresses like regular variables. My rubber duck received an education in creative profanity that day.&lt;/p&gt;

&lt;p&gt;Day 8: Created "FileSort9000" – a program that organized my digital photo collection by date. It worked surprisingly well until it didn't, teaching me valuable lessons about buffer overflows and why using &lt;code&gt;gets()&lt;/code&gt; is like playing Russian roulette with your program.&lt;/p&gt;

&lt;p&gt;Day 12: Built a simple text-based adventure game called "Escape the Segmentation Fault" where the final boss was, you guessed it, memory management. Meta, I know.&lt;/p&gt;

&lt;p&gt;Day 14: Felt comfortable enough with C that I could actually read other people's code without my brain melting. Success!&lt;/p&gt;

&lt;p&gt;The key was that I was &lt;em&gt;using&lt;/em&gt; C constantly. Every project forced me to apply what I'd learned and identify what I still didn't understand. Documentation wasn't my teacher; it was my reference guide that I consulted when I got stuck. My actual teacher was failure – glorious, frustrating, educational failure.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Dutch Debacle: 5+ Years of "Hallo" and Not Much Else
&lt;/h2&gt;

&lt;p&gt;Meanwhile, for over five years, I've been "learning" Dutch. And by learning, I mean opening Duolingo when I feel guilty, completing enough exercises to silence the owl's judgment, and then promptly forgetting everything I've supposedly learned.&lt;/p&gt;

&lt;p&gt;I've diligently collected a menagerie of Dutch phrases that I can recite with all the confidence of a nervous chihuahua:&lt;/p&gt;

&lt;p&gt;"De jongen eet een appel." (The boy eats an apple.)&lt;br&gt;
"Ik heb een rode fiets." (I have a red bicycle.)&lt;br&gt;
"Waar is het station?" (Where is the station?)&lt;/p&gt;

&lt;p&gt;Revolutionary stuff, I know. I'm practically fluent if you need to discuss boys eating fruit or my hypothetical bicycle.&lt;/p&gt;

&lt;p&gt;The few times I've ventured to Dutch-speaking regions, armed with my carefully rehearsed phrases, the conversations went something like this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Me&lt;/strong&gt;: &lt;em&gt;"Goedemorgen! Ik zou graag een koffie willen bestellen."&lt;/em&gt; (Good morning! I would like to order a coffee.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dutch Person&lt;/strong&gt;: &lt;em&gt;[Responds with what sounds like a machinegun of syllables]&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Me&lt;/strong&gt;: &lt;em&gt;[Blank stare of incomprehension]&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dutch Person&lt;/strong&gt;: &lt;em&gt;[Sighs]&lt;/em&gt; "Just speak English, man. It's easier for both of us."&lt;/p&gt;

&lt;p&gt;And just like that, my Dutch practice opportunity vanishes. This happens EVERY. SINGLE. TIME. It's like the universe has conspired to ensure I never progress beyond the linguistic capabilities of a Dutch toddler with a limited interest in apples and bicycles.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Absurdity of the Comparison
&lt;/h2&gt;

&lt;p&gt;Now, comparing learning Dutch to learning C is admittedly ridiculous. It's like comparing climbing Mount Everest to climbing the stairs to your apartment – both involve ascending, but one is significantly more complex.&lt;/p&gt;

&lt;p&gt;Human languages are infinitely more nuanced than programming languages. They're filled with cultural context, idioms, irregular verbs, and native speakers who can detect your foreignness from a single mispronounced vowel.&lt;/p&gt;

&lt;p&gt;Programming languages, by contrast, are designed to be learned. They have documentation that explicitly tells you how things work. They don't change pronunciation based on regional dialects, and compilers don't switch to English when they see you struggling.&lt;/p&gt;

&lt;p&gt;If C had been like Dutch:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The compiler would randomly change syntax rules based on its mood&lt;/li&gt;
&lt;li&gt;Variables would refuse to be declared on Tuesdays&lt;/li&gt;
&lt;li&gt;Semicolons would sometimes be optional, but only during full moons&lt;/li&gt;
&lt;li&gt;Error messages would be delivered via interpretive dance&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What This Taught Me About Learning
&lt;/h2&gt;

&lt;p&gt;Here's what I've learned from these vastly different experiences:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Practice trumps theory every time.&lt;/strong&gt; I made more progress with C in two weeks of building projects than I did with Dutch in years of passive learning.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Motivation comes from meaningful application.&lt;/strong&gt; My C projects solved actual problems I had. My Dutch phrases about apples and bicycles... not so much.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Feedback loops need to be tight.&lt;/strong&gt; When I wrote bad C code, the compiler yelled at me immediately. My Dutch mistakes often go uncorrected because native speakers switch to English.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Immersion is non-negotiable.&lt;/strong&gt; I was immersed in C code all day during those two weeks. My Dutch "immersion" consists of occasionally remembering to change Netflix audio to Dutch before falling asleep 10 minutes into the show.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Documentation is a reference, not a teacher.&lt;/strong&gt; Reading C documentation without applying it would have been useless. Similarly, memorizing Dutch grammar rules doesn't make you conversational.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Path Forward
&lt;/h2&gt;

&lt;p&gt;So where does this leave me? Well, I'm now reasonably competent in C, and I still say "dank je wel" with the confidence of someone who learned it from a tourist phrasebook five minutes ago.&lt;/p&gt;

&lt;p&gt;For Dutch, I need to find ways to practice that don't allow for English bailouts. Maybe I'll tape Dutch vocabulary to my bathroom mirror. Perhaps I'll find a Dutch penpal who doesn't speak English (do those exist?). Or maybe I'll just accept that my Dutch skills will remain permanently stuck at "can order coffee but cannot understand the response."&lt;/p&gt;

&lt;p&gt;As for programming languages, I'm convinced that my "build first, check docs when stuck" approach is the way to go. Documentation makes a terrible teacher but an excellent reference.&lt;/p&gt;

&lt;p&gt;The biggest lesson? Learning happens in the doing, not in the studying. So if you'll excuse me, I need to go write some C code that prints "Ik spreek geen Nederlands" 1000 times. It's the perfect intersection of my skill sets.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;P.S. If you're a Dutch speaker who's read this far: alstublieft, spreek Nederlands met mij, zelfs als ik er slecht in ben. En nee, ik heb Google Translate niet gebruikt voor deze zin... oké, misschien een beetje.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>c</category>
      <category>programming</category>
      <category>learning</category>
      <category>productivity</category>
    </item>
    <item>
      <title>A Quick, Simple Guide to Building a Chatbot with JavaScript and Node.js</title>
      <dc:creator>Itamar Tati </dc:creator>
      <pubDate>Mon, 31 Mar 2025 19:16:36 +0000</pubDate>
      <link>https://forem.com/itamartati/a-quick-simple-guide-to-building-a-chatbot-with-javascript-and-nodejs-k79</link>
      <guid>https://forem.com/itamartati/a-quick-simple-guide-to-building-a-chatbot-with-javascript-and-nodejs-k79</guid>
      <description>&lt;p&gt;Chatbots have become essential tools for businesses and developers looking to automate customer interactions and provide instant support. In this post, we'll walk through creating a simple chatbot using JavaScript, Node.js, and a serverless architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Build a Chatbot?
&lt;/h2&gt;

&lt;p&gt;Developing your own chatbot allows you to explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Conversational UI design&lt;/strong&gt; – Understanding how users interact through chat interfaces.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Serverless computing&lt;/strong&gt; – Using cloud functions for scalable, cost-effective solutions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Natural Language Processing&lt;/strong&gt; – Implementing basic intent recognition and responses.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before getting started, ensure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;GitHub account&lt;/strong&gt; for version control.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Node.js&lt;/strong&gt; installed on your computer.&lt;/li&gt;
&lt;li&gt;Basic knowledge of &lt;strong&gt;JavaScript&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 1: Setting Up Your Project
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Create a new directory for your project: &lt;code&gt;mkdir simple-chatbot&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Navigate to the directory: &lt;code&gt;cd simple-chatbot&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Initialize a new Node.js project: &lt;code&gt;npm init -y&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Install necessary packages: &lt;code&gt;npm install express body-parser axios dotenv&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 2: Creating the Basic Server
&lt;/h2&gt;

&lt;p&gt;Create an &lt;code&gt;index.js&lt;/code&gt; file in your project directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bodyParser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body-parser&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dotenv&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;config&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;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&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;PORT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Middleware&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bodyParser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;static&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;public&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// Routes&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/message&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="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&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;userMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;processMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userMessage&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;processMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&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;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hi&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="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello there! How can I help you today?&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="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;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;help&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="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;I can answer questions about our services, products, or provide support. What do you need?&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="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;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bye&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="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Goodbye! Feel free to chat again if you need assistance.&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="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;I'm still learning. Could you rephrase that or ask something else?&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="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="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;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Server running on port &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;PORT&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;h2&gt;
  
  
  Step 3: Building the Frontend Interface
&lt;/h2&gt;

&lt;p&gt;Create a &lt;code&gt;public&lt;/code&gt; folder in your project directory and add an &lt;code&gt;index.html&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Simple Chatbot&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Arial&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;sans-serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;600px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;#chat-container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;400px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#ccc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;overflow-y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;scroll&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;#user-input&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;80%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt; &lt;span class="m"&gt;15px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.user-message&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;right&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#0084ff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;.bot-message&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;left&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#333&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Simple Chatbot&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"chat-container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"user-input"&lt;/span&gt; &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"Type your message..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;onclick=&lt;/span&gt;&lt;span class="s"&gt;"sendMessage()"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Send&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;chatContainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;chat-container&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user-input&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;addMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isUser&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;messageDiv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;messageDiv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;isUser&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user-message&lt;/span&gt;&lt;span class="dl"&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;bot-message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;messageDiv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;chatContainer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;messageDiv&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;chatContainer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scrollTop&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;chatContainer&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;userInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&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;message&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="nf"&gt;addMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;userInput&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;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/message&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="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&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;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&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;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;message&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;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;addMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&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;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nf"&gt;addMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Sorry, there was an error processing your request.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&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;userInput&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="s1"&gt;keypress&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="nx"&gt;e&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;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Enter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="c1"&gt;// Welcome message&lt;/span&gt;
    &lt;span class="nf"&gt;addMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hi! I&lt;/span&gt;&lt;span class="se"&gt;\'&lt;/span&gt;&lt;span class="s1"&gt;m your chatbot assistant. How can I help you today?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4: Deploy and Test
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Run your application locally: &lt;code&gt;node index.js&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Open your browser and visit &lt;code&gt;http://localhost:3000&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Interact with your chatbot by sending messages&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Enhancing Your Chatbot
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Add intent recognition&lt;/strong&gt;: Implement a more robust NLP system using libraries like natural.js&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Connect to external APIs&lt;/strong&gt;: Add weather forecasts or news updates&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implement user sessions&lt;/strong&gt;: Store conversation history for context-aware responses&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deploy to cloud&lt;/strong&gt;: Use services like Heroku, Vercel, or AWS for public access&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Building a chatbot with JavaScript and Node.js is a straightforward way to explore conversational interfaces. This simple implementation can be expanded into a powerful tool with additional features and integrations.&lt;/p&gt;

</description>
      <category>node</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>lambda</category>
    </item>
    <item>
      <title>Creating the Codebase for an Enterprise Application from Scratch: Lessons Learned and Things I Regret</title>
      <dc:creator>Itamar Tati </dc:creator>
      <pubDate>Mon, 31 Mar 2025 16:37:37 +0000</pubDate>
      <link>https://forem.com/itamartati/creating-the-codebase-for-an-enterprise-application-from-scratch-lessons-learned-and-things-i-114a</link>
      <guid>https://forem.com/itamartati/creating-the-codebase-for-an-enterprise-application-from-scratch-lessons-learned-and-things-i-114a</guid>
      <description>&lt;p&gt;After spending a year building an enterprise application from the ground up, I've accumulated valuable insights—many learned the hard way. Here's what went wrong and what I wish I'd done differently.&lt;/p&gt;

&lt;h2&gt;
  
  
  Starting with Frameworks Instead of Business Logic
&lt;/h2&gt;

&lt;p&gt;My first critical mistake was beginning with frameworks. I built the entire infrastructure around entry points to both frontend and backend frameworks, directly contradicting Robert Martin's advice on clean architecture. His philosophy emphasizes organizing code around business cases rather than technical frameworks.&lt;/p&gt;

&lt;p&gt;In hindsight, I should have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Started with core business domain models&lt;/li&gt;
&lt;li&gt;Built use cases independent of delivery mechanisms&lt;/li&gt;
&lt;li&gt;Added frameworks as implementation details, not foundational elements&lt;/li&gt;
&lt;li&gt;Maintained clear boundaries between business logic and technical infrastructure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This approach would have created a more flexible, maintainable system that could evolve with changing requirements and technology.&lt;/p&gt;

&lt;h2&gt;
  
  
  Failing to Push Back on Full-System Development
&lt;/h2&gt;

&lt;p&gt;Rather than advocating for an incremental approach, I acquiesced to management's desire for comprehensive development. We spent a year building an entire ecosystem without releasing anything to users. The costs have been substantial:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A year of development costs with zero revenue&lt;/li&gt;
&lt;li&gt;No real user feedback to validate assumptions&lt;/li&gt;
&lt;li&gt;Mounting pressure as launch approaches&lt;/li&gt;
&lt;li&gt;Risk of delivering something users might reject entirely&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What I Would Do Differently
&lt;/h2&gt;

&lt;p&gt;If I could start over, I would champion a different strategy:&lt;/p&gt;

&lt;h3&gt;
  
  
  Release a Minimal Viable Product
&lt;/h3&gt;

&lt;p&gt;I should have pushed management to focus on delivering a single service that provided immediate value. This would have allowed us to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Get something into users' hands quickly&lt;/li&gt;
&lt;li&gt;Gather real feedback early in the process&lt;/li&gt;
&lt;li&gt;Build momentum and confidence&lt;/li&gt;
&lt;li&gt;Justify additional development with proven results&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Embrace Iterative Development
&lt;/h3&gt;

&lt;p&gt;The startup wisdom of "fail fast, fail often" exists for a reason. Most successful startups:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ship early, imperfect versions&lt;/li&gt;
&lt;li&gt;Learn from actual usage patterns&lt;/li&gt;
&lt;li&gt;Iterate rapidly based on real data&lt;/li&gt;
&lt;li&gt;Avoid the sunk cost of building unwanted features&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Moving Forward
&lt;/h2&gt;

&lt;p&gt;Though I can't reclaim the lost time and resources, I can apply these lessons going forward:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Break the remaining work into smaller, releasable increments&lt;/li&gt;
&lt;li&gt;Prioritize getting user feedback as quickly as possible&lt;/li&gt;
&lt;li&gt;Refactor gradually toward cleaner architecture while delivering value&lt;/li&gt;
&lt;li&gt;Document these lessons for future projects&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The most expensive education is one paid for but not applied. I intend to ensure these hard-earned insights guide our future development decisions.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>AI: The Biggest Scam of the Century—Wake Up, Sheep!</title>
      <dc:creator>Itamar Tati </dc:creator>
      <pubDate>Sat, 29 Mar 2025 08:08:38 +0000</pubDate>
      <link>https://forem.com/itamartati/ai-the-biggest-scam-of-the-century-wake-up-sheep-19jk</link>
      <guid>https://forem.com/itamartati/ai-the-biggest-scam-of-the-century-wake-up-sheep-19jk</guid>
      <description>&lt;p&gt;Alright, buckle up, because I’m about to rip into the biggest tech scam since NFTs: Artificial Intelligence. Yeah, that’s right—AI, the shiny new toy that every tech bro with a hoodie and a podcast swears is going to “revolutionize the world.” Meanwhile, I’m over here fuming because people keep falling for this garbage like it’s the Second Coming of Steve Jobs. Spoiler alert: It’s not. It’s a overhyped parlor trick, and I’m sick of watching everyone drool over it like Pavlov’s dogs at a bell factory.&lt;/p&gt;




&lt;p&gt;🤖 AI: The Tech Bro’s Wet Dream&lt;br&gt;&lt;br&gt;
Listen, I get it. The idea of a magical robot brain solving all our problems sounds cool—until you realize it’s just a glorified autocomplete with a better PR team. Tech bros have been hyping AI like it’s the key to world peace, curing cancer, and making your coffee just the way you like it. “It’s the future!” they scream from their overpriced San Francisco lofts, sipping $20 kombucha. Yeah, okay, Chad. Tell that to the dot-com bubble, Google Glass, or that time you said Segways would replace cars. Tech bros have a track record of being wrong more often than a broken clock, but sure, &lt;em&gt;this time&lt;/em&gt; they’ve totally got it figured out.&lt;/p&gt;

&lt;p&gt;Here’s the dirty little secret: AI isn’t some genius overlord—it’s only as good as the schmuck typing prompts into it. You know who’s really running the show? The guy who knows how to ask it the right questions. That’s it. AI isn’t “smart”; it’s a mirror reflecting the competence (or incompetence) of its user. Give it to your grandma and tell her to build Facebook. Go ahead, I’ll wait. Oh, what’s that? She made it write a recipe for meatloaf instead? Exactly. AI doesn’t “change the world”—it just parrots back whatever you feed it, dressed up in fancy buzzwords.&lt;/p&gt;




&lt;p&gt;🎪 The Great AI Scam Unveiled&lt;br&gt;&lt;br&gt;
Let’s break down this clown show for what it really is:&lt;/p&gt;

&lt;p&gt;1️⃣ &lt;strong&gt;It’s a glorified search engine&lt;/strong&gt; 🔍 — Oh, you thought ChatGPT was “intelligent”? Nah, it’s just scraping the internet and remixing it into sentences that sound vaguely coherent. It’s like giving a toddler a thesaurus and calling it Shakespeare.&lt;/p&gt;

&lt;p&gt;2️⃣ &lt;strong&gt;It’s dumber than a bag of hammers&lt;/strong&gt; 🛠️ — Ask AI to do anything remotely creative or outside its training data, and it flops harder than a fish on a dock. “Write me a song about existential dread in the key of G minor.” Sure, it’ll spit out some lyrics, but good luck getting it to compose the actual music—or make it not suck.&lt;/p&gt;

&lt;p&gt;3️⃣ &lt;strong&gt;It’s a money pit&lt;/strong&gt; 💸 — Companies are pouring billions into AI projects, and for what? A chatbot that tells you to reboot your router? Meanwhile, the tech bros cashing the checks are laughing all the way to their private jets.&lt;/p&gt;

&lt;p&gt;4️⃣ &lt;strong&gt;It’s a job-security racket&lt;/strong&gt; 🤓 — The more incomprehensible the tech, the more indispensable the “experts” become. Suddenly, you need an “AI consultant” to tell you how to use it. Funny how that works, huh?&lt;/p&gt;

&lt;p&gt;5️⃣ &lt;strong&gt;It’s not even that new&lt;/strong&gt; 🕰️ — Machine learning’s been around for decades. They just slapped a sexy new label on it and called it “AI” so they could sell it to gullible CEOs who think “disruption” is a personality trait.&lt;/p&gt;

&lt;p&gt;But nah, let’s all pretend this is some groundbreaking revolution instead of a recycled hype cycle with better marketing.&lt;/p&gt;




&lt;p&gt;💰 Who’s Really Winning?&lt;br&gt;&lt;br&gt;
Spoiler: It’s not you, me, or society. The real winners are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cloud giants&lt;/strong&gt; ☁️ — AWS, Google, and Microsoft are raking it in as companies waste cash running AI models that need more computing power than a small country.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tech bros&lt;/strong&gt; 🕶️ — They get to look like visionaries while pocketing VC funding and speaking fees.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consultants&lt;/strong&gt; 🧑‍💼 — Someone’s gotta “teach” your team how to use this mess, right? Cha-ching!
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Meanwhile, the rest of us get stuck with half-baked AI “solutions” that break more than they fix. Your customer service chatbot can’t even refund my order, but sure, it’s gonna “transform industries.”&lt;/p&gt;




&lt;p&gt;🔥 “But AI Can Do Amazing Things!”&lt;br&gt;&lt;br&gt;
Oh, please. Spare me the TED Talk. Yeah, AI can generate a blurry picture of a cat or write a haiku about blockchain. Big whoop. You know what else can do amazing things? A human with a calculator and a decent work ethic. If you really think AI’s gonna magically fix the world, hand it over to your grandma and tell her to solve climate change. Let me know how that goes—probably ends with her asking it for knitting patterns while the planet keeps burning.&lt;/p&gt;

&lt;p&gt;The truth is, AI’s “amazing” feats are just party tricks propped up by clever prompts and cherry-picked demos. It’s not solving real problems—it’s creating new ones, like how to explain to your boss why the AI-powered app crashed the server again.&lt;/p&gt;




&lt;p&gt;🚀 The Sane Alternative (That Nobody Wants to Hear)&lt;br&gt;&lt;br&gt;
Here’s a wild idea: Instead of worshipping at the altar of AI, how about we focus on stuff that actually works?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hire competent people&lt;/strong&gt; 👩‍💻 — You don’t need a robot to do your job if you’ve got humans who know what they’re doing.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use proven tools&lt;/strong&gt; 🛠️ — Databases, algorithms, and good old-fashioned logic have been solving problems for years without the AI hype train.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stop overcomplicating everything&lt;/strong&gt; 🙅‍♂️ — Complexity isn’t innovation—it’s a liability.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But nah, that’s too boring. Why fix things the smart way when you can throw money at a shiny AI buzzword and call it progress?&lt;/p&gt;




&lt;p&gt;🤬 Final Rant: Wake Up, Sheeple!&lt;br&gt;&lt;br&gt;
I’m so done with this AI scam driving me up the wall. It’s not changing the world—it’s changing your bank account balance, and not in a good way. Tech bros have been wrong about everything from hoverboards to the metaverse, but somehow we’re all drinking the AI Kool-Aid like they’ve cracked the code to utopia. Newsflash: They haven’t. It’s a grift, a con, a sham—and the only thing it’s disrupting is my patience.&lt;/p&gt;

&lt;p&gt;Next time some smug startup founder tries to sell you on “AI-powered” anything, tell them to shove it. Better yet, give their precious AI to your grandma and watch it churn out a grocery list instead of the next billion-dollar app. Case closed. 🚨&lt;/p&gt;

</description>
      <category>ai</category>
    </item>
    <item>
      <title>Why You Should Just Study Computer Science: Regrets of a Self-Taught Software Engineer</title>
      <dc:creator>Itamar Tati </dc:creator>
      <pubDate>Fri, 28 Mar 2025 22:07:09 +0000</pubDate>
      <link>https://forem.com/itamartati/why-you-should-just-study-computer-science-regrets-of-a-self-taught-software-engineer-15f</link>
      <guid>https://forem.com/itamartati/why-you-should-just-study-computer-science-regrets-of-a-self-taught-software-engineer-15f</guid>
      <description>&lt;p&gt;I’ve always been fascinated by computers. As a kid, I was the one who aced every ICT class, the one who could troubleshoot family laptops, the one who instinctively understood how technology worked. But growing up in a public school where coding wasn’t even on the curriculum, no one ever pushed me to explore it further. No teacher said, &lt;em&gt;"You’re good at this—you should learn programming."&lt;/em&gt; No mentor guided me toward computer science. So, like many others, I stumbled into tech much later, teaching myself how to code out of passion.  &lt;/p&gt;

&lt;p&gt;And now, years into my career as a self-taught software engineer, I have one big regret: &lt;strong&gt;I wish I had just studied computer science.&lt;/strong&gt;  &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Limits of Being Self-Taught&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;When you teach yourself, you learn what you &lt;em&gt;need&lt;/em&gt; to know, not what you &lt;em&gt;should&lt;/em&gt; know. For me, that meant diving deep into frontend development—JavaScript, React, CSS—because that’s where the jobs were. And for a while, it worked. I built things, I got hired, I progressed.  &lt;/p&gt;

&lt;p&gt;But then reality hit: &lt;strong&gt;I was pigeonholed.&lt;/strong&gt;  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;"You’re Just a Frontend Dev"&lt;/strong&gt; – No matter how much I tried to branch out, people saw me as &lt;em&gt;only&lt;/em&gt; a frontend engineer. Colleagues with CS degrees—even those with less experience—were handed backend tasks, DevOps work, system design challenges. They were allowed to fail, to learn, to grow. Meanwhile, I was stuck in the same role, fighting the perception that I couldn’t do more.  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Gaps in Fundamentals&lt;/strong&gt; – I didn’t fully understand data structures, algorithms, or how computers really worked under the hood. When faced with complex problems, I had to work twice as hard just to catch up. CS grads had a structured foundation; I had scattered knowledge from tutorials and Stack Overflow.  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Shitty Startups &amp;amp; Stunted Growth&lt;/strong&gt; – Because I lacked a degree, my early career was a grind through exploitative startups—long hours, toxic cultures, zero mentorship. These companies didn’t invest in my growth; they just burned me out. Meanwhile, my peers with CS degrees walked into better-structured companies with real career paths.  &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Harsh Truth About Self-Taught vs. CS Degrees&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Yes, you &lt;em&gt;can&lt;/em&gt; succeed without a degree. But you’ll always be fighting an uphill battle:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Gatekeeping in Hiring&lt;/strong&gt; – Some companies (especially big tech) still filter resumes by degree.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lack of Depth&lt;/strong&gt; – Without formal education, you might miss critical concepts that become important later (networking, concurrency, compilers).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Career Ceilings&lt;/strong&gt; – Moving into senior roles, architecture, or specialized fields (AI, security, distributed systems) is much harder without foundational knowledge.
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;If You’re Young and Have the Chance—Just Study CS&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If you’re still in school or early in your career, and you love tech, &lt;strong&gt;go to university for computer science&lt;/strong&gt;. It’s not just about the degree—it’s about the structured learning, the mentorship, the exposure to concepts you’d never stumble upon alone. It’s about having the credibility to move freely in your career instead of being boxed into one role.  &lt;/p&gt;

&lt;p&gt;If, like me, you’re already deep into the self-taught path, it’s not hopeless—but you’ll have to work harder to fill the gaps. Study algorithms, take online CS courses, force yourself into unfamiliar areas of programming.  &lt;/p&gt;

&lt;p&gt;But if you have the choice? &lt;strong&gt;Don’t make my mistake. Just study computer science.&lt;/strong&gt; Your future self will thank you.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>career</category>
    </item>
    <item>
      <title>Code Review Tyrants: The Pretentious Pedants Strangling Your Productivity 🚩 (and Why Their Code Sucks 💩)</title>
      <dc:creator>Itamar Tati </dc:creator>
      <pubDate>Fri, 14 Mar 2025 17:15:45 +0000</pubDate>
      <link>https://forem.com/itamartati/code-review-tyrants-the-pretentious-pedants-strangling-your-productivity-and-why-their-code-2e41</link>
      <guid>https://forem.com/itamartati/code-review-tyrants-the-pretentious-pedants-strangling-your-productivity-and-why-their-code-2e41</guid>
      <description>&lt;p&gt;Let’s call them what they really are: &lt;strong&gt;Code Review Tyrants&lt;/strong&gt; 👑. These aren’t just “bad” reviewers—they’re a special breed of self-righteous, nitpicking, productivity-sucking vampires � who treat every pull request like it’s their personal battleground ⚔️. They’re not here to help you write better code; they’re here to flex their superiority complex 💪, waste your time ⏳, and make you question why you even bother showing up to work 🤔. If you’ve ever had your PR held hostage over a missing semicolon 🚨, a background color that’s “not quite right” 🎨, or indentation that doesn’t match their personal preferences 📏, you know exactly what I’m talking about.&lt;/p&gt;

&lt;p&gt;And here’s the sad part: these people are almost always higher than you on the ladder 🪜. They’ve somehow climbed their way into positions of power, and now they’re using that power to make your life miserable 😤. But don’t worry—their code is usually a dumpster fire of bugs 🐛, inefficiency 🐌, and crashes 💥. You can’t make this stuff up.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Code Review Tyrant’s Playbook 📖
&lt;/h3&gt;

&lt;p&gt;Code Review Tyrants are masters of turning a collaborative process into a soul-crushing ordeal. Here’s how they operate:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Semicolon Sheriff 🤠&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
You’re working in JavaScript, and you forgot a semicolon. Big deal, right? Wrong. The Semicolon Sheriff is on the case 🕵️‍♂️, and they’re ready to write a dissertation on why your missing semicolon is a “critical issue” 🚨. Never mind that modern JavaScript doesn’t even require semicolons in most cases. Never mind that your code works perfectly fine without it. Nope, this is about &lt;em&gt;principle&lt;/em&gt; 🧐. And by “principle,” I mean their desperate need to feel superior 😏.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The CSS Color Cop 🚔&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
You’re working on a UI, and you set a background color to &lt;code&gt;#F5F5F5&lt;/code&gt;. But wait—the CSS Color Cop has arrived, and they’re furious 😡. “This should be &lt;code&gt;#F4F4F4&lt;/code&gt;,” they declare, as if the difference between these two shades of off-white is the hill they’re willing to die on ⚰️. Meanwhile, their own CSS is a bloated mess of &lt;code&gt;!important&lt;/code&gt; tags and inline styles 🗑️, but hey, at least their colors are &lt;em&gt;perfect&lt;/em&gt; 👌.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Indentation Inquisitor 🧐&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
You’re working in a language that doesn’t care about indentation (like Java or C#), and you used 3 spaces instead of 4. Or maybe you used tabs instead of spaces. Or maybe you mixed them. Whatever you did, the Indentation Inquisitor is here to make sure you never do it again 🚫. They’ll reject your PR faster than you can say “linting rules” 📜, all while their own code is a chaotic mess of inconsistent formatting and random line breaks 🤯.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Framework Fanatic 🛠️&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
You wrote a simple utility function to solve a problem. It’s clean, it’s efficient, and it works. But the Framework Fanatic is having none of it 🙅‍♂️. “Why didn’t you use [insert bloated library here]?” they demand, as if adding 10,000 lines of unnecessary dependencies is somehow better than writing 10 lines of straightforward code 🤦‍♀️. Spoiler alert: their code is a Frankenstein’s monster of outdated libraries and deprecated APIs 🧟‍♂️, but they’ll never admit it.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Why Do They Do It? 🤷‍♂️
&lt;/h3&gt;

&lt;p&gt;Let’s be real: Code Review Tyrants aren’t trying to improve the codebase. They’re trying to validate their own egos 🥳. For some reason, they’ve convinced themselves that their nitpicking makes them a “senior” developer, when in reality, it just makes them insufferable 😒. They’re the kind of people who think that writing “clean code” means following every rule in the book 📚, even if it makes the code harder to read, harder to maintain, and slower to ship 🐢.&lt;/p&gt;

&lt;p&gt;And here’s the kicker: these people are often the least productive members of the team 🏃‍♂️💨. While everyone else is busy delivering value, they’re busy writing novels in the comments section of your PR 📖. They’re not adding value—they’re adding friction 🔥.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Irony: Their Code Is Garbage 🗑️
&lt;/h3&gt;

&lt;p&gt;Here’s the part that really stings: &lt;strong&gt;Code Review Tyrants usually have the worst code in the entire company&lt;/strong&gt; 🏢. Their code is slow 🐌, buggy 🐛, and crashes more often than a toddler learning to ride a bike 🚴‍♂️. But because they’re higher up the ladder, no one dares to call them out on it 🙊. Instead, they get to sit in their ivory tower 🏰, nitpicking everyone else’s work while their own garbage code languishes in production, causing outages and frustrating users 😤.&lt;/p&gt;

&lt;p&gt;You can’t make this up. These are the same people who will reject your PR because your function name isn’t “descriptive enough,” but their own functions are 300 lines long, have 15 nested &lt;code&gt;if&lt;/code&gt; statements, and are littered with magic numbers and hardcoded strings 🧙‍♂️. The cognitive dissonance is mind-blowing 🤯.&lt;/p&gt;




&lt;h3&gt;
  
  
  Why You Can’t Deal with Them (and Why It Sucks) 😩
&lt;/h3&gt;

&lt;p&gt;Here’s the brutal truth: &lt;strong&gt;there’s no way to deal with them&lt;/strong&gt; 🚫. They’re usually higher than you on the ladder, which means they have the power to block your PRs, derail your projects, and make your life a living hell 🔥. If you push back, they’ll label you as “difficult” or “not a team player” 🏷️. If you escalate, they’ll spin the narrative to make you look like the problem 🎭. And if you try to ignore them, they’ll just double down on their nitpicking 🔍.&lt;/p&gt;

&lt;p&gt;It’s a lose-lose situation, and it’s one of the most toxic aspects of working in tech 💻. These people thrive in environments where hierarchy matters more than merit, and they use their position to shield themselves from accountability 🛡️.&lt;/p&gt;




&lt;h3&gt;
  
  
  What Can You Do? (Spoiler: Not Much) 🤷‍♀️
&lt;/h3&gt;

&lt;p&gt;Let’s be honest: most of the advice you’ll find about dealing with Code Review Tyrants is useless 🗑️. “Document everything” 📝? Sure, because nothing says “productive work environment” like keeping a spreadsheet of petty arguments. “Play the game” 🎮? Great, let’s all waste our time appeasing someone who’s clearly compensating for their lack of actual skills. “Find allies” 🤝? Cool, but good luck convincing anyone to stand up to the person who signs their performance reviews.&lt;/p&gt;

&lt;p&gt;The sad reality is that the only real solution is to &lt;strong&gt;find another job&lt;/strong&gt; 🏃‍♂️💨. If your company tolerates this kind of behavior, it’s probably not a great place to work 🏢. Start looking for a new job where your skills are valued and your time isn’t wasted by petty tyrants 👑.&lt;/p&gt;




&lt;h3&gt;
  
  
  Final Thoughts: Stop the Madness 🛑
&lt;/h3&gt;

&lt;p&gt;Code reviews are supposed to be a collaborative process, not a power trip 🚀. It’s time to stop letting Code Review Tyrants hijack the process with their nonsense 🤡. If you’re one of these people, take a long, hard look in the mirror 🪞 and ask yourself: are you actually helping, or are you just being a pretentious pain in the ass? The answer might surprise you. And if it doesn’t, well, maybe it’s time to find a new hobby—one that doesn’t involve ruining everyone else’s day 🌞.&lt;/p&gt;

&lt;p&gt;And to everyone else: keep your head down, keep shipping 🚢, and remember—their code is probably worse than yours 💩.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>career</category>
    </item>
    <item>
      <title>It’s Time to Stop Calling It "Artificial Intelligence"—Let’s Call It "Artificial Calculations" Instead</title>
      <dc:creator>Itamar Tati </dc:creator>
      <pubDate>Tue, 11 Mar 2025 08:52:24 +0000</pubDate>
      <link>https://forem.com/itamartati/its-time-to-stop-calling-it-artificial-intelligence-lets-call-it-artificial-calculations-31p7</link>
      <guid>https://forem.com/itamartati/its-time-to-stop-calling-it-artificial-intelligence-lets-call-it-artificial-calculations-31p7</guid>
      <description>&lt;p&gt;The term "artificial intelligence" (AI) has become ubiquitous in our modern world. From video games to self-driving cars, and from chatbots to image generators, AI is everywhere. But here’s the problem: the term is deeply misleading. What we call "AI" isn’t intelligent—it’s a series of mathematical calculations performed by machines. It doesn’t think, reason, or understand; it computes. It’s time to retire the term "artificial intelligence" and replace it with something more accurate: &lt;strong&gt;artificial calculations&lt;/strong&gt; or &lt;strong&gt;artificial computation&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%2F5jphytpz1bktt9bnbyms.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%2F5jphytpz1bktt9bnbyms.png" alt="Image of AI robot looking sinister" width="800" height="606"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Misleading Nature of "Artificial Intelligence"
&lt;/h3&gt;

&lt;p&gt;The term "artificial intelligence" evokes images of sentient machines, capable of human-like thought and creativity. This is a fantasy. What we currently have as AI is nothing more than sophisticated algorithms that process data, recognize patterns, and generate outputs based on predefined rules. For example, ChatGPT can write essays, but it doesn’t "understand" the words it’s producing—it’s simply predicting the next word in a sequence based on its training data. Similarly, the AI in a game like &lt;em&gt;Total War&lt;/em&gt; doesn’t "strategize"; it follows a set of instructions to move units and attack targets.&lt;/p&gt;

&lt;p&gt;This isn’t intelligence—it’s computation. Intelligence implies the ability to reason, adapt, and think critically. AI, as it exists today, does none of these things. It’s a tool, not a mind. By calling it "artificial intelligence," we’re perpetuating a myth that obscures the true nature of these systems and inflates public expectations.&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%2Fp2zkn8ta8morrt89xcs8.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%2Fp2zkn8ta8morrt89xcs8.png" alt="Image of quote by Thomas Jefferson about the importance of honesty" width="800" height="376"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Why "Artificial Calculations" Is a Better Term
&lt;/h3&gt;

&lt;p&gt;The term "artificial calculations" is far more accurate. It reflects the reality that these systems are performing mathematical operations, not engaging in anything resembling human thought. Here’s why this term works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;It’s Honest&lt;/strong&gt;: "Artificial calculations" doesn’t pretend to be something it’s not. It acknowledges that these systems are based on math, not intelligence.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It’s Clear&lt;/strong&gt;: The term removes the mystique surrounding AI and helps people understand what these systems actually do.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It’s Specific&lt;/strong&gt;: Unlike "AI," which is a vague and overused term, "artificial calculations" describes the process at the heart of these systems.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For example, when you play a game like &lt;em&gt;Civilization&lt;/em&gt; and the AI makes a decision, it’s not "thinking"—it’s running calculations to determine the optimal move based on its programming. When you use a tool like MidJourney to generate art, it’s not "creating"—it’s processing data to produce an image based on patterns it has learned. These are computational tasks, not acts of intelligence.&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%2F74y8hmgpmpurpggacidy.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%2F74y8hmgpmpurpggacidy.png" alt="AI created image of a man looking a city with advertisements calling for AI takeover and AI revolution" width="686" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Problem with Overhyping AI
&lt;/h3&gt;

&lt;p&gt;The misuse of the term "artificial intelligence" has real-world consequences. It creates unrealistic expectations about what these systems can do, leading to disappointment when they inevitably fall short. For example, players often complain about the "stupidity" of AI in games like &lt;em&gt;Total War&lt;/em&gt; or &lt;em&gt;XCOM&lt;/em&gt;, not realizing that the AI was never intelligent to begin with—it was just following a script. Similarly, people are sometimes alarmed by the capabilities of generative AI, fearing that it might "take over" or "replace humans," when in reality, it’s just a sophisticated tool that relies on human input and oversight.&lt;/p&gt;

&lt;p&gt;By rebranding AI as "artificial calculations," we can reset these expectations. People will understand that these systems are tools, not rivals, and that their capabilities are limited to the data and algorithms they’re built on.&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%2F85lo66zdfkcf7wzriua3.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%2F85lo66zdfkcf7wzriua3.png" alt="Meme of drake saying no to learning from experts but preferring to learn from AI influencers" width="498" height="483"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Hype Economy: Selling AI Solutions and Courses
&lt;/h3&gt;

&lt;p&gt;One of the most troubling consequences of the AI hype is the rise of companies and individuals profiting from the confusion. The market is flooded with "AI solutions" and "AI courses" that promise to revolutionize businesses, careers, and lives. But many of these offerings are built on buzzwords, not substance. Companies sell AI-powered tools as if they’re magic bullets, while self-proclaimed experts peddle courses that claim to teach "AI mastery" in a matter of weeks.&lt;/p&gt;

&lt;p&gt;The problem is that many buyers don’t understand what they’re purchasing. They hear "AI" and assume they’re getting cutting-edge technology that can solve all their problems. In reality, they’re often buying basic automation tools or pre-packaged algorithms that are far less impressive than the marketing suggests. For example, a small business might invest in an "AI-driven marketing platform" only to discover that it’s just a glorified email scheduler with some data analytics tacked on.&lt;/p&gt;

&lt;p&gt;Similarly, individuals might spend hundreds or even thousands of dollars on AI courses, hoping to land a high-paying job in the tech industry. But many of these courses offer little more than surface-level knowledge, leaving students ill-prepared for the realities of working with these systems. The hype around AI creates a gold rush mentality, where companies and individuals exploit the public’s lack of understanding to make a quick profit.&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%2Fxfuspnpqq9676gzut8qd.gif" 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%2Fxfuspnpqq9676gzut8qd.gif" alt="Animation of AI in Rome 2 being bad" width="300" height="168"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Gaming Industry: A Case Study in Misleading AI
&lt;/h3&gt;

&lt;p&gt;The gaming industry is a perfect example of how the term "AI" creates false expectations. In games, AI is often used to control non-player characters (NPCs) or opponents. But as any experienced gamer knows, these systems are rarely impressive. They follow predictable patterns, make obvious mistakes, and can often be "tricked" by players who understand how they work.&lt;/p&gt;

&lt;p&gt;For instance, in &lt;em&gt;Total War&lt;/em&gt;, the AI might send its units charging into a trap because it’s programmed to prioritize attacking the closest target. In &lt;em&gt;XCOM&lt;/em&gt;, the AI might ignore a high-value target in favor of attacking a less threatening one. These behaviors aren’t signs of intelligence—they’re the result of rigid calculations that lack the flexibility and adaptability of human thought.&lt;/p&gt;

&lt;p&gt;If we called these systems "artificial calculations" instead of "AI," players would have a better understanding of their limitations. They wouldn’t expect the AI to be a genius tactician; they’d understand that it’s just a set of rules and math problems running in the background.&lt;/p&gt;




&lt;h3&gt;
  
  
  A Call for Change
&lt;/h3&gt;

&lt;p&gt;It’s time for a shift in how we talk about these systems. The term "artificial intelligence" is not only inaccurate but also harmful. It creates confusion, inflates expectations, and distracts from the real potential of these technologies. By adopting terms like "artificial calculations" or "artificial computation," we can foster a more honest and productive conversation about what these systems can and cannot do.&lt;/p&gt;

&lt;p&gt;This change isn’t just about semantics—it’s about clarity and accountability. When we stop pretending that these systems are intelligent, we can focus on improving them in meaningful ways. We can design better algorithms, create more transparent systems, and set realistic expectations for their use.&lt;/p&gt;




&lt;h3&gt;
  
  
  Conclusion: Let’s Embrace Accuracy
&lt;/h3&gt;

&lt;p&gt;The term "artificial intelligence" has had its moment, but it’s time to move on. What we’re dealing with isn’t intelligence—it’s computation. By calling it "artificial calculations," we can better reflect the reality of these systems and set the stage for a more informed and realistic discussion about their role in our world.&lt;/p&gt;

&lt;p&gt;Whether it’s in gaming, generative tools, or any other application, let’s stop pretending that these systems are something they’re not. Let’s embrace accuracy, clarity, and honesty. The future of technology depends on it. And let’s not forget: the hype around AI isn’t just misleading—it’s profitable for those who exploit it. It’s time to cut through the noise and focus on what really matters: understanding and improving the tools we have, not the fantasies we’ve been sold.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>career</category>
      <category>chatgpt</category>
    </item>
    <item>
      <title>🚨 Micro-frontends: The Dumbest Idea Tech Bros Have Ever Sold to Businesses 🚨</title>
      <dc:creator>Itamar Tati </dc:creator>
      <pubDate>Fri, 28 Feb 2025 23:06:29 +0000</pubDate>
      <link>https://forem.com/itamartati/micro-frontends-the-dumbest-idea-tech-bros-have-ever-sold-to-businesses-heh</link>
      <guid>https://forem.com/itamartati/micro-frontends-the-dumbest-idea-tech-bros-have-ever-sold-to-businesses-heh</guid>
      <description>&lt;p&gt;Ah yes, &lt;strong&gt;microfrontends&lt;/strong&gt;—because somehow, breaking your perfectly fine frontend into a convoluted mess of multiple frameworks, repositories, and deployment pipelines is &lt;strong&gt;the future™&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;&lt;em&gt;"We need independent teams!"&lt;/em&gt; they scream.&lt;br&gt;&lt;br&gt;
&lt;em&gt;"We need better scalability!"&lt;/em&gt; they insist.&lt;br&gt;&lt;br&gt;
&lt;em&gt;"We need microfrontends!"&lt;/em&gt; they whine, without a single clue why.  &lt;/p&gt;

&lt;p&gt;Let me tell you the &lt;strong&gt;real&lt;/strong&gt; reason microfrontends exist: &lt;strong&gt;To make software engineers look smart while bleeding businesses dry.&lt;/strong&gt;  &lt;/p&gt;

&lt;h2&gt;
  
  
  🤡 How to Overcomplicate the Simple
&lt;/h2&gt;

&lt;p&gt;For &lt;strong&gt;years&lt;/strong&gt;, we’ve had modular architectures. We’ve had &lt;strong&gt;reusable components, lazy loading, and optimized build pipelines&lt;/strong&gt;—all of which solve the same problems &lt;strong&gt;without turning your app into a dumpster fire&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;But no, that wasn’t enough. Instead, some genius decided:  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Hey, what if we take our frontend and smash it into a thousand tiny pieces, each requiring its own framework, build process, and deployment strategy? Sounds smart, right?"  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And thus, the &lt;strong&gt;clown show&lt;/strong&gt; known as microfrontends was born.  &lt;/p&gt;

&lt;h3&gt;
  
  
  🎭 The Reality of Microfrontends
&lt;/h3&gt;

&lt;p&gt;Let’s talk about what &lt;strong&gt;really&lt;/strong&gt; happens when you go down this rabbit hole:  &lt;/p&gt;

&lt;p&gt;1️⃣ &lt;strong&gt;Your app becomes an incoherent mess&lt;/strong&gt; 🧩 – One page is React, another is Angular, and suddenly Vue.js is lurking in the corner like an unwanted guest.&lt;br&gt;&lt;br&gt;
2️⃣ &lt;strong&gt;Performance nosedives into the ground&lt;/strong&gt; 💀 – Because, of course, loading three different JavaScript runtimes on the same page &lt;strong&gt;totally&lt;/strong&gt; makes sense.&lt;br&gt;&lt;br&gt;
3️⃣ &lt;strong&gt;Styling consistency? HA!&lt;/strong&gt; 🎨 – Every team rolls their own styles, breaking your design system &lt;strong&gt;beyond repair&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
4️⃣ &lt;strong&gt;Debugging turns into a full-time job&lt;/strong&gt; 🔍 – "Why is this page broken? Oh, right, because it was built by a separate team in a completely different repo with zero coordination!"&lt;br&gt;&lt;br&gt;
5️⃣ &lt;strong&gt;Deployments become a nightmare&lt;/strong&gt; 😱 – Hope you enjoy spending weeks figuring out which microfrontend update broke the entire app.  &lt;/p&gt;

&lt;p&gt;But hey, who cares about any of this? It’s &lt;em&gt;modern engineering&lt;/em&gt;, right?  &lt;/p&gt;

&lt;h2&gt;
  
  
  🏆 The Scam: How Engineers Sell Microfrontends to Clueless Executives
&lt;/h2&gt;

&lt;p&gt;The best part? &lt;strong&gt;Business people fall for this nonsense every time.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;Why? Because they don’t understand tech, and engineers &lt;strong&gt;love&lt;/strong&gt; taking advantage of that.  &lt;/p&gt;

&lt;p&gt;All it takes is a few buzzwords in a PowerPoint:  &lt;/p&gt;

&lt;p&gt;✅ &lt;em&gt;"Independent deployments!"&lt;/em&gt;&lt;br&gt;&lt;br&gt;
✅ &lt;em&gt;"Scalability!"&lt;/em&gt;&lt;br&gt;&lt;br&gt;
✅ &lt;em&gt;"Autonomous teams!"&lt;/em&gt;&lt;br&gt;&lt;br&gt;
✅ &lt;em&gt;"Microservices, but for the frontend!"&lt;/em&gt;  &lt;/p&gt;

&lt;p&gt;And boom—&lt;strong&gt;millions of dollars get flushed down the drain&lt;/strong&gt; on unnecessary complexity.  &lt;/p&gt;

&lt;p&gt;Meanwhile, the engineers pushing this garbage &lt;strong&gt;cash in on consultant fees, job security, and endless infrastructure budgets.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;Because guess what? The harder your system is to understand, the more valuable they become.  &lt;/p&gt;

&lt;h2&gt;
  
  
  🔥 Disagree? Get Fired
&lt;/h2&gt;

&lt;p&gt;And here’s the kicker: &lt;strong&gt;If you dare to question this stupidity, you get labeled as ‘resistant to change.’&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;💀 &lt;em&gt;"Oh, you just don’t want to adapt!"&lt;/em&gt;&lt;br&gt;&lt;br&gt;
💀 &lt;em&gt;"You’re a junior dev who doesn’t understand modern architecture!"&lt;/em&gt;&lt;br&gt;&lt;br&gt;
💀 &lt;em&gt;"This is how FAANG does it, so it must be good!"&lt;/em&gt;  &lt;/p&gt;

&lt;p&gt;The moment you challenge the microfrontend scam, &lt;strong&gt;you become a threat.&lt;/strong&gt; And since tech is a glorified popularity contest, they’ll shove you out the door before admitting they’re wrong.  &lt;/p&gt;

&lt;h2&gt;
  
  
  💸 Who Actually Benefits?
&lt;/h2&gt;

&lt;p&gt;Let’s be honest—microfrontends &lt;strong&gt;only&lt;/strong&gt; exist to:  &lt;/p&gt;

&lt;p&gt;💰 &lt;strong&gt;Sell more cloud infrastructure&lt;/strong&gt; – AWS, Google Cloud, and Vercel love when companies waste money on microfrontend garbage.&lt;br&gt;&lt;br&gt;
💰 &lt;strong&gt;Give engineers job security&lt;/strong&gt; – The more complex your system, the harder it is to fire them.&lt;br&gt;&lt;br&gt;
💰 &lt;strong&gt;Let consultants milk businesses for all they’re worth&lt;/strong&gt; – Because someone has to "train" your team to deal with the chaos they created.  &lt;/p&gt;

&lt;p&gt;Meanwhile, the actual product? &lt;strong&gt;Slower. Buggier. More expensive.&lt;/strong&gt;  &lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 The Simple Alternative (That Actually Works)
&lt;/h2&gt;

&lt;p&gt;If you &lt;strong&gt;actually&lt;/strong&gt; care about your business (and your sanity), do this instead:  &lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Use a well-architected monolith&lt;/strong&gt; – Modern frontend frameworks already support modularization &lt;strong&gt;without the insanity&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Leverage component-based design&lt;/strong&gt; – Break things up inside a single codebase, instead of spawning 10+ unnecessary repos.&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Use lazy loading and code splitting&lt;/strong&gt; – You don’t need a different framework for each page. &lt;strong&gt;Just load what you need, when you need it.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;But no—why do things the easy way when you can create &lt;strong&gt;a bloated, overengineered disaster that guarantees job security for bad engineers?&lt;/strong&gt;  &lt;/p&gt;

&lt;h2&gt;
  
  
  🔥 Final Thoughts: Stop Falling for the Bullsh*t
&lt;/h2&gt;

&lt;p&gt;If you take &lt;strong&gt;one&lt;/strong&gt; thing away from this, let it be this:  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Microfrontends are a scam.&lt;/strong&gt;  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;They don’t improve performance.&lt;br&gt;&lt;br&gt;
They don’t make development easier.&lt;br&gt;&lt;br&gt;
They don’t solve any real problems &lt;strong&gt;that can’t already be solved with better architecture.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;The only thing they do? &lt;strong&gt;Make incompetent engineers look smart while setting businesses on fire.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;So next time some clown tries to sell you on microfrontends, &lt;strong&gt;tell them to get lost.&lt;/strong&gt; 🚀  &lt;/p&gt;

</description>
      <category>microservices</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>career</category>
    </item>
  </channel>
</rss>
