<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Damilola Oshungboye</title>
    <description>The latest articles on DEV Community by Damilola Oshungboye (@thatcoolguy).</description>
    <link>https://dev.to/thatcoolguy</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%2F173379%2Fdf729b12-338b-41e6-9b7d-e9e17bdb741b.JPEG</url>
      <title>DEV Community: Damilola Oshungboye</title>
      <link>https://dev.to/thatcoolguy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/thatcoolguy"/>
    <language>en</language>
    <item>
      <title>How to refine Hope AI output after the initial generation</title>
      <dc:creator>Damilola Oshungboye</dc:creator>
      <pubDate>Tue, 19 May 2026 20:00:13 +0000</pubDate>
      <link>https://dev.to/hackmamba/how-to-refine-hope-ai-output-after-the-initial-generation-59mn</link>
      <guid>https://dev.to/hackmamba/how-to-refine-hope-ai-output-after-the-initial-generation-59mn</guid>
      <description>&lt;p&gt;If you’ve tried &lt;a href="https://medium.com/bitsrc/a-devs-guide-to-prompting-bit-cloud-the-right-way-6640b5bfe7fc" rel="noopener noreferrer"&gt;prompting Hope AI&lt;/a&gt;, you know the first version is a production-grade application that can be used immediately. But a working app isn't always the right app.&lt;/p&gt;

&lt;p&gt;As you review the generated output, you may notice areas where the application isn’t aligned with your requirements or where boundaries and interfaces need adjustment. That’s a normal part of the process, and you shouldn’t have to start over to address it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://bit.cloud/products/hope-ai" rel="noopener noreferrer"&gt;Hope AI&lt;/a&gt;’s output is designed to be refined in place, with components and contracts that stay consistent as you make changes. That stability lets you narrow the scope and improve the structure step by step, building forward instead of starting over&lt;/p&gt;

&lt;p&gt;This article covers how refinement works in Hope AI. It explains how to improve output after the first version and how teams use this process to move toward review and release.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is refinement in Hope AI?
&lt;/h2&gt;

&lt;p&gt;Refinement is the process of aligning the generated structure with what you actually intend to build. It is how you make the structure clearer and more focused. This stage is where many teams lose momentum by jumping straight into implementation details, rather than clarifying what the product should do. &lt;/p&gt;

&lt;p&gt;That approach tends to backfire because external tools often provide generic solutions that can clash with existing architectural decisions or introduce unnecessary complexity. The result looks more technical, but it’s harder to evaluate and extend.&lt;/p&gt;

&lt;p&gt;Effective refinement works the other way around. It starts by narrowing the question. What behavior needs to change? Which feature is affected? How should the user experience differ after the change?&lt;/p&gt;

&lt;p&gt;That kind of request gives Hope AI something concrete to work with. Once the behavior is clear, adjusting the structure becomes straightforward. You might split responsibilities, tighten interfaces or move logic into a more appropriate place, but those changes follow naturally from intent.&lt;/p&gt;

&lt;p&gt;The important point is that refinement builds on what already exists. You are not replacing the system or re-specifying everything from scratch. The overall shape remains intact, while each pass makes the code easier to review, explain and move forward with.&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%2Fflh7hasi5yh4fibb8f7g.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%2Fflh7hasi5yh4fibb8f7g.png" alt="Hope AI’s Refinement Cycle" width="799" height="492"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How refinement with Hope AI differs from other AI builders
&lt;/h2&gt;

&lt;p&gt;Many AI app builders treat updates as replacements. When a change is requested, the system regenerates large portions of the output, often resetting context and obscuring earlier structural decisions.&lt;/p&gt;

&lt;p&gt;Hope AI follows a different approach.&lt;/p&gt;

&lt;p&gt;Because components and contracts persist across iterations, changes are applied within existing boundaries rather than replacing the output completely. Context also accumulates as the system evolves and earlier decisions continue to shape what comes next. The table below highlights this difference.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Other AI builders&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Hope AI&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Change triggers regeneration&lt;/td&gt;
&lt;td&gt;Change triggers refinement&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Context often lost&lt;/td&gt;
&lt;td&gt;Context accumulates&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Output replaced&lt;/td&gt;
&lt;td&gt;Output evolves through targeted updates&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Iteration breaks structure&lt;/td&gt;
&lt;td&gt;Iteration sharpens structure&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Since structure and intent remain intact, developers can make focused adjustments that improve quality without destabilizing the system. Each change builds on what already exists, which is why refinement in Hope AI tends to strengthen earlier work rather than undo it.&lt;/p&gt;

&lt;p&gt;That’s the foundation for the techniques below.&lt;/p&gt;

&lt;h2&gt;
  
  
  Techniques for refining Hope AI output
&lt;/h2&gt;

&lt;p&gt;Here are some practical techniques to refine Hope AI output and prepare it for review.&lt;/p&gt;

&lt;p&gt;Refinement usually involves:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Narrowing component responsibility when boundaries blur&lt;/li&gt;
&lt;li&gt;Defining explicit contracts and interfaces&lt;/li&gt;
&lt;li&gt;Using tests to make expected behavior clear&lt;/li&gt;
&lt;li&gt;Respecting existing patterns unless the reason to break them is explicit&lt;/li&gt;
&lt;li&gt;Asking Hope AI to explain architectural decisions before changing them&lt;/li&gt;
&lt;li&gt;Aligning naming conventions for consistency&lt;/li&gt;
&lt;li&gt;Refactoring integration points to keep them flexible&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of the techniques below expands on one of these moves and shows how to apply it without having to start over.&lt;/p&gt;

&lt;p&gt;1.&lt;strong&gt;Narrow component responsibility when boundaries blur&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When components have overlapping responsibilities, review becomes difficult. Mixed logic forces reviewers to sort through code just to understand intent. Splitting those concerns into focused pieces with clear boundaries makes the structure easier to follow.&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="c1"&gt;// Before&lt;/span&gt;
    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;UserProfile&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;handleLogin&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;credentials&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;handleUpdate&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;data&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;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;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;user&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;LoginForm&lt;/span&gt; &lt;span class="nx"&gt;onSubmit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleLogin&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt; : null&lt;/span&gt;&lt;span class="err"&gt;}
&lt;/span&gt;          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;isEditing&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;EditForm&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;DisplayProfile&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// After&lt;/span&gt;
    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ProfileDisplay&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="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&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;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&amp;gt;&lt;/span&gt;&lt;span class="err"&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;ProfileEditor&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;onSave&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="nx"&gt;onSubmit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onSave&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/form&amp;gt;&lt;/span&gt;&lt;span class="err"&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;AuthManager&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;onAuthSuccess&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;LoginForm&lt;/span&gt; &lt;span class="nx"&gt;onSubmit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleLogin&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Components that have a single responsibility are easier to review. Reviewers can review each part independently without having to sort through mixed logic.&lt;/p&gt;

&lt;p&gt;2.&lt;strong&gt;Define explicit contracts and interfaces&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Generic objects or unclear methods can lead to runtime errors. By defining clear contracts for data and component boundaries, teams can spot mismatches early and keep changes isolated.&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="c1"&gt;// Before&lt;/span&gt;
    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;UserForm&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;onSubmit&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;handleSubmit&lt;/span&gt; &lt;span class="o"&gt;=&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;onSubmit&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="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// After&lt;/span&gt;
    &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;UserFormData&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&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;UserForm&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; 
      &lt;span class="nx"&gt;onSubmit&lt;/span&gt; 
    &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
      &lt;span class="nl"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;:&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;UserFormData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 
    &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;validate&lt;/span&gt; &lt;span class="o"&gt;=&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;UserFormData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&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;@&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="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;field&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Invalid email&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="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clear contracts help teams find integration issues during development. Reviewers can verify that components work together simply by examining the interface definitions.&lt;/p&gt;

&lt;p&gt;3.&lt;strong&gt;Use test descriptions to clarify expected behavior&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If test names are too vague, it’s hard to tell what the component does. Reviewers can’t verify that the code is correct by looking at generic test descriptions. Use test names that clearly describe the behavior you’re testing.&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="c1"&gt;// Before&lt;/span&gt;
    &lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;EmailValidator&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;works&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&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;toBe&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="c1"&gt;// After&lt;/span&gt;
    &lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;EmailValidator&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rejects empty email addresses&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&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;toEqual&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
          &lt;span class="na"&gt;valid&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="na"&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;Email is required&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="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;accepts valid email format&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;validate&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@example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toEqual&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
          &lt;span class="na"&gt;valid&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="p"&gt;});&lt;/span&gt;

      &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;trims whitespace before validation&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;validate&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@example.com  &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toEqual&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
          &lt;span class="na"&gt;valid&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="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;Descriptive test names indicate how the code should work, so teams can infer the requirements from them.&lt;/p&gt;

&lt;p&gt;4.&lt;strong&gt;Respect existing patterns unless the reason is explicit&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Refinement can weaken a system when it introduces behavior that doesn’t line up with how the rest of the codebase already works. &lt;/p&gt;

&lt;p&gt;Breaking a pattern can still be the right decision. What matters is whether the reason is stated explicitly in the request. When the business context is explicit, Hope AI can apply the change in a narrow way while preserving the rest of the system’s structure.&lt;/p&gt;

&lt;p&gt;5.&lt;strong&gt;Ask Hope AI to explain architectural decisions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sometimes, the generated structure reflects design trade-offs that aren’t immediately obvious. Without that context, it can be harder to evaluate how the architecture fits your project.&lt;/p&gt;

&lt;p&gt;When something isn’t clear, ask Hope AI to explain the reasoning behind its choices and the trade-offs involved. This gives you a clearer view of how the design aligns with your requirements and where you might want to adjust scope or complexity as refinement continues.&lt;/p&gt;

&lt;p&gt;6.&lt;strong&gt;Clarify naming conventions for consistency&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When components and functions use different naming styles, it becomes harder to understand the code. Developers end up spending time on naming conventions rather than on logic. To avoid this, use consistent naming conventions so the codebase is easy to scan and understand. Consistent naming helps teams quickly spot component types, utilities and hooks without having to read through all the code.&lt;/p&gt;

&lt;p&gt;7.&lt;strong&gt;Ask Hope AI to refactor integration points to avoid vendor lock-in&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Components that interact with external systems benefit from clearly defined integration boundaries. You can ask Hope AI to refactor integrations using clear adapter interfaces, making it easy to swap out external services.&lt;/p&gt;

&lt;p&gt;Putting vendor-specific details behind clear contracts helps keep your core components stable and makes it easy to swap out different implementations without changing the system’s core logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to stop refining and start reviewing
&lt;/h2&gt;

&lt;p&gt;You know you’re ready to review when further changes no longer meaningfully improve the generated structure. In practice, teams are ready to review Hope AI output when the following conditions are true:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each component has a clear responsibility that can be explained plainly, without qualifiers.&lt;/li&gt;
&lt;li&gt;Interfaces express intent directly, without relying on comments or implicit assumptions.&lt;/li&gt;
&lt;li&gt;Tests describe expected behavior clearly and fail for meaningful reasons.&lt;/li&gt;
&lt;li&gt;Changes to one component stay contained and don’t ripple into unrelated areas.&lt;/li&gt;
&lt;li&gt;The code feels ready to hand off to another engineer without additional context.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At this point, refinement has done its job. The structure is stable and the system can be evaluated and extended through normal peer review processes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;In Hope AI, work begins with prompting. Right from your first prompt, you receive well-structured, production-ready code. The next step is refinement, where teams adjust the output to fit their workflows and prepare it for review.&lt;/p&gt;

&lt;p&gt;If you remember only one thing about refining Hope AI output, make it structural consistency. Refinement works best when you &lt;a href="https://bit.cloud/docs/hope-ai/coding-patterns" rel="noopener noreferrer"&gt;follow the patterns already present in the system&lt;/a&gt;, where each feature owns its UI, data logic and API surface. Building within that structure keeps changes contained and maintenance straightforward.&lt;/p&gt;

&lt;p&gt;Next, try using one or two of these refinement techniques on your current Hope AI project and see how quickly the output becomes ready for review.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>The Three-Layer Architecture That Makes Software Production-Ready</title>
      <dc:creator>Damilola Oshungboye</dc:creator>
      <pubDate>Tue, 19 May 2026 19:59:32 +0000</pubDate>
      <link>https://dev.to/hackmamba/the-three-layer-architecture-that-makes-software-production-ready-2pdh</link>
      <guid>https://dev.to/hackmamba/the-three-layer-architecture-that-makes-software-production-ready-2pdh</guid>
      <description>&lt;p&gt;AI development tools such as Cursor and Lovable make it possible to build working applications quickly, but that speed comes with a serious side effect.&lt;/p&gt;

&lt;p&gt;Responsibilities that should remain separate often end up combined in the same components, with request handling, service calls, decision logic and data operations written together.&lt;/p&gt;

&lt;p&gt;Teams that successfully deploy these AI-generated applications into production address those challenges through architectural separation, dividing the system into layers, each performing a specific role before passing the request along.&lt;/p&gt;

&lt;p&gt;This article explains the three-layer architecture behind production-ready applications built with AI tools. It describes what each layer does, how requests move through them and which failures appear when those boundaries are missing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The three-layer production architecture
&lt;/h2&gt;

&lt;p&gt;AI-generated applications often run into problems when multiple responsibilities are combined. For example, issues can arise if a component manages authentication and also calls an AI service, if a request handler starts automated workflows or if a service writes to the database while interpreting AI output. These operational concerns should be kept separate.&lt;/p&gt;

&lt;p&gt;Production-grade AI-generated applications are typically structured around three layers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Presentation layer&lt;/strong&gt; – governs how requests enter the system&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Application layer&lt;/strong&gt; – governs how application decisions are made&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Data layer&lt;/strong&gt; – governs how data is stored and retrieved&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The presentation layer governs system entry&lt;/strong&gt;. Every request passes through authentication, input validation and rate limiting before reaching any application logic. Adversarial inputs and malformed payloads are also handled here before they affect internal services.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The application layer governs decisions&lt;/strong&gt;. Application workflows run in this layer, and external services are integrated into those workflows. Responses from those services, including AI services, move through orchestration, validation checks and rule enforcement before any automated action occurs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The data layer governs data persistence&lt;/strong&gt;. It manages how application data is written, updated and retrieved across the system. Databases, storage systems and data access patterns operate in this layer, providing a consistent foundation for storing application state. Records of application activity, service responses and decision outcomes are also stored here so system behavior can be inspected and audited when needed.&lt;/p&gt;

&lt;p&gt;Requests move through these layers sequentially, with each layer performing its checks and passing control to the next. The sections below describe each layer in detail, starting with the data layer, which should be designed before the application is built.&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%2Fog6u3i84x2emlmajtqto.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%2Fog6u3i84x2emlmajtqto.png" alt="three-layer-architecture" width="800" height="577"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 3 - The data layer
&lt;/h2&gt;

&lt;p&gt;The data layer governs how application data is stored and how system activity is recorded. Building it early provides the persistence and traceability needed to recover from failures and understand how they occurred.&lt;/p&gt;

&lt;p&gt;This layer is typically responsible for the following functions:&lt;/p&gt;

&lt;p&gt;1.&lt;strong&gt;Data storage&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The data layer manages how application data is written, updated and retrieved. Databases, storage systems and data access patterns operate here to keep application state consistent and available across the system.&lt;/p&gt;

&lt;p&gt;2.&lt;strong&gt;Data pipelines&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Data pipelines control how information enters and moves through the system. Inputs pass through ingestion paths that enforce schema validation, sanitize payloads, apply access permissions and record transformations as data flows between services. These controls protect data integrity while preserving a record of what entered the system and when.&lt;/p&gt;

&lt;p&gt;3.&lt;strong&gt;Activity records&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Applications that integrate external services generate additional system records alongside standard application data. Inputs sent to services, responses returned and the resulting system decisions are stored for auditing and debugging.&lt;/p&gt;

&lt;p&gt;These records allow teams to reconstruct how a particular result was produced when investigating incidents or reviewing system behavior. They also provide the historical data that observability systems analyze to detect behavioral changes over time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 2 - The application layer
&lt;/h2&gt;

&lt;p&gt;The application layer governs how decisions are made. Requests reaching this layer have already passed authentication and validation and are now processed by the application logic.&lt;/p&gt;

&lt;p&gt;This layer typically handles the following concerns.&lt;/p&gt;

&lt;p&gt;1.&lt;strong&gt;Orchestration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Orchestration manages how the application interacts with internal components and external services. It constructs requests, processes responses and handles operational concerns such as retries, timeouts and error handling.&lt;/p&gt;

&lt;p&gt;By centralizing these interactions, orchestration prevents service failures or malformed responses from reaching users and keeps requests on a consistent execution path.&lt;/p&gt;

&lt;p&gt;2.&lt;strong&gt;Rule enforcement&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Application rules determine how system decisions are made. These rules enforce constraints such as approval thresholds, escalation policies, account tiers and workflow conditions. Placing these constraints inside the application layer prevents external service responses from directly controlling application behavior.&lt;/p&gt;

&lt;p&gt;3.&lt;strong&gt;Feature flags&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;New behavior should be introduced gradually rather than deployed to all users at once.&lt;/p&gt;

&lt;p&gt;Feature flags allow teams to control how functionality is rolled out by enabling changes for internal traffic first, expanding to limited user segments and eventually releasing to the full user base once system behavior remains stable.&lt;/p&gt;

&lt;p&gt;This layer acts as the control center of the application. External services provide signals, while the application layer determines how those signals influence system behavior.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 1 - The presentation layer
&lt;/h2&gt;

&lt;p&gt;The presentation layer governs what enters the system. Every external request passes through it before reaching application logic, making it responsible for authentication, validation and request control.&lt;/p&gt;

&lt;p&gt;This layer handles the following.&lt;/p&gt;

&lt;p&gt;1.&lt;strong&gt;Authentication and access control&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Requests must carry a verified identity, e.g., a Bearer token, before the system processes them. Role-based access control must also determine which operations each identity is permitted to perform. Without these controls, external requests can trigger system actions that cannot be traced to a specific user or workflow.&lt;/p&gt;

&lt;p&gt;2.&lt;strong&gt;Input validation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;User input must be validated before entering the system. Structured request schemas enforce predictable formats and prevent malformed payloads from reaching application logic. For applications that integrate AI capabilities, input validation also helps reduce the risk of prompt injection.&lt;/p&gt;

&lt;p&gt;3.&lt;strong&gt;Rate limiting&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Rate limiting protects the system from excessive traffic and resource exhaustion. A single unprotected endpoint under sustained load can quickly consume available capacity. Rate limits typically operate across several dimensions, including per-user quotas, endpoint throttling and adaptive controls that respond to system load.&lt;/p&gt;

&lt;p&gt;4.&lt;strong&gt;Request and response formatting&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Consistent request and response structures simplify processing across the system. When incoming requests follow predictable schemas, the application layer can evaluate them without handling arbitrary input shapes.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the layers connect
&lt;/h2&gt;

&lt;p&gt;The three layers provide operational safety only when requests pass through them in sequence. Systems that implement each layer but allow components to bypass boundaries recreate the same failure conditions that the architecture is meant to prevent. &lt;/p&gt;

&lt;p&gt;A request walkthrough illustrates how the layers interact under normal conditions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Presentation layer&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A user submits a support ticket through the application interface.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The request carries an authentication token that is validated by the identity service.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Role-based permissions are checked for the requested operation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The request schema is validated against the expected format.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The input is checked for malformed or unsafe content.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The rate limiter verifies that the user has not exceeded their quota.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The request is normalized into the expected structure before entering the application layer.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Application layer&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The orchestration component receives the request and coordinates the processing workflow.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The application calls an external service to analyze the support ticket.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The service returns a structured response describing the ticket category, priority level and suggested action.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Application rules evaluate whether the suggested action is allowed based on policies such as approval thresholds, escalation rules and account tier.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Feature flags determine whether the new automation behavior is enabled for this request.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The application determines the final action and prepares the response.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Data layer&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The system stores the request payload and the resulting application state.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Activity records capture the service response and the decision taken by the application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Data pipelines record how the request moved through the system for auditing and debugging.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;These records allow engineers to reconstruct how the system processed the request.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If an action triggers an incident days later, engineers can trace the full decision path through the logged request record.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common architectural mistakes
&lt;/h2&gt;

&lt;p&gt;Production failures often trace back to architectural shortcuts taken early in development. These problems usually appear when the responsibilities of the three layers are ignored or collapsed together.&lt;/p&gt;

&lt;p&gt;1.&lt;strong&gt;Skipping presentation-layer controls&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Some systems allow requests to reach application logic without proper validation. Authentication, request validation and rate limiting are either incomplete or missing entirely.&lt;/p&gt;

&lt;p&gt;Without these controls, malformed inputs reach internal services, traffic spikes exhaust system capacity and requests cannot be tied to a specific identity. Problems that should have been stopped at the system boundary propagate throughout the application.&lt;/p&gt;

&lt;p&gt;2.&lt;strong&gt;Placing application logic inside request handlers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Another common mistake is embedding orchestration, service calls and rule evaluation directly inside request handlers.&lt;/p&gt;

&lt;p&gt;When this happens, the presentation layer and application layer collapse into a single component. Authentication, request parsing, service interaction and decision logic all run in the same execution path.&lt;/p&gt;

&lt;p&gt;This structure makes the system difficult to maintain. Changes to one part of the workflow affect the entire request path, and failures become harder to isolate.&lt;/p&gt;

&lt;p&gt;3.&lt;strong&gt;Allowing external services to determine system behavior&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When applications return service responses directly to users or trigger workflows without applying application rules, those services effectively control system behavior. Incorrect outputs or unexpected responses propagate through the system without evaluation.&lt;/p&gt;

&lt;p&gt;The application layer must remain the authority that determines which actions are allowed.&lt;/p&gt;

&lt;p&gt;4.&lt;strong&gt;Failing to record system activity&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Systems that do not store activity records become difficult to operate in production. Without records of inputs, service responses and decision outcomes, teams cannot reconstruct how the system processed a request. Incident investigations rely on guesswork and behavioral changes become difficult to detect. Operational visibility depends on the records maintained in the data layer.&lt;/p&gt;

&lt;p&gt;5.&lt;strong&gt;Building rollback mechanisms after deployment&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Rollback capabilities must be in place before the system reaches production. When configuration changes, service integrations or data transformations are not tracked, teams cannot isolate which change caused a failure. This increases incident duration and operational risk.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing out
&lt;/h2&gt;

&lt;p&gt;AI development tools accelerate how quickly applications can be built, but that speed often introduces architectural shortcuts. As seen in this article, responsibilities such as request handling, service interactions, decision logic and data operations frequently end up combined in the same components.&lt;/p&gt;

&lt;p&gt;Separating these responsibilities through a layered architecture restores that control. The presentation layer governs how requests enter the system, the application layer evaluates service responses and applies system rules and the data layer records the activity needed to monitor and recover from failures.&lt;/p&gt;

&lt;p&gt;At &lt;a href="https://bit.cloud/" rel="noopener noreferrer"&gt;&lt;strong&gt;Bit Cloud&lt;/strong&gt;&lt;/a&gt;, this architectural separation forms the foundation for building and operating production AI systems. Teams that structure their systems this way gain the control and visibility required to run applications safely under real production conditions.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>architecture</category>
      <category>software</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>The top 15 developer productivity tools in 2026</title>
      <dc:creator>Damilola Oshungboye</dc:creator>
      <pubDate>Tue, 19 May 2026 19:31:08 +0000</pubDate>
      <link>https://dev.to/coderabbitai/the-top-15-developer-productivity-tools-in-2026-1nb6</link>
      <guid>https://dev.to/coderabbitai/the-top-15-developer-productivity-tools-in-2026-1nb6</guid>
      <description>&lt;p&gt;&lt;em&gt;Meta: Discover the 15 best developer productivity tools in 2026. Compare AI coding agents, automation, code review, and engineering intelligence platforms.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The rise of developer productivity tools is closely linked to the widespread adoption of AI in engineering. A 2026 Cortex survey, which gathered data from 50 engineering leaders across North America, Europe, and Asia-Pacific in companies with over 500 employees, found that nearly &lt;a href="https://www.cortex.io/report/engineering-in-the-age-of-ai-2026-benchmark-report" rel="noopener noreferrer"&gt;90% of them&lt;/a&gt; reported their teams are actively using AI, with implementation ranging from individual use to mandatory adoption across all teams.&lt;/p&gt;

&lt;p&gt;The market reflects this growth, as projections anticipate the global &lt;a href="https://www.businessresearchinsights.com/market-reports/software-development-tools-market-106006" rel="noopener noreferrer"&gt;software development tools market&lt;/a&gt; will reach $22.6 billion by 2033.&lt;/p&gt;

&lt;p&gt;With hundreds of options available today, the challenge lies not in finding a tool, but in selecting the right one for an individual or a team. To simplify tool selection, we will categorize the options and then highlight the best choice within each category, a method used throughout this article.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why developer productivity tools matter
&lt;/h2&gt;

&lt;p&gt;Developers would ideally dedicate all their work hours to coding. However, the reality is that their time is split among various essential, non-coding tasks. These often include diagnosing and fixing bugs, conducting code reviews, managing software dependencies, and creating or consulting documentation.&lt;/p&gt;

&lt;p&gt;Furthermore, their schedule is also filled with strategy discussions, meetings with non-technical stakeholders, client communications, and administrative duties.&lt;/p&gt;

&lt;p&gt;A few quick stats to drive these points home:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Developers spend around &lt;a href="https://aws.amazon.com/about-aws/whats-new/2024/12/amazon-q-developer-generate-documentation-source-code/" rel="noopener noreferrer"&gt;one hour per day&lt;/a&gt; coding.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The average developer spends nearly &lt;a href="https://www.computerworld.com/article/1612747/for-developers-too-many-meetings-too-little-focus-time.html" rel="noopener noreferrer"&gt;11 hours per week&lt;/a&gt; in meetings.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Approximately 57% of developer time is spent on &lt;a href="https://newsroom.cisco.com/c/r/newsroom/en/us/a/y2024/m05/developers-spending-more-time-firefighting-issues-than-delivering-innovation.html" rel="noopener noreferrer"&gt;reactive work&lt;/a&gt;, like debugging.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Code maintenance consumes up to &lt;a href="https://www.sonarsource.com/blog/developers-spend-30-of-their-time-on-code-maintenance-our-latest-survey-results-part-3/" rel="noopener noreferrer"&gt;12 hours of developer time&lt;/a&gt; per week.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Clearly, something is very wrong. When developers spend the vast majority of their time engaging with tasks other than coding, their focus spills, team morale erodes, and productivity suffers across the board.&lt;/p&gt;

&lt;p&gt;This shows why productivity tools for developers can make a huge difference to workflows. They automate repetitive tasks, reduce cognitive load, strengthen collaboration, provide insights, and improve the overall developer experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  The four types of developer productivity tools
&lt;/h2&gt;

&lt;p&gt;We have categorized the developer productivity tools below into four main groups. These categories reflect how the tools assist software development teams in achieving faster, higher-quality code, optimizing their workflows, and ensuring consistent quality standards throughout the entire development lifecycle.&lt;/p&gt;

&lt;h3&gt;
  
  
  Productivity and engineering intelligence platforms
&lt;/h3&gt;

&lt;p&gt;Productivity and engineering intelligence platforms aggregate data from Git repositories, CI/CD pipelines, and project tracking tools in order to provide insights into a developer team's use of resources and overall effectiveness.&lt;/p&gt;

&lt;p&gt;Port, DX, Jellyfish, Linearb, Harness, Axify, and Atlassian Compass stand out among productivity and engineering intelligence platforms available on the market today. They collect and analyze data, turning raw commits, tickets, and build logs into actionable metrics like, for example, code churn and cycle time. Consequently, they help benchmark a team's performance and improve workflows.&lt;/p&gt;

&lt;p&gt;With dashboards and alerts, these tools for developer productivity help keep projects on track, surfacing issues like stalled pull requests or delayed testing, helping organizations to optimize internal processes better.&lt;/p&gt;

&lt;h3&gt;
  
  
  AI coding agents
&lt;/h3&gt;

&lt;p&gt;AI coding agents, such as Claude Code, Cursor and Copilot, use large language models (LLMs) and deep learning to write and refactor code. They can work autonomously across projects and understand context spanning multiple files and repositories, generating, testing, reviewing and debugging code.&lt;/p&gt;

&lt;p&gt;AI coding agents are used to automate a wide range of repetitive and routine tasks, letting developers to focus on more complex work. For example, a developer might use an AI coding agent to automate code reviews or identify bugs and find ways to fix them.&lt;/p&gt;

&lt;p&gt;These AI tools for developer productivity integrate directly into workflows and can even serve as personal coding assistants, engaging in conversation with developers, explaining code to new hires, and guiding them through unfamiliar parts of a project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Automation tools
&lt;/h3&gt;

&lt;p&gt;Automation tools serve an important purpose in the software development lifecycle, reducing the manual steps a developer team needs to make. This helps developers test, build, and deploy software faster. Tools such as Gradle, Postman, and GitHub Actions, among others, fall into this category.&lt;/p&gt;

&lt;p&gt;By eliminating repetitive tasks such as running tests on each code commit or automatically deploying successful builds to staging environments, automation tools reduce human error and improve efficiency.&lt;/p&gt;

&lt;p&gt;They can, for example, merge pull requests without human intervention, which helps reduce bottlenecks.&lt;/p&gt;

&lt;p&gt;Automation tools deliver real productivity gains by allowing engineers to iterate rapidly and safely, while handling tedious tasks on their own.&lt;/p&gt;

&lt;h3&gt;
  
  
  Code review and code quality tools
&lt;/h3&gt;

&lt;p&gt;Code review and code quality tools, like CodeRabbit and Crucible, enforce coding standards early in the software development process, catching defects such as bugs, security vulnerabilities, or style violations.&lt;/p&gt;

&lt;p&gt;By providing continuous and automated feedback on code health, these productivity tools for developers help teams reduce the risk of failure, blocking releases when issues are detected so that the software is stable and secure.&lt;/p&gt;

&lt;p&gt;More often than not, code review and code quality tools come with collaboration features like inline comments and threaded discussions to improve communication and collaboration among developers. They also use AI assistants to identify bugs, suggest improvements, and automate fixes.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 15 best productivity tools for developers
&lt;/h2&gt;

&lt;p&gt;Now that we've covered the ground concerning the importance and different types of productivity tools, here are the 15 best productivity tools for developers in 2026.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Port: Unified internal developer portal
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvc9nskhi8g1qviwy25dq.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%2Fvc9nskhi8g1qviwy25dq.png" alt="Port developer tool with custom pricing for enterprises, homepage screeenshot." width="800" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.port.io/" rel="noopener noreferrer"&gt;Port&lt;/a&gt; provides an internal developer portal that centralizes resources, unifying all tools, services, and documentation your team uses. It offers a single control plane to browse microservices, APIs and infrastructure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key features and benefits&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Searchable registry of all components&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;One-click actions integrated via CI/CD and Terraform&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Automated scorecards for security and compliance&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Connects to hundreds of tools out of the box&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. DX: Data-driven platform for developer insights
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0x3svdsx180xwlo2sbdg.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%2F0x3svdsx180xwlo2sbdg.png" alt="DX developer intelligence platform for actionable insights, homepage screenshot." width="800" height="444"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://getdx.com/" rel="noopener noreferrer"&gt;DX&lt;/a&gt; is a developer intelligence platform that uses data and developer surveys to help engineering teams improve productivity. DX aggregates activity from code, CI/CD, and project management to identify bottlenecks. Customers report improvements of up to 6 times faster lead times and 2 times higher deployment rates.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key features and benefits&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Centralized engineering data&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Automated surveys and feedback loops for a full view of developer experience&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tools to standardize developer workflows&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;AI and automation features&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Jellyfish: Intelligence for AI-integrated teams
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmgxeyhfo2hu5luzuim57.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%2Fmgxeyhfo2hu5luzuim57.png" alt="Jellyfish developer tool for complex projects, homepage screenshot." width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://jellyfish.co/" rel="noopener noreferrer"&gt;Jellyfish&lt;/a&gt; is a software engineering intelligence platform that collects data from repositories and issue trackers to give leaders clear visibility into productivity. Its dashboards display metrics like cycle time, code churn, and AI tool usage to spot bottlenecks early.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key features and benefits&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Unified dashboards for Git, Jira, CI/CD, and other sources&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Capacity planning to balance team workloads&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Measurement tools for AI impact and team morale&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Jira integration to turn comments into issues&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. Linearb: Workflow optimization
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fur7ki7syuk9jkypr7zus.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%2Fur7ki7syuk9jkypr7zus.png" alt="LinearB, one of the best tools to improve developer productivity, homepage screenshot." width="800" height="487"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://linearb.io/" rel="noopener noreferrer"&gt;LinearB&lt;/a&gt; is an engineering productivity platform that provides visibility into developer workflows, automation, and process metrics. It collects data across the entire development lifecycle to diagnose blockers and optimize delivery. One user reports saving 321 developer-hours per month.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key features and benefits&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Real-time DORA and SPACE metrics visualized in dashboards.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rule-based bots to auto-assign PRs, manage labels, block large PRs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Built-in team health checks and surveys.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;AI tool integrations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Project forecasting module to predict delivery dates based on historical velocity.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  5. Harness: AI-driven CI/CD platform
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdvo30gq3e58hz42ncukh.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%2Fdvo30gq3e58hz42ncukh.png" alt="Harness tool for AI powered development, homepage screenshot." width="800" height="479"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.harness.io/" rel="noopener noreferrer"&gt;Harness&lt;/a&gt; is an AI-driven continuous integration and delivery platform. It offers advanced deployment automation and verification and helps automate deployments with GitOps or push-based workflows, using AI to analyze test results.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key features and benefits&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Runs only impacted tests, reducing pipeline time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Advanced deployment strategies with automated rollback on failure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Real-time metrics on deployment frequency, failure rates, and cost.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  6. CodeRabbit: Industry leading AI code review platform
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8dn0wcwjr7tindxv8bb3.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%2F8dn0wcwjr7tindxv8bb3.png" alt="CodeRabbit: Industry leading AI code review platform" width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.coderabbit.ai/" rel="noopener noreferrer"&gt;CodeRabbit&lt;/a&gt; is the category-defining platform for AI-powered code reviews, built for modern engineering teams navigating the rise of AI-generated development. It combines generative AI models with linters and static code analyzers to deliver codebase-aware reviews that catch and fix errors before they reach production. By pulling in dozens of contextual signals, CodeRabbit provides comprehensive, context-aware reviews, along with powerful customization features that tailor feedback to your codebase and reduce noise. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key features and benefits&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Codebase-aware AI reviews: Reviews PRs in the context of your entire codebase to catch regressions and side effects diff-only reviews miss.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Actionable, high-signal feedback: Flags bugs, logic errors, security issues, test gaps, and docstring drift without drowning you in noise.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Faster reviews and merges: PR summaries, walkthroughs, and one-click fixes reduce back-and-forth and help teams merge significantly faster.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fits into your workflow: Works directly inside your Git platform and supports IDEs, acting as a first-pass reviewer so humans can focus on intent and architecture.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  7. Axify: Software delivery intelligence
&lt;/h2&gt;

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

&lt;p&gt;Axify is a metrics and forecasting tool designed to help development teams deliver faster. It tracks DORA metrics, flow metrics, and team well-being to optimize development processes. Axify can forecast delivery dates based on historical data and current sprint progress, alerting teams to risks early on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key features and benefits&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Predicts release dates and highlights overdue work based on past performance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Monitors lead time, deployment frequency, cycle efficiency, and other key metrics.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Visualizes the software delivery process to pinpoint delays and waste.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Surveys to assess developer sentiment.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Progress tracking through integrated metrics.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  8. Atlassian Compass: Modern developer portal for small teams
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwpau6rqxv5x8e7bzxzg6.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%2Fwpau6rqxv5x8e7bzxzg6.png" alt="Atlassian Compass, one of the best dev tools, homepage screenshot." width="800" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.atlassian.com/software/compass" rel="noopener noreferrer"&gt;Atlassian Compass&lt;/a&gt; is a free internal developer portal for cataloging services, components and templates. It provides a component catalog and health scorecards so teams can easily discover and monitor all their software services. Compass also lets organizations codify best practices via golden path templates so new components start with secure, observable defaults.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key features and benefits&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Inventory of all code components with metadata, dependencies, docs, and owner info.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Health scorecards.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Upstream and downstream service mapping for impact analysis.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reusable templates for project creation that enforce policies automatically.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  9. Claude Code: AI coding assistant for developer productivity
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fky2lafglyh11v0de30aa.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%2Fky2lafglyh11v0de30aa.png" alt="Homepage screenshot of Claude Code software developer productivity tool for maximum coding efficiency." width="800" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.anthropic.com/claude-code" rel="noopener noreferrer"&gt;Claude Code&lt;/a&gt; is a coding assistant that runs in the developer’s terminal. You describe what you want in plain English, and Claude Code will generate code, fix bugs, or automate tasks. It can operate with deep context or integrate with external tools.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key features and benefits&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Easy code generation with Claude making an execution plan and coding it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Automated debugging and fix implementation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Codebase Q&amp;amp;A.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Operates via CLI.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  10. Cursor: Advanced AI code editor
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1sijjyoq94op5tkyboiu.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%2F1sijjyoq94op5tkyboiu.png" alt="Cursor productivity tool for intelligent assistance homepage screenshot. " width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cursor.com/" rel="noopener noreferrer"&gt;Cursor&lt;/a&gt; is an AI-powered code editor that uses Claude, GPT, and Gemini models to suggest whole-line or multi-line completions as you type, often just by hitting Tab. Cursor also lets you use natural language commands to modify code, applying them across files.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key features and benefits&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Context-aware autocomplete that predicts code edits and fills them in bulk.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Codebase awareness.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The option to disable cloud logging so your code is not stored remotely.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Supports many AI models with custom agent layers for speed.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  11. Copilot: AI coding assistant
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3k8qebszo766t7zkkc7r.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%2F3k8qebszo766t7zkkc7r.png" alt="Copilot development tool with code extensions for all major editors, homepage screenshot." width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/features/copilot" rel="noopener noreferrer"&gt;GitHub Copilot&lt;/a&gt; is an AI coding assistant integrated into IDEs that suggests code completions, functions, and generates code from comments as you type. Copilot uses OpenAI and GitHub models to offer context-aware recommendations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key features and benefits:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Predicts and inserts code snippets and functions based on surrounding code and comments.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Chat interface for code Q&amp;amp;A and generation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extensions for all major editors.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Warns about code vulnerabilities and insecure patterns in.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  12. Gradle: Build automation and dependency management
&lt;/h2&gt;

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

&lt;p&gt;&lt;a href="https://gradle.org/" rel="noopener noreferrer"&gt;Gradle&lt;/a&gt; is a modern build system and dependency manager used in Java, Kotlin and Android development. It uses a task-based approach and supports incremental builds and caching for speed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key features and benefits&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Incremental builds&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Shares build results across developers and CI to avoid redundant work&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Builds native code, Android apps, and Node.js projects&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Thousands of plugins&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Highly extensible and type-safe&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  13. Postman: The best API development platform
&lt;/h2&gt;

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

&lt;p&gt;&lt;a href="https://www.postman.com/" rel="noopener noreferrer"&gt;Postman&lt;/a&gt; is an API development platform that helps teams design, test, and document APIs collaboratively. Teams use Postman collections and workspaces to share endpoints and scripts for consistency across projects. This helps teams onboard faster and reduce errors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key features and benefits&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Collaboration workspaces with shared collections, mock servers, and docs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Auto-generated, interactive docs for all endpoints&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Automation with AI assistant to write test scripts or debug APIs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Links with version control, CI/CD, and cloud tools to embed APIs into the lifecycle&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  14. GitHub Actions: Native CI/CD and automation
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxlabmij4lxdii035b9c2.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%2Fxlabmij4lxdii035b9c2.png" alt="Native CI/CD automation platform Github Actions homepage screenshot." width="800" height="482"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/features/actions" rel="noopener noreferrer"&gt;GitHub Actions&lt;/a&gt; lets developers automate workflows directly within GitHub. You write YAML workflow files that trigger on repository events to build, test, and deploy code. Actions provides hosted runners and supports matrix builds, so you can test across multiple OS versions in parallel.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key features and benefits&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Runs builds and deployments in your GitHub repo context&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Simultaneous code testing on multiple operating systems and language versions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Real-time workflow logs and an encrypted secrets store for credentials.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Workflow automation&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  15. Crucible: Collaborative code review tools
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxislanshm18ic2snq7vd.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%2Fxislanshm18ic2snq7vd.png" alt="Screenshot of Crubicle collaborative code review tool for multiple team members. " width="799" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.atlassian.com/software/crucible" rel="noopener noreferrer"&gt;Crucible&lt;/a&gt; is a code review tool that teams perform peer reviews on commits from Git, SVN, and Mercurial with discussion threads on specific lines or files. It supports both formal workflows and informal reviews alike, and provides dashboards to track review status and code coverage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key features and benefits&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Inline comments, threaded discussions, and review statuses to collaborate on code quality&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tracking and reporting&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Connects to Jira and Bitbucket Server&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Complete history of reviews and comments for compliance and accountability.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Choosing the right developer productivity tool
&lt;/h2&gt;

&lt;p&gt;Developer productivity is about creating the right environment for developers to write code, instead of wasting their time and cognitive energy on dealing with inefficiencies and bottlenecks.&lt;/p&gt;

&lt;p&gt;The 15 tools we’ve explored here stand out as some of the most powerful resources today, covering everything from data-driven insights and automated deployments to intelligent code suggestions and quality checks.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to use AI to identify and fix security vulnerabilities in your codebase</title>
      <dc:creator>Damilola Oshungboye</dc:creator>
      <pubDate>Wed, 22 Apr 2026 09:40:52 +0000</pubDate>
      <link>https://dev.to/coderabbitai/how-to-use-ai-to-identify-and-fix-security-vulnerabilities-in-your-codebase-4na2</link>
      <guid>https://dev.to/coderabbitai/how-to-use-ai-to-identify-and-fix-security-vulnerabilities-in-your-codebase-4na2</guid>
      <description>&lt;p&gt;&lt;em&gt;Meta: Understand the common code-based security vulnerabilities, from SQL injection to XSS, and how AI simplifies the detection and resolution of these security vulnerabilities for improved code security.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;With the average &lt;a href="https://insurica.com/blog/average-data-breach-cost-hits-all-time-high-of-4-4m/" rel="noopener noreferrer"&gt;data breach now costing companies $4.45 million,&lt;/a&gt; securing your code has never been more urgent. &lt;/p&gt;

&lt;p&gt;As development cycles accelerate, security vulnerabilities like SQL injections or cross-site scripting (XSS) are still common or discovered too late. AI is changing that. By scanning large codebases, learning from actual attack patterns, and offering targeted fixes, AI tools help you address code security flaws faster than ever.&lt;/p&gt;

&lt;p&gt;This article explores where traditional approaches fall short, how AI can fill those gaps, and the practical steps to embedding AI code security into your development workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common security vulnerabilities in your codebase
&lt;/h2&gt;

&lt;p&gt;When you look at the &lt;a href="https://owasp.org/www-project-top-ten/" rel="noopener noreferrer"&gt;OWASP Top 10&lt;/a&gt;, you’ll notice how many serious threats come from your routine everyday coding patterns. Let’s examine a few of the most prevalent vulnerabilities:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. SQL injection
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://owasp.org/www-community/attacks/SQL_Injection" rel="noopener noreferrer"&gt;SQL injection&lt;/a&gt; can be especially dangerous because it exploits the mechanism you rely on to store and retrieve data. An attacker essentially “&lt;strong&gt;injects&lt;/strong&gt;” malicious SQL commands into an application’s inputs, potentially gaining unauthorized access to or altering the underlying data.&lt;/p&gt;

&lt;p&gt;Here’s an example from a simple authentication routine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# auth_service.py
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;authenticate_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
        SELECT id, role FROM users 
        WHERE username = &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; 
        AND password = &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetchone&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code appears functional but is highly vulnerable to SQL injection attacks. The &lt;code&gt;authenticate_user&lt;/code&gt; function constructs an SQL query using string concatenation, which allows an attacker to inject malicious SQL code. If an attacker inputs ' OR '1'='1 as the username, the query becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;role&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="s1"&gt;'1'&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'1'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'anything'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This query will always return true, allowing the attacker to potentially bypass authentication and access protected data. The consequences of SQL injection attacks can be severe, including loss of confidentiality, tampering with existing data, identity spoofing, and even gaining administrative access to the database server.&lt;/p&gt;

&lt;p&gt;A more secure approach uses parameterized queries:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# auth_service.py (secure version)
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;authenticate_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
        SELECT id, role FROM users 
        WHERE username = %s AND password = %s
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetchone&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this secure version, the SQL query uses placeholders (%s) for the user input, and the actual values are passed as parameters to the execute method. This approach ensures that the input data is properly escaped and cannot be used to manipulate the SQL query structure&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Cross-site scripting (XSS)
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://owasp.org/www-community/attacks/xss/" rel="noopener noreferrer"&gt;XSS&lt;/a&gt; happens when attackers inject malicious scripts (often JavaScript) into web pages that other users view. Any spot in your application where user input is rendered onto the page can be a gateway for XSS.&lt;/p&gt;

&lt;p&gt;The following example of a blog post display function is a common pattern in content management systems and is vulnerable to XSS attacks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/blog/&amp;lt;post_id&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;display_post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;post_id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;post_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
        &amp;lt;article&amp;gt;
            &amp;lt;h1&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;/h1&amp;gt;
            &amp;lt;div&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;/div&amp;gt;
        &amp;lt;/article&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An attacker could inject malicious JavaScript through the post content, affecting every visitor.&lt;/p&gt;

&lt;p&gt;In this example, an attacker could script malicious JavaScript through the post.content field. For instance, if an attacker submits a blog post with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;XSS&lt;/span&gt;&lt;span class="dl"&gt;'&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This script will be executed by every visitor who views the blog post, allowing the attacker to steal session cookies, manipulate the user's browser, or perform other malicious actions.&lt;/p&gt;

&lt;p&gt;To counter XSS, always sanitize and escape user-generated content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;markupsafe&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;escape&lt;/span&gt;

&lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/blog/&amp;lt;post_id&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;display_post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;post_id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;post_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;render_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;post.html&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;escape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;escape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&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;The escape function from the markupsafe library is used to ensure that any user-provided content is properly sanitized, preventing malicious scripts from being executed in the user's browser.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Hardcoded secrets
&lt;/h3&gt;

&lt;p&gt;Hardcoding sensitive information, like API keys or database credentials, into your code is a common mistake, often done for convenience. However, attackers can use these secrets to gain unauthorized access if this code ends up in a public repository or is leaked elsewhere.&lt;/p&gt;

&lt;p&gt;Here is a simple but risky approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StorageService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;aws_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AKIA1234567890ABCDEF&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;aws_secret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;jK8*2nP9$mB4#kL5&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s3&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;aws_access_key_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;aws_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;aws_secret_access_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;aws_secret&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If these credentials appear in a publicly accessible repository, malicious actors can exploit them immediately. Instead, you can store secrets in environment variables or a secure secrets manager:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;decouple&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StorageService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s3&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;aws_access_key_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;AWS_ACCESS_KEY&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;aws_secret_access_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;AWS_SECRET_KEY&lt;/span&gt;&lt;span class="sh"&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;The decouple library from config is used to load the AWS credentials from environment variables, ensuring that sensitive information is not hardcoded in the application code. This approach significantly reduces the risk of credential exposure and subsequent security breaches.&lt;/p&gt;

&lt;p&gt;Although these vulnerabilities may appear obvious individually, they become difficult to detect within large codebases, especially when many developers make multiple commits daily across various repositories. Manual reviews alone struggle to consistently catch security issues at scale.&lt;/p&gt;

&lt;p&gt;Keeping these vulnerabilities in mind, let's examine how various types of security testing can help identify and prevent them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choosing static or dynamic code analysis?
&lt;/h2&gt;

&lt;p&gt;It’s critical to identify vulnerabilities early. Two practical approaches to scrutinizing your code are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://circleci.com/blog/static-application-security-testing-sast/" rel="noopener noreferrer"&gt;&lt;strong&gt;Static Application Security Testing&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;(SAST)&lt;/strong&gt; – Analyzes your codebase without executing it, pinpointing issues like insecure coding patterns, hardcoded secrets, or known vulnerability signatures.
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://circleci.com/blog/dynamic-application-security-testing-dast/" rel="noopener noreferrer"&gt;&lt;strong&gt;Dynamic Application Security Testing&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;(DAST)&lt;/strong&gt; – Interacts with your running application to spot real-time issues, such as misconfigurations or runtime injection paths.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Many security teams rely on both since SAST focuses on code structure, whereas DAST uncovers flaws that are only visible during runtime. Whichever approach you take, the idea is to catch issues well before affecting production users.&lt;/p&gt;

&lt;h2&gt;
  
  
  An AI-assisted approach to code security
&lt;/h2&gt;

&lt;p&gt;Even if you’re vigilant about security, modern codebases constantly evolve, and it’s easy for vulnerabilities to slip through. AI code review tools help by quickly scanning large repositories, drawing on known attack patterns, and machine learning to spot issues you might otherwise miss.&lt;/p&gt;

&lt;p&gt;They also offer practical suggestions for fixing those issues, reinforcing your overall security posture.&lt;/p&gt;

&lt;p&gt;To see this in action, consider a Python Flask project that handles user profiles and file uploads (two areas where security oversights often hide). AI can highlight these hidden risks and guide you in resolving them before they become real problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up an AI tool for automated code reviews for security vulnerabilities
&lt;/h2&gt;

&lt;p&gt;If you’d like to explore AI-based reviews, you can try any tool that suits your needs; some include &lt;a href="https://github.com/features/copilot" rel="noopener noreferrer"&gt;GitHub Copilot&lt;/a&gt;, &lt;a href="https://claude.ai/" rel="noopener noreferrer"&gt;Claude&lt;/a&gt;, and &lt;a href="https://www.perplexity.ai/" rel="noopener noreferrer"&gt;Perplexity.&lt;/a&gt; For this tutorial, we’ll use a popular AI tool like &lt;a href="https://chatgpt.com/" rel="noopener noreferrer"&gt;ChatGPT&lt;/a&gt; to review and examine common vulnerabilities with a Python Flask application that manages user profiles and handles photo uploads.&lt;/p&gt;

&lt;p&gt;First, clone the Python project that handles user profile management.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/Tabintel/py-photo-lib.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Navigate to the project directory and install dependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;py-photo-lib
python &lt;span class="nt"&gt;-m&lt;/span&gt; venv venv
venv&lt;span class="se"&gt;\S&lt;/span&gt;cripts&lt;span class="se"&gt;\a&lt;/span&gt;ctivate
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, create a branch for the new photo upload functionality:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; feature/profile-uploads
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After cloning the repository and creating the branch, copy the code from this &lt;a href="https://gist.github.com/Tabintel/0afac74f60b27e8b1212baa378e788ab" rel="noopener noreferrer"&gt;GitHub gist&lt;/a&gt; into your app.py file. &lt;/p&gt;

&lt;p&gt;This feature adds photo upload capabilities to the application, allowing users to upload profile images.&lt;/p&gt;

&lt;p&gt;The changes include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;New route /upload for uploading images.
&lt;/li&gt;
&lt;li&gt;File upload handling using Flask's request.files.
&lt;/li&gt;
&lt;li&gt;Database query in /profile/&amp;lt;username&amp;gt; to fetch user details.
&lt;/li&gt;
&lt;li&gt;Configured API to handle profile image paths.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Before pushing the code to the main repository, you’ll first use an AI tool to review it for any vulnerabilities.&lt;/p&gt;

&lt;p&gt;Give this prompt to your AI tool (we’re using ChatGPT in this case):&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"Review the following code, which adds a new profile image upload feature to a Python Flask application. Identify any security vulnerabilities or potential risks in the implementation, briefly explain why, and suggest improvements where necessary."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In the review process, you would likely receive precise, line-by-line recommendations, such as these examples:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Exception handling enhancement
&lt;/h3&gt;

&lt;p&gt;The review flagged broad exception handling, suggesting you implement more specific error tracking to prevent the exposure of sensitive information. &lt;/p&gt;

&lt;p&gt;This is a critical security concern, as broad exception handling can make identifying and addressing potential issues difficult. To address this, you can implement a robust exception-handling mechanism that includes specific error messages and logging.&lt;/p&gt;

&lt;p&gt;For example, instead of using a broad exception handler like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can implement a more specific exception handler that includes error messages and logging:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;ValueError&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Log the exception and return an error message
&lt;/span&gt;    &lt;span class="n"&gt;logging&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="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Invalid value: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;error&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Invalid value&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Log the exception and continue
&lt;/span&gt;    &lt;span class="n"&gt;logging&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="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;An error occurred: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach ensures that each exception type is handled specifically, providing more detailed error logs and making diagnosing and fixing issues easier.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Undefined username
&lt;/h3&gt;

&lt;p&gt;Another vulnerability identified is related to undefined model imports. Having undefined model imports in any codebase can make it difficult to ensure data integrity and prevent unauthorized access. &lt;/p&gt;

&lt;p&gt;To address this, you can enhance the username validation to prevent undefined model imports.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;
&lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query&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="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the User models are imported correctly, you prevent potential errors that could arise from undefined models, which can lead to data inconsistencies and prevent attacks like SQL injections.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Additional code vulnerabilities
&lt;/h3&gt;

&lt;p&gt;From this particular review, you can see that the AI tool recognizes areas in the app.py code pull request and points out the exact lines of code that the changes need to be reviewed for security purposes. Let’s look at each of them:&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Image format validation
&lt;/h3&gt;

&lt;p&gt;The automated review flags the need to review image format validation. Currently, the application only allows png, jpg, jpeg, and gif formats for uploaded photos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;ALLOWED_EXTENSIONS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;png&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;jpg&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;jpeg&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;gif&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;MAX_FILE_SIZE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;  &lt;span class="c1"&gt;# 5MB
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While this approach is sufficient for basic use cases, it leaves the application vulnerable to limitations or potential misuse. &lt;/p&gt;

&lt;p&gt;For example, if the project requires support for other formats (e.g., webp, tiff), the lack of validation for these could result in errors or even security risks when unexpected file types are uploaded. &lt;/p&gt;

&lt;p&gt;Proper validation ensures that the system explicitly handles supported formats, mitigating risks from unverified file uploads.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Function usage documentation
&lt;/h3&gt;

&lt;p&gt;Next, there’s a suggestion to clarify function usage in docstring. A short docstring for allowed_file could be helpful in describing its purpose and the expected parameter or return types.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;allowed_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;.&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; \
           &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rsplit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;.&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;ALLOWED_EXTENSIONS&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without documentation, you may misunderstand the purpose or behavior of this function. Adding a short docstring that specifies the function's role (validating file extensions) and details the expected parameters and return values would prevent miscommunication and misuse.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Image processing logging
&lt;/h3&gt;

&lt;p&gt;There's a suggestion to validate and log image processing steps. The image processing logic is good but may benefit from explicit logging when conversions or resizing occur, especially to diagnose user-upload issues.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image_path&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Convert to RGB if necessary
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mode&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;RGB&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;img&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;convert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;RGB&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;# Resize if too large
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;thumbnail&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="c1"&gt;# Save optimized version
&lt;/span&gt;        &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;JPEG&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;quality&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;85&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;optimize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without logs, it becomes difficult to diagnose issues when image uploads fail. Logging each step would provide a clear trail for troubleshooting and prevent vulnerabilities caused by incomplete or incorrect processing. Logs also enhance accountability and allow developers to detect unexpected behavior during uploads.&lt;/p&gt;

&lt;p&gt;Through this automated code review process, you've seen how AI tools comprehensively analyze the code, highlighting vulnerabilities in the photo upload feature. The review shows critical security gaps, from unhandled exceptions that could expose system information to unsecured file type validation that might allow malicious uploads and missing model imports that could compromise data integrity. &lt;/p&gt;

&lt;p&gt;Once you've added the code from the review, commit and push the changes to your GitHub repository using the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add app.py
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"feat: add profile photo upload functionality"&lt;/span&gt;
git push origin feature/profile-uploads
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Implementing code security best practices
&lt;/h2&gt;

&lt;p&gt;Security requires ongoing diligence. Here are some routines you can integrate into daily development:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Regular code reviews
&lt;/h3&gt;

&lt;p&gt;Peer reviews remain indispensable for catching logical errors and sharing knowledge. To maximize coverage, combine them with automated scanning.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Secure coding standards
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Avoid storing secrets in code.

&lt;ul&gt;
&lt;li&gt;Enforce the least privilege for database connections.
&lt;/li&gt;
&lt;li&gt;Use parameterized queries by default.
&lt;/li&gt;
&lt;li&gt;These guidelines reduce the risk of common issues slipping through.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Frequent vulnerability assessments
&lt;/h3&gt;

&lt;p&gt;Schedule periodic scans (e.g., monthly or quarterly) using SAST and DAST tools. Consider penetration tests for critical areas of your application.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Automate where possible
&lt;/h3&gt;

&lt;p&gt;CI/CD pipelines can automatically run security tests before deployment, ensuring no commit merges without scrutiny. AI can assist in triaging results, making the process more efficient.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Embrace DevOps culture
&lt;/h3&gt;

&lt;p&gt;Encourage open collaboration between development and operations, ensuring that security is baked in from the start rather than bolted on at the end.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Shift-Left security
&lt;/h3&gt;

&lt;p&gt;Moving security checks to earlier stages of development (DevSecOps) reduces last-minute surprises. Addressing security vulnerabilities earlier in the development process significantly reduces the time and resources required for remediation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up: Securing your codebase
&lt;/h2&gt;

&lt;p&gt;Applying thoughtful, ongoing code security practices and AI code review checks can significantly reduce your application’s vulnerability. Whether it’s preventing SQL injection, mitigating XSS, or ensuring secrets don’t leak, each layer of protection adds up.&lt;/p&gt;

&lt;p&gt;As you refine these habits and explore AI code security solutions, you’ll discover more efficient ways to keep your applications secure, protect sensitive data, and maintain a reliable development pipeline.   &lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>vulnerabilities</category>
      <category>code</category>
    </item>
    <item>
      <title>Looking to optimize memory in your Go application? Check out this guide</title>
      <dc:creator>Damilola Oshungboye</dc:creator>
      <pubDate>Sat, 01 Feb 2025 13:04:11 +0000</pubDate>
      <link>https://dev.to/thatcoolguy/looking-to-optimize-memory-in-your-go-application-check-out-this-guide-gh5</link>
      <guid>https://dev.to/thatcoolguy/looking-to-optimize-memory-in-your-go-application-check-out-this-guide-gh5</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/thatcoolguy/memory-management-in-go-4-effective-approaches-39d2" class="crayons-story__hidden-navigation-link"&gt;How to Manage Memory in Go Applications&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/thatcoolguy" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F173379%2Fdf729b12-338b-41e6-9b7d-e9e17bdb741b.JPEG" alt="thatcoolguy profile" class="crayons-avatar__image" width="800" height="766"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/thatcoolguy" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Damilola Oshungboye
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Damilola Oshungboye
                
              
              &lt;div id="story-author-preview-content-2253943" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/thatcoolguy" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F173379%2Fdf729b12-338b-41e6-9b7d-e9e17bdb741b.JPEG" class="crayons-avatar__image" alt="" width="800" height="766"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Damilola Oshungboye&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/thatcoolguy/memory-management-in-go-4-effective-approaches-39d2" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Feb 1 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/thatcoolguy/memory-management-in-go-4-effective-approaches-39d2" id="article-link-2253943"&gt;
          How to Manage Memory in Go Applications
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/go"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;go&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/beginners"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;beginners&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/tutorial"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;tutorial&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/thatcoolguy/memory-management-in-go-4-effective-approaches-39d2" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;2&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/thatcoolguy/memory-management-in-go-4-effective-approaches-39d2#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            10 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>go</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to Manage Memory in Go Applications</title>
      <dc:creator>Damilola Oshungboye</dc:creator>
      <pubDate>Sat, 01 Feb 2025 13:03:16 +0000</pubDate>
      <link>https://dev.to/thatcoolguy/memory-management-in-go-4-effective-approaches-39d2</link>
      <guid>https://dev.to/thatcoolguy/memory-management-in-go-4-effective-approaches-39d2</guid>
      <description>&lt;p&gt;Go, also known as Golang, is known for its &lt;a href="https://medium.com/safetycultureengineering/an-overview-of-memory-management-in-go-9a72ec7c76a8" rel="noopener noreferrer"&gt;effective memory management system&lt;/a&gt;. While the language's garbage collector automates most tasks involving memory, understanding and implementing effective memory management techniques helps improve your Go applications' performance and resource usage.&lt;/p&gt;

&lt;p&gt;So, in this tutorial, you’ll learn four effective techniques you can apply to manage memory even better in your Go application. Whether you are an experienced developer or just starting out, you will gain insightful knowledge that you can apply to make your Go code more memory-efficient.&lt;/p&gt;

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

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

&lt;p&gt;Before going any further, ensure you have the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Go installed on your system. You can download it from the &lt;a href="https://golang.org/dl/" rel="noopener noreferrer"&gt;official website&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A text editor or IDE of your choice to write and edit your Go code&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A project directory for the tutorial's code&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Go’s garbage collector
&lt;/h2&gt;

&lt;p&gt;Go's memory management is primarily handled by its garbage collector (GC). The GC automatically allocates and deallocates memory, relieving developers from manual memory management tasks common in languages like C or C++. &lt;/p&gt;

&lt;p&gt;Here’s an example to demonstrate how the GC works by tracking memory usage before and after garbage collection.&lt;/p&gt;

&lt;p&gt;In your project directory, create a new file named &lt;strong&gt;main.go&lt;/strong&gt; and paste the code below into it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;

    &lt;span class="s"&gt;"fmt"&lt;/span&gt;

    &lt;span class="s"&gt;"runtime"&lt;/span&gt;

&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;mem&lt;/span&gt; &lt;span class="n"&gt;runtime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MemStats&lt;/span&gt;

    &lt;span class="n"&gt;runtime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadMemStats&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Initial memory usage: %v KBn"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mem&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Alloc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;references&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;1000000&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="n"&gt;references&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;new&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="m"&gt;1000000&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;runtime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadMemStats&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Memory usage after allocation: %v KBn"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mem&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Alloc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;references&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;

    &lt;span class="n"&gt;runtime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GC&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;runtime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadMemStats&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Memory usage after garbage collection: %v KBn"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mem&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Alloc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above, the initial memory usage is printed, followed by the allocation of 100 large arrays, which significantly increases memory usage. The &lt;code&gt;references&lt;/code&gt; &lt;a href="https://www.w3schools.com/go/go_slices.php" rel="noopener noreferrer"&gt;slice&lt;/a&gt; is then set to &lt;code&gt;nil&lt;/code&gt; to remove all references to these arrays, and a manual garbage collection is triggered. Finally, the memory usage is printed again to show the current memory usage.&lt;/p&gt;

&lt;p&gt;Run the below command in your terminal to execute the code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go run main.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see a result similar to the image below, indicating that the GC cleared the unused memory.&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%2Flawcuiy7waoezb3i73vu.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%2Flawcuiy7waoezb3i73vu.png" alt=" " width="798" height="210"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Memory management approaches in Go
&lt;/h2&gt;

&lt;p&gt;In this section, you’ll learn about the approaches and techniques you can use to manage memory better in your Go application.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Design memory-efficient structs
&lt;/h3&gt;

&lt;p&gt;In Go, &lt;a href="https://www.w3schools.com/go/go_struct.php" rel="noopener noreferrer"&gt;structs&lt;/a&gt; are typed collections of fields. Each field in the struct can be of a different &lt;a href="https://www.w3schools.com/go/go_data_types.php" rel="noopener noreferrer"&gt;data type&lt;/a&gt;, making structs a flexible way of combining related data. Structs are commonly used to represent records or complex data structures.&lt;/p&gt;

&lt;p&gt;While structs can be considered, in some respects, as being similar to classes in object-oriented languages such as Java and C++, Go does not support explicit inheritance as other languages do.&lt;/p&gt;

&lt;p&gt;Here’s how you would define a struct in Go.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;StructName&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="n"&gt;field1&lt;/span&gt; &lt;span class="n"&gt;Type1&lt;/span&gt;

    &lt;span class="n"&gt;field2&lt;/span&gt; &lt;span class="n"&gt;Type2&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When using structs in Go, it's important to consider how the fields are aligned in memory. You should order struct fields from largest to smallest to &lt;a href="https://dev.to/aymanepraxe/golang-field-ordering-matters-2i6m"&gt;minimize&lt;/a&gt; the amount of padding between fields.&lt;/p&gt;

&lt;p&gt;Padding refers to the extra space added between struct fields to align them properly in memory. This alignment is necessary for the CPU to access the fields efficiently, but it can lead to wasted memory if fields are not ordered carefully. By organizing fields from largest to smallest, you can reduce the amount of padding, making the memory layout more compact.&lt;/p&gt;

&lt;p&gt;Replace the content of the &lt;em&gt;main.go&lt;/em&gt; file with the below code block to demonstrate this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;

    &lt;span class="s"&gt;"fmt"&lt;/span&gt;

    &lt;span class="s"&gt;"unsafe"&lt;/span&gt;

&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Inefficient&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;

        &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="kt"&gt;int64&lt;/span&gt;

        &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;

        &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="kt"&gt;int32&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Efficient&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="kt"&gt;int64&lt;/span&gt;

        &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="kt"&gt;int32&lt;/span&gt;

        &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;

        &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Size of Inefficient: %d bytesn"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Inefficient&lt;/span&gt;&lt;span class="p"&gt;{}))&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Size of Efficient: %d bytesn"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Efficient&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;The code above defines two structs: &lt;code&gt;Inefficient&lt;/code&gt; and &lt;code&gt;Efficient&lt;/code&gt;. The &lt;code&gt;Inefficient&lt;/code&gt; struct arranges its fields in a way that increases memory usage due to extra padding between fields. &lt;/p&gt;

&lt;p&gt;On the other hand, the &lt;code&gt;Efficient&lt;/code&gt; struct organizes fields from largest to smallest, reducing padding and making the struct more memory-efficient. The difference in size is shown using the &lt;code&gt;unsafe.Sizeof()&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;Run the command below in your terminal to execute the code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go run main.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will see the result displayed below.&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%2Fv8njdwbwgj92979f85r6.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%2Fv8njdwbwgj92979f85r6.png" alt=" " width="800" height="123"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As shown in the image above, arranging your structs from largest to smallest fields causes it to use memory more effectively.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Use pointers for large data structures
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://go.dev/tour/moretypes/1" rel="noopener noreferrer"&gt;Pointers&lt;/a&gt; in Go are variables that store the memory address of another variable. They allow you to reference and manipulate the value of a variable directly in memory rather than working with a &lt;em&gt;copy&lt;/em&gt; of the value.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key facts about pointers:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Declaration&lt;/strong&gt;: A pointer is declared by placing an asterisk (&lt;code&gt;*&lt;/code&gt;) before the type. For example, &lt;code&gt;var p *int&lt;/code&gt; declares a pointer to an integer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Address Operator&lt;/strong&gt; (&lt;code&gt;&amp;amp;&lt;/code&gt;): To get the address of a variable, you use the address operator. For example, &lt;code&gt;p = &amp;amp;x&lt;/code&gt; assigns the address of &lt;code&gt;x&lt;/code&gt; to the pointer &lt;code&gt;p&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dereferencing&lt;/strong&gt;: To access or modify the value at the address stored in a pointer, you use the dereference operator (&lt;code&gt;*&lt;/code&gt;). For instance, &lt;code&gt;*p = 10&lt;/code&gt; sets the value of &lt;code&gt;x&lt;/code&gt; to &lt;code&gt;10&lt;/code&gt; if &lt;code&gt;p&lt;/code&gt; points to &lt;code&gt;x&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here’s a simple example to demonstrate pointers. Replace the contents of your &lt;em&gt;main.go&lt;/em&gt; file with the below code block.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;

    &lt;span class="s"&gt;"fmt"&lt;/span&gt;

&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;42&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Initial value of number:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;



    &lt;span class="n"&gt;pointerToNumber&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;

    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pointerToNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;99&lt;/span&gt;



    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Value of number after pointer modification:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Memory address of number: %pn"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pointerToNumber&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above, the variable &lt;code&gt;number&lt;/code&gt; is initialized to 42. A pointer named &lt;code&gt;pointerToNumber&lt;/code&gt; is created and assigned the memory address of &lt;code&gt;number&lt;/code&gt;. The value of &lt;code&gt;number&lt;/code&gt; is then updated to 99 by modifying the value stored directly by the &lt;code&gt;pointerToNumber&lt;/code&gt; pointer.&lt;/p&gt;

&lt;p&gt;Run the below command in your terminal to execute the code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go run main.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see the result shown in the image below.&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%2Fv5xgmqdyp9r79843etur.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%2Fv5xgmqdyp9r79843etur.png" alt=" " width="800" height="147"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using pointers is an effective way to save memory when working with large data structures. Instead of passing these data structures directly to a function, you can pass a pointer that holds their memory address. This allows the function to modify the original data without the overhead of creating a copy, which normally occurs when the value of an object is passed into a function.&lt;/p&gt;

&lt;p&gt;However, you must be careful not to create references that can lead to memory leaks by setting the references to &lt;code&gt;nil&lt;/code&gt; after the code is done. Replace the content of your &lt;em&gt;main.go&lt;/em&gt; file with the code block below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;

    &lt;span class="s"&gt;"fmt"&lt;/span&gt;

    &lt;span class="s"&gt;"runtime"&lt;/span&gt;

&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;LargeDataSet&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="n"&gt;values&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;8000000&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;GenerateData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;LargeDataSet&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;LargeDataSet&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="m"&gt;1000&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Memory usage before data generation:"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;DisplayMemoryStats&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;dataset&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;GenerateData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"nMemory usage after data generation:"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;DisplayMemoryStats&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"nFirst value in dataset: %dn"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

    &lt;span class="n"&gt;dataset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;

    &lt;span class="n"&gt;runtime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GC&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"nMemory usage after removing dataset reference: "&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;DisplayMemoryStats&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;DisplayMemoryStats&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;memStats&lt;/span&gt; &lt;span class="n"&gt;runtime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MemStats&lt;/span&gt;

    &lt;span class="n"&gt;runtime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadMemStats&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;memStats&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;allocatedMiB&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;memStats&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Alloc&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="m"&gt;1024&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="m"&gt;1024&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Allocated = %v MiB"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;allocatedMiB&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the example above, the &lt;code&gt;GenerateData()&lt;/code&gt; function creates a large data structure and returns a pointer to it, avoiding the overhead of copying the large data. After executing the function, the pointer is set to &lt;code&gt;nil&lt;/code&gt;, allowing the garbage collector to &lt;a href="https://bwoff.medium.com/understanding-gos-garbage-collection-415a19cc485c" rel="noopener noreferrer"&gt;reclaim the memory&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Run the below command in your terminal to execute the code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go run main.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see the result shown in the image below.&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%2Fbc3up2e0l1upvaupkoc4.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%2Fbc3up2e0l1upvaupkoc4.png" alt=" " width="800" height="235"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Manage variables scopes
&lt;/h3&gt;

&lt;p&gt;The proper understanding and usage of variable scopes plays a vital role in memory management in Go. A variable's scope determines its visibility and lifetime within the program, impacting directly when the garbage collector can free up the memory associated with it.&lt;/p&gt;

&lt;h4&gt;
  
  
  Limit variables scopes
&lt;/h4&gt;

&lt;p&gt;While writing your Go code, you should keep variable scopes as limited as possible so the garbage collector can free them as soon as possible.&lt;/p&gt;

&lt;p&gt;To demonstrate this, replace the content of your &lt;strong&gt;main.go&lt;/strong&gt; file with the code block below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;

    &lt;span class="s"&gt;"fmt"&lt;/span&gt;

&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"This is available throughout main"&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="n"&gt;blockMessage&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"This is only available in this block"&lt;/span&gt;

        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blockMessage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;blockMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blockMessage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the example above, the &lt;code&gt;message&lt;/code&gt; variable is declared at the top of the &lt;code&gt;main()&lt;/code&gt; function and is accessible throughout the entire function, including all nested blocks. Conversely, the &lt;code&gt;blockMessage&lt;/code&gt; variable is defined within a nested block inside the &lt;code&gt;main()&lt;/code&gt; function. Consequently, its scope is limited to that block, making it inaccessible outside of it.&lt;/p&gt;

&lt;p&gt;Therefore, accessing the &lt;code&gt;blockMessage&lt;/code&gt; variable outside its scope will result in a compilation error, as shown in the image below. This is because the Go compiler detects that the variable is not defined in that context.&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%2F4rq3sko1l4or9taq286n.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%2F4rq3sko1l4or9taq286n.png" alt=" " width="668" height="136"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Use global variables cautiously
&lt;/h4&gt;

&lt;p&gt;You can also manage memory more effectively by using global variables cautiously since they persist throughout the program's entire lifecycle and can result in memory leaks.&lt;/p&gt;

&lt;p&gt;Replace the content of your &lt;em&gt;main.go&lt;/em&gt; file with the below code block.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;

    &lt;span class="s"&gt;"fmt"&lt;/span&gt;

    &lt;span class="s"&gt;"runtime"&lt;/span&gt;

&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;globalStorage&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Storage&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Storage&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="n"&gt;Elements&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;800000&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;int32&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;initializeStorage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;tempStorage&lt;/span&gt; &lt;span class="n"&gt;Storage&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tempStorage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Elements&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="n"&gt;tempStorage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Elements&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;int32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="m"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;globalStorage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;tempStorage&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Memory usage before initializeStorage:"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;displayMemoryStats&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;initializeStorage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"nMemory usage after initializeStorage:"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;displayMemoryStats&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"nMemory usage after local variable out of scope (globalStorage still set):"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;displayMemoryStats&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;displayMemoryStats&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;memStats&lt;/span&gt; &lt;span class="n"&gt;runtime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MemStats&lt;/span&gt;

    &lt;span class="n"&gt;runtime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadMemStats&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;memStats&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;allocatedMiB&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;memStats&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Alloc&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="m"&gt;1024&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="m"&gt;1024&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Allocated = %v MiB"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;allocatedMiB&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code block above, the &lt;code&gt;initializeStorage()&lt;/code&gt; function creates a &lt;code&gt;tempStorage&lt;/code&gt; variable and fills its &lt;code&gt;Elements&lt;/code&gt; array with data. Then, the address of &lt;code&gt;tempStorage&lt;/code&gt; is assigned to the global variable &lt;code&gt;globalStorage&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Run the command below in your terminal to execute the code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go run main.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will see the below results displayed in your terminal.&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%2F4r6fd7zaufly50ljrzl6.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%2F4r6fd7zaufly50ljrzl6.png" alt=" " width="800" height="175"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As seen in the image above, although &lt;code&gt;tempStorage&lt;/code&gt; goes out of scope when &lt;code&gt;initializeStorage&lt;/code&gt; finishes, the global variable &lt;code&gt;globalStorage&lt;/code&gt; continues to hold a reference to it because it was defined globally. This prevents the garbage collector from reclaiming the memory.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Pool resources
&lt;/h3&gt;

&lt;p&gt;Go has a technique for managing memory resource-intensive scenarios. It allows you to reuse resources, such as objects and memory, instead of allocating and deallocating them repeatedly.&lt;/p&gt;

&lt;p&gt;You should use &lt;code&gt;sync.Pool&lt;/code&gt; when dealing with scenarios that require frequent reuse of short-lived objects to reduce allocation costs and garbage collection overhead, especially during concurrency operations.&lt;/p&gt;

&lt;p&gt;To demonstrate this, replace the content of your &lt;em&gt;main.go&lt;/em&gt; file with the code block below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;

    &lt;span class="s"&gt;"fmt"&lt;/span&gt;

    &lt;span class="s"&gt;"sync"&lt;/span&gt;

&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;syncPool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sync&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pool&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;interface&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="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;syncStruct&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;type&lt;/span&gt; &lt;span class="n"&gt;syncStruct&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="n"&gt;Object&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;syncPool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;syncStruct&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Object&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Pooling resources!"&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;syncPool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;data2&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;syncPool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;syncStruct&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the example above, &lt;code&gt;sync.Pool&lt;/code&gt; is used to manage and reuse instances of the &lt;code&gt;syncStruct&lt;/code&gt; type. When an object is requested from the pool using &lt;code&gt;syncPool.Get()&lt;/code&gt;, if none are available, a new one is created. The object is then used, and after processing it is returned to the pool using &lt;code&gt;syncPool.Put()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Run the command below in your terminal to run the code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go run main.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will see the results displayed below.&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%2Ftf2rdulbzt7b2whbjaby.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%2Ftf2rdulbzt7b2whbjaby.png" alt=" " width="736" height="136"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Profile and monitor memory usage
&lt;/h2&gt;

&lt;p&gt;Go provides in-built methods for identifying bottlenecks and memory leaks in your Go application using its profiler: pprof.&lt;/p&gt;

&lt;p&gt;To profile memory usage, you will need to import &lt;a href="https://pkg.go.dev/runtime/pprof" rel="noopener noreferrer"&gt;the runtime/pprof package&lt;/a&gt; and write memory profiles to files for later analysis. Running these profiles through pprof helps identify inefficient memory usage in your application.&lt;/p&gt;

&lt;p&gt;Below is an example of its usage. Replace the contents of your &lt;em&gt;main.go&lt;/em&gt; file with the code block below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;

    &lt;span class="s"&gt;"log"&lt;/span&gt;

    &lt;span class="s"&gt;"os"&lt;/span&gt;

    &lt;span class="s"&gt;"runtime"&lt;/span&gt;

    &lt;span class="s"&gt;"runtime/pprof"&lt;/span&gt;

&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="n"&gt;runtime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MemProfileRate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;2048&lt;/span&gt;

    &lt;span class="n"&gt;profileFile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"mem.prof"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to create memory profile file: "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;profileFile&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;generateDataStructures&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;pprof&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteHeapProfile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;profileFile&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Unable to write memory profile: "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Memory profile saved to mem.prof"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;generateDataStructures&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="n"&gt;structures&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;800000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;structures&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="n"&gt;structures&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;

            &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"A"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"B"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"C"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"D"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"E"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

        &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;structures&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above, Go’s runtime function &lt;code&gt;runtime.MemProfileRate()&lt;/code&gt; is set to capture memory allocations in 2KB intervals. The program creates a profile file named &lt;em&gt;mem.prof&lt;/em&gt; to store the profiling data. Finally, the profiling data is written to the &lt;em&gt;mem.prof&lt;/em&gt; file for later analysis.&lt;/p&gt;

&lt;p&gt;Run the code using the command below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go run main.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see a prompt that indicates the profile data has been saved, as shown in the image below.&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%2Fhr5fgcpaxvrhhk88xi2t.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%2Fhr5fgcpaxvrhhk88xi2t.png" alt=" " width="800" height="91"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, run the code below in your terminal to begin the analysis of the profile data using &lt;code&gt;pprof&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go tool pprof mem.prof
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will return the prompt, as seen in the image below.&lt;/p&gt;

&lt;p&gt;![][image9]Explore the profile data with the &lt;strong&gt;top&lt;/strong&gt; command, which displays the top memory-consuming functions.&lt;/p&gt;

&lt;p&gt;Paste the below command in your terminal to see this command in action.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;top
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Ftw8yjautkkiw4299xrup.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%2Ftw8yjautkkiw4299xrup.png" alt=" " width="800" height="227"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The top memory-consuming functions are displayed in the image above.&lt;/p&gt;

&lt;p&gt;It’s also possible to check the particular lines in each function that consumes the memory using the&lt;code&gt;list &amp;lt;function_name&amp;gt;&lt;/code&gt; command. Use the command below to see this in action.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;list generateDataStructures
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Flz22p04ewxegr7djt87x.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%2Flz22p04ewxegr7djt87x.png" alt=" " width="800" height="330"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The image above displays the memory allocation per line. It shows that line 32 consumes the most memory—64.15 MB.&lt;/p&gt;

&lt;h2&gt;
  
  
  That’s how to improve memory management in Go
&lt;/h2&gt;

&lt;p&gt;In this article, you learned about Go's garbage collector and the best approaches for improved memory efficiency. You also learned how to use Go's built-in memory profiler to detect memory leaks in your code.&lt;/p&gt;

&lt;p&gt;Effective memory management enhances application performance and reduces the risk of memory-related errors. By applying the techniques in this tutorial, you can confidently build memory-safe Go applications.&lt;/p&gt;

&lt;p&gt;Cheers to more learning!&lt;/p&gt;

</description>
      <category>go</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to Build a Real-Time Chat App With Laravel, Vue.js, and Pusher</title>
      <dc:creator>Damilola Oshungboye</dc:creator>
      <pubDate>Sun, 08 Sep 2024 21:10:54 +0000</pubDate>
      <link>https://dev.to/thatcoolguy/how-to-build-a-real-time-chat-app-with-laravel-vuejs-and-pusher-19ik</link>
      <guid>https://dev.to/thatcoolguy/how-to-build-a-real-time-chat-app-with-laravel-vuejs-and-pusher-19ik</guid>
      <description>&lt;p&gt;Real-time chat applications like WhatsApp and Discord have witnessed a remarkable surge in popularity in recent years, revolutionising communication with instantaneous messaging. However, while building your own chat app with this functionality might seem daunting, it’s entirely achievable.&lt;/p&gt;

&lt;p&gt;In this tutorial, you will learn how to build a real-time chat application using Laravel, Vue.js, and Pusher. You'll use the Laravel framework to build the back end of the chat application, a combination of Blade templates and Vue.js to develop the user interface and layout of the application, and the Pusher platform for the real-time chat functionality.&lt;/p&gt;

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

&lt;p&gt;To complete this tutorial, you will need the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;PHP 8.3 (or higher) installed&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.npmjs.com/downloading-and-installing-node-js-and-npm" rel="noopener noreferrer"&gt;Node and NPM&lt;/a&gt; installed&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://getcomposer.org" rel="noopener noreferrer"&gt;Composer&lt;/a&gt; installed globally&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A Pusher account. Create a new account &lt;a href="https://dashboard.pusher.com/accounts/sign_up" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Basic knowledge of &lt;a href="https://www.pubnub.com/guides/websockets/" rel="noopener noreferrer"&gt;WebSockets&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Basic knowledge of the Vue.js framework would be nice, but is not essential&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Backend setup
&lt;/h2&gt;

&lt;p&gt;Begin by setting up all the necessary backend configurations required for the chat application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scaffold a new Laravel project
&lt;/h3&gt;

&lt;p&gt;To get started with building your chat application, you need to create a new Laravel project using Composer and change into the project directory by running the below commands in your terminal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
composer create-project laravel/laravel chat-app

&lt;span class="nb"&gt;cd &lt;/span&gt;chat-app

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, install &lt;a href="https://laravel.com/docs/11.x/starter-kits" rel="noopener noreferrer"&gt;Laravel Breeze&lt;/a&gt; using the command below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
composer require laravel/breeze 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the Laravel Breeze installation is complete, scaffold the authentication for the application. Do that by running the following commands one after the other.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
php artisan breeze:install

npm &lt;span class="nb"&gt;install

&lt;/span&gt;npm run dev

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When prompted, select the options below.&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%2Fh2gflihecr0xxiroo8fe.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%2Fh2gflihecr0xxiroo8fe.png" alt=" " width="800" height="365"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The final step in the scaffolding process is to add the necessary packages and config files for WebSocket and event broadcast. Run the command below in a new terminal instance or tab.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
php artisan &lt;span class="nb"&gt;install&lt;/span&gt;:broadcasting

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When prompted, select these options:&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%2Fn04q3b75muwinzjdxewb.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%2Fn04q3b75muwinzjdxewb.png" alt=" " width="800" height="321"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This command creates &lt;em&gt;channels.php&lt;/em&gt; in the &lt;em&gt;routes&lt;/em&gt; folder and &lt;em&gt;broadcasting.php&lt;/em&gt; in the &lt;em&gt;config&lt;/em&gt; folder. These files will hold the WebSocket configurations and install the necessary client libraries (&lt;a href="https://laravel.com/docs/11.x/broadcasting#client-side-installation" rel="noopener noreferrer"&gt;Laravel Echo&lt;/a&gt; and &lt;a href="https://github.com/pusher/pusher-js" rel="noopener noreferrer"&gt;pusher-js&lt;/a&gt;) needed to work with WebSockets. &lt;/p&gt;

&lt;p&gt;With all of the scaffolding completed, start the application development server by running the commands below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
php artisan serve

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the application server is up, open &lt;a href="http://localhost:8000/" rel="noopener noreferrer"&gt;http://localhost:8000/&lt;/a&gt; in your browser. You should see the default Laravel welcome page with options to log in or register for your chat app, as shown in the image below.&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%2F3t45bqxvsu2bpu5f5na3.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%2F3t45bqxvsu2bpu5f5na3.png" alt=" " width="800" height="518"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The next step is to open the project in your preferred IDE or text editor.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configure Pusher
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://pusher.com" rel="noopener noreferrer"&gt;Pusher&lt;/a&gt; is a cloud-hosted service that makes adding real-time functionality to applications easy. It acts as a real-time communication layer between servers and clients. This allows your backend server to instantly broadcast new data via Pusher to your &lt;a href="http://Vue.Js" rel="noopener noreferrer"&gt;Vue.&lt;/a&gt;&lt;a href="http://Vue.Js" rel="noopener noreferrer"&gt;j&lt;/a&gt;&lt;a href="http://Vue.Js" rel="noopener noreferrer"&gt;s&lt;/a&gt; client.&lt;/p&gt;

&lt;p&gt;Install the Pusher helper library by running the command below in a new terminal instance or tab.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
composer require pusher/pusher-php-server

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, in your Pusher &lt;a href="https://dashboard.pusher.com" rel="noopener noreferrer"&gt;dashboard&lt;/a&gt;, create a new app by clicking &lt;strong&gt;Create App&lt;/strong&gt; under &lt;strong&gt;Channels&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%2Fj0h4qf6tpb8wv7jyfic0.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%2Fj0h4qf6tpb8wv7jyfic0.png" alt=" " width="800" height="318"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, fill out the form, as in the screenshot below, and click &lt;strong&gt;Create app.&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%2Fv3bedoh2wb8oz1bm375y.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%2Fv3bedoh2wb8oz1bm375y.png" alt=" " width="800" height="933"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After creating a new channels app, navigate to the &lt;strong&gt;App Keys&lt;/strong&gt; section in the Pusher dashboard where you will find your Pusher credentials: App ID, Key, Secret, and Cluster. Note these values as you will need them shortly.&lt;/p&gt;

&lt;p&gt;Now, locate the &lt;em&gt;.env&lt;/em&gt; file in the root directory of your project. This file is used to keep sensitive data and other configuration settings out of your code. Add the following lines to the bottom of the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="nv"&gt;PUSHER_APP_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;your_pusher_app_id&amp;gt;
&lt;span class="nv"&gt;PUSHER_APP_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;your_pusher_app_key&amp;gt;
&lt;span class="nv"&gt;PUSHER_APP_SECRET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;your_pusher_app_secret&amp;gt;
&lt;span class="nv"&gt;PUSHER_APP_CLUSTER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;your_pusher_app_cluster&amp;gt;
&lt;span class="nv"&gt;VITE_PUSHER_APP_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PUSHER_APP_KEY&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nv"&gt;VITE_PUSHER_APP_CLUSTER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PUSHER_APP_CLUSTER&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nv"&gt;BROADCAST_CONNECTION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;pusher
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ensure you replace &lt;code&gt;&amp;lt;your_pusher_app_id&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;your_pusher_app_key&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;your_pusher_app_secret&amp;gt;&lt;/code&gt;, and &lt;code&gt;&amp;lt;your_pusher_app_cluster&amp;gt;&lt;/code&gt; with the actual values from your Pusher dashboard. Be careful to only replace the placeholder values with your actual credentials and do not alter the keys. This setup will enable your application to connect to Pusher's cloud servers and set Pusher as your broadcast driver.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setup model and migration
&lt;/h3&gt;

&lt;p&gt;After scaffolding the application, the next step is to create a model and a corresponding database migration. This will allow us to store chat messages and user information in the database. Run the following command in your terminal to create a model with a corresponding migration file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
php artisan make:model &lt;span class="nt"&gt;-m&lt;/span&gt; ChatMessages 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will generate &lt;em&gt;ChatMessages.php&lt;/em&gt; in the &lt;em&gt;app/Models&lt;/em&gt; directory and a migration file in the &lt;em&gt;database/Migrations&lt;/em&gt; directory.&lt;/p&gt;

&lt;p&gt;Open &lt;em&gt;app/Models&lt;/em&gt; and update the content of &lt;em&gt;ChatMessages.php&lt;/em&gt; with this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;
&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Models&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Database\Eloquent\Factories\HasFactory&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Database\Eloquent\Model&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ChatMessages&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Model&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;HasFactory&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$fillable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'sender_id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'receiver_id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'text'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;



    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;sender&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="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;belongsTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'sender_id'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  

    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;receiver&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="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;belongsTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'receiver_id'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above, the &lt;code&gt;$fillable&lt;/code&gt; property allows &lt;code&gt;sender_id&lt;/code&gt;, &lt;code&gt;receiver_id&lt;/code&gt;, and text to be mass-assigned. Additionally, the model defines two many-to-one relationships: the sender relationship links to the user model via the &lt;code&gt;sender_id&lt;/code&gt;, and the receiver relationship links to the user model via &lt;code&gt;receiver_id&lt;/code&gt;, representing the sender and receiver of the message, respectively.&lt;/p&gt;

&lt;p&gt;Next, navigate to &lt;em&gt;database/Migrations&lt;/em&gt; and update the file that ends with &lt;em&gt;create_chat_messages_table.php&lt;/em&gt; with the following code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;
&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Database\Migrations\Migration&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Database\Schema\Blueprint&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Support\Facades\Schema&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Migration&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="o"&gt;/**&lt;/span&gt;

     &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nc"&gt;Run&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;migrations&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;

     &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;up&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;

    &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="nc"&gt;Schema&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'chat_messages'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Blueprint&lt;/span&gt; &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

            &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;foreignId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'sender_id'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;constrained&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'users'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;foreignId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'receiver_id'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;constrained&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'users'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'text'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;timestamps&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="o"&gt;/**&lt;/span&gt;

     &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nc"&gt;Reverse&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;migrations&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;

     &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;down&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;

    &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="nc"&gt;Schema&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;dropIfExists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'chat\_messages'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;};&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the migration above, the database schema of the chat application is defined. This schema includes an &lt;code&gt;id&lt;/code&gt; for each message, foreign keys &lt;code&gt;sender_id&lt;/code&gt; and &lt;code&gt;receiver_id&lt;/code&gt; that reference the &lt;code&gt;users&lt;/code&gt; table, a &lt;code&gt;text&lt;/code&gt; column to store the content of the message, and &lt;code&gt;timestamp&lt;/code&gt; columns to record when each message is created and updated.&lt;/p&gt;

&lt;p&gt;After updating the model and migration, the next step is to run the migration. Do that by running the command below in your terminal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
php artisan migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Setup the event broadcast
&lt;/h3&gt;

&lt;p&gt;Next, set up the event broadcast by navigating to &lt;em&gt;channels.php&lt;/em&gt; file in the &lt;em&gt;routes&lt;/em&gt; folder and update it with the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;
&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Support\Facades\Auth&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Support\Facades\Broadcast&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nc"&gt;Broadcast&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'chat'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$user&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="nc"&gt;Auth&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="p"&gt;});&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above, a new broadcast channel named "chat" is defined, and a closure is passed to ensure that only authenticated users can subscribe to the channel.&lt;/p&gt;

&lt;p&gt;After defining the channel, create a new event which will be broadcast to the client on the "chat" channel. Run the command below in your terminal to generate the event class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
php artisan make:event MessageSent

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command will create a new file called &lt;em&gt;MessageSent.php&lt;/em&gt; in the &lt;em&gt;app/Events&lt;/em&gt; directory. Open the &lt;em&gt;MessageSent.php&lt;/em&gt; file and update it with the below content.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;
&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Events&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Models\ChatMessages&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Broadcasting\Channel&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Broadcasting\InteractsWithSockets&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Broadcasting\PresenceChannel&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Broadcasting\PrivateChannel&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Contracts\Broadcasting\ShouldBroadcast&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Contracts\Broadcasting\ShouldBroadcastNow&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Foundation\Events\Dispatchable&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Queue\SerializesModels&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Models\User&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MessageSent&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;ShouldBroadcast&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Dispatchable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;InteractsWithSockets&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;SerializesModels&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$chatMessage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="cd"&gt;/**

     \* Create a new event instance.

     \*

    public function __construct(User $user, ChatMessages $chatMessage)

    {

        $this-&amp;gt;user = $user;

        $this-&amp;gt;chatMessage = $chatMessage;

    }

    /**

     \* Get the channels the event should broadcast on.

     \*

     \* @return array\&amp;lt;int, \\Illuminate\\Broadcasting\\Channel\&amp;gt;

     \*/&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;broadcastOn&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;array&lt;/span&gt;

    &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;

            &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PrivateChannel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"chat"&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;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;broadcastWith&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'message'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;chatMessage&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above, the user and the message are passed into the constructor. The &lt;code&gt;broadcastOn()&lt;/code&gt; method specifies that the event will be broadcast on a private channel named "chat", while the &lt;code&gt;broadcastWith()&lt;/code&gt; method adds the chat message to the broadcast payload.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create the controller
&lt;/h3&gt;

&lt;p&gt;The next step is to create a controller class that will contain all the application logic. To create the controller, run the command below in your terminal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
php artisan make:controller ChatController

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will create a new file called &lt;em&gt;ChatController.php&lt;/em&gt; in the &lt;em&gt;app/Http/Controllers&lt;/em&gt; folder.&lt;/p&gt;

&lt;p&gt;Open the &lt;em&gt;ChatController.php&lt;/em&gt; file and replace the content with the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;
&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Http\Controllers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Events\MessageSent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Http\Controllers\Controller&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Models\ChatMessages&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Models\User&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Http\Request&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Support\Facades\Auth&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ChatController&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Controller&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;User&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ChatMessages&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'sender'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'receiver'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
            &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;whereIn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'sender_id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;Auth&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
            &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;whereIn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'receiver_id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;Auth&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
            &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$messages&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;User&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ChatMessages&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
            &lt;span class="s1"&gt;'sender_id'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Auth&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="s1"&gt;'receiver_id'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'text'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="nf"&gt;broadcast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MessageSent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$message&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toOthers&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above, the necessary imports required for the chat application are added. In the &lt;code&gt;index()&lt;/code&gt; function, messages exchanged between the currently authenticated user and the specified user are retrieved while &lt;a href="https://laravel.com/docs/11.x/eloquent-relationships#eager-loading" rel="noopener noreferrer"&gt;eager-loading&lt;/a&gt; the sender and receiver information using the relationships. In the &lt;code&gt;store()&lt;/code&gt; function, a new message from the currently authenticated user to the specified user is saved to the database, and the &lt;code&gt;MessageSent&lt;/code&gt; event is broadcasted on the chat channel.&lt;/p&gt;

&lt;h3&gt;
  
  
  Update the routes
&lt;/h3&gt;

&lt;p&gt;Now, it's time to update the routing table. So, in the &lt;em&gt;web.php&lt;/em&gt; file located in the &lt;em&gt;routes&lt;/em&gt; folder, add the following imports at the beginning of the file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Http\Controllers\ChatController&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Models\User&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Support\Facades\Auth&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, replace the dashboard route with the following*&lt;em&gt;.&lt;/em&gt;*&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;
&lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/dashboard'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&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="nf"&gt;view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'dashboard'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="s1"&gt;'users'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'!='&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Auth&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;get&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="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'auth'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'verified'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'dashboard'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/chat/{user}'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;User&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'chat'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s1"&gt;'user'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$user&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="nf"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'auth'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'verified'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'chat'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s1"&gt;'messages/{user}'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="nc"&gt;ChatController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'only'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'index'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'store'&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="nf"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'auth'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These routes set up the necessary endpoints for the chat application. The &lt;code&gt;/dashboard&lt;/code&gt; route displays a list of users, excluding the current user. The &lt;code&gt;/chat/{user}&lt;/code&gt; route loads the chat interface for a selected user. The &lt;code&gt;Route::resource&lt;/code&gt; line sets up routes for retrieving and sending messages using the &lt;code&gt;ChatController&lt;/code&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Frontend setup
&lt;/h2&gt;

&lt;p&gt;Now that the backend part of the chat application is fully set up, it’s time to build the user interface of the chat application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Install Vue.js
&lt;/h3&gt;

&lt;p&gt;First, install Vue.js and the necessary plugin to detect &lt;em&gt;.vue&lt;/em&gt; files by running the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
npm &lt;span class="nb"&gt;install &lt;/span&gt;vue vue-loader  

npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; @vitejs/plugin-vue

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create a new Vue.js component
&lt;/h3&gt;

&lt;p&gt;Next, navigate to &lt;em&gt;resources/js&lt;/em&gt; and create a new folder called &lt;em&gt;components&lt;/em&gt;. In the newly created &lt;em&gt;components&lt;/em&gt; folder, create a new file called &lt;em&gt;ChatBox.vue&lt;/em&gt;. Update its content with the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;
&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"chat-box"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;"messagesBox"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"chat-messages"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"(message, index) in messages"&lt;/span&gt; &lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"index"&lt;/span&gt; &lt;span class="na"&gt;:class=&lt;/span&gt;&lt;span class="s"&gt;"['chat-message', &lt;/span&gt;{ 'own-message': message.sender_id === sender.id }]"&amp;gt;
                &lt;span class="si"&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;text&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"timestamp"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nf"&gt;formatTimestamp&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;created_at&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/span&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;/div&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"chat-input"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"newMessage"&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;keyup.enter=&lt;/span&gt;&lt;span class="s"&gt;"sendMessage"&lt;/span&gt; &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"Type a 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="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click=&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;/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;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;axios&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;axios&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&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;nextTick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onMounted&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;watch&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;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;required&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="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;required&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="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nf"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&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;messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ref&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;newMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&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;messagesBox&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&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;scrollToBottom&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;messagesBox&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="nx"&gt;scrollTop&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;messagesBox&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="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="nf"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nf"&gt;nextTick&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="nf"&gt;scrollToBottom&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                &lt;span class="p"&gt;});&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;deep&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="p"&gt;);&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sendMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newMessage&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="o"&gt;!==&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;axios&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="s2"&gt;`/messages/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&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;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;newMessage&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="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="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;messages&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;push&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="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                        &lt;span class="nx"&gt;newMessage&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="p"&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;formatTimestamp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timestamp&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;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getHours&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getMinutes&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;span class="nf"&gt;onMounted&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;axios&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="s2"&gt;`/messages/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;response&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="p"&gt;});&lt;/span&gt;
            &lt;span class="nx"&gt;Echo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;private&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&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="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;MessageSent&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;response&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;response&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;messageExists&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;messages&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;some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;response&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;id&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;messageExists&lt;/span&gt;&lt;span class="p"&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;response&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;sender_id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;response&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;receiver_id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; 
                                &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&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;sender_id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;response&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;receiver_id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                                &lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&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="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="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nx"&gt;newMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nx"&gt;messagesBox&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nx"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nx"&gt;formatTimestamp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;style&lt;/span&gt; &lt;span class="na"&gt;scoped&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nc"&gt;.chat-box&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="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;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&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;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;500px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.chat-messages&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
    &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex-start&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;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;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;.chat-input&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border-top&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="nc"&gt;.chat-input&lt;/span&gt; &lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&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-right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.chat-input&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;10px&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;#0a0a0a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.chat-message&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;inline-block&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&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="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;15px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;word-wrap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;break-word&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.chat-message.own-message&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;align-self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex-end&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#d1e7ff&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;#0056b3&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="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.chat-message&lt;/span&gt;&lt;span class="nd"&gt;:not&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;.own-message&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;align-self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex-start&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#e1e1e1&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="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.timestamp&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.8rem&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;#aaa&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;margin-left&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="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;style&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code above is a Vue.js &lt;a href="https://vuejs.org/guide/essentials/component-basics.html" rel="noopener noreferrer"&gt;component&lt;/a&gt; responsible for the chat functionality. The &lt;code&gt;&amp;lt;template&amp;gt;&lt;/code&gt; section defines the HTML structure, including a div for displaying messages and an input area for sending new messages, with each message conditionally styled to distinguish between messages sent by the current user and others. &lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; section, the receiver and sender are passed as &lt;code&gt;[props](https://v2.vuejs.org/v2/guide/components-props)&lt;/code&gt; to identify the two users currently chatting. Within the &lt;code&gt;setup&lt;/code&gt; function, &lt;a href="https://vuejs.org/guide/essentials/reactivity-fundamentals.html" rel="noopener noreferrer"&gt;reactive references&lt;/a&gt; &lt;code&gt;messages&lt;/code&gt;, &lt;code&gt;newMessage&lt;/code&gt;, and &lt;code&gt;messagesBox&lt;/code&gt; are defined. The &lt;code&gt;scrollToBottom()&lt;/code&gt; function ensures that the chat view always scrolls to display the latest message, while the &lt;code&gt;sendMessage()&lt;/code&gt; function handles sending new messages to the server and updating the chat view accordingly. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;formatTimestamp()&lt;/code&gt; function formats the message timestamps for display. The &lt;code&gt;onMounted&lt;/code&gt; &lt;a href="https://vuejs.org/api/options-lifecycle.html#options-lifecycle" rel="noopener noreferrer"&gt;lifecycle hook&lt;/a&gt; fetches existing messages and listens for the &lt;code&gt;MessageSent&lt;/code&gt; event on the “chat” channel using Laravel Echo. Finally, the &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt; section adds CSS styles to define the layout, the appearance of the messages, and the input area.&lt;/p&gt;

&lt;h3&gt;
  
  
  Update the Echo.js and App.js file
&lt;/h3&gt;

&lt;p&gt;After creating the chat components, the next step is to update the JavaScript files. In the &lt;em&gt;resources/js&lt;/em&gt; directory, locate the &lt;em&gt;echo.js&lt;/em&gt; file and replace the content of the file with the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Echo&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;laravel-echo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Pusher&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;pusher-js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Pusher&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Pusher&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Echo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Echo&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;broadcaster&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pusher&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="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;meta&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;VITE_PUSHER_APP_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;:&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;meta&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;VITE_PUSHER_APP_CLUSTER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;forceTLS&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the updated &lt;em&gt;echo.js&lt;/em&gt; file, Echo is configured to use Pusher as the broadcaster for real-time events. It uses the key and cluster information specified earlier in our &lt;em&gt;.env&lt;/em&gt; file to connect the application to the Pusher service.&lt;/p&gt;

&lt;p&gt;Then, replace the content of the &lt;em&gt;resources/js/app.js&lt;/em&gt; file with the content below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;
&lt;span class="n"&gt;import&lt;/span&gt; &lt;span class="s1"&gt;'./bootstrap'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;createApp&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;'vue'&lt;/span&gt; 
&lt;span class="n"&gt;import&lt;/span&gt; &lt;span class="nc"&gt;ChatBox&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;'./components/ChatBox.vue'&lt;/span&gt; 

&lt;span class="nf"&gt;createApp&lt;/span&gt;&lt;span class="p"&gt;({})&lt;/span&gt; 
    &lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;component&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'chat-box'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;ChatBox&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'#app'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the updated app.js file, the Vue.js application is set up by importing the necessary dependencies and creating a new instance. The &lt;code&gt;ChatBox&lt;/code&gt; component is registered to the alias &lt;code&gt;chat-box&lt;/code&gt;, and mounted to the HTML element with the id &lt;code&gt;app&lt;/code&gt;, enabling the chat functionality in your application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Update the vite.config.js file
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://vitejs.dev" rel="noopener noreferrer"&gt;Vite&lt;/a&gt; is a build tool that is responsible for building and bundling your frontend assets. You’ll need to update its config file so it can detect and build Vue.js components.&lt;/p&gt;

&lt;p&gt;To do that, in the root directory, open the &lt;em&gt;vite.config.js&lt;/em&gt; and update it with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineConfig&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;vite&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;laravel&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;laravel-vite-plugin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;vue&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;@vitejs/plugin-vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;defineConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="nf"&gt;laravel&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;input&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;resources/css/app.css&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;resources/js/app.js&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;refresh&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="p"&gt;}),&lt;/span&gt;
        &lt;span class="nf"&gt;vue&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; 
            &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;transformAssetUrls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="na"&gt;base&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;includeAbsolute&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="p"&gt;}),&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;alias&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;vue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue/dist/vue.esm-bundler.js&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="p"&gt;});&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the updated &lt;em&gt;vite.config.js&lt;/em&gt;, the &lt;code&gt;laravel-vite-plugin\&lt;/code&gt; is configured to handle the CSS and JS files for your Laravel application. The &lt;code&gt;@vitejs/plugin-vue\&lt;/code&gt; plugin is also included to enable support for Vue.js single-file components. Additionally, the &lt;code&gt;resolve\&lt;/code&gt; section sets up an alias to use the Vue ES module build, which is necessary for single-file component support. This configuration ensures that Vite can properly process and serve your application during the development and build stages.&lt;/p&gt;

&lt;h3&gt;
  
  
  Update the Blade templates
&lt;/h3&gt;

&lt;p&gt;The final step in the frontend setup is updating &lt;a href="https://laravel.com/docs/11.x/blade" rel="noopener noreferrer"&gt;the Blade templates&lt;/a&gt;. Navigate to &lt;em&gt;resources/views&lt;/em&gt; and update &lt;em&gt;dashboard.blade.php&lt;/em&gt; with the below content.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;
&lt;span class="nt"&gt;&amp;lt;x-app-layout&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;x-slot&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"header"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;h2&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"font-semibold text-xl text-gray-800 dark:text-gray-200 leading-tight"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            {{Auth::user()-&amp;gt;name}} 
        &lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/x-slot&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"py-12"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"max-w-7xl mx-auto sm:px-6 lg:px-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"bg-white dark:bg-gray-800 overflow-hidden shadow-sm sm:rounded-lg"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"p-6 text-gray-900 dark:text-gray-100"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                        @foreach ($users as $user)
                            &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"overflow-hidden bg-white shadow-sm sm:rounded-lg"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                                &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"p-6"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                                    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"flex items-center"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                                        &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"{{ route('chat', $user) }}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                                            &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"ml-4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                                                &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-sm font-medium text-gray-900 dark:text-gray-100"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                                                    {{ $user-&amp;gt;name }}
                                                &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
                                                &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-sm text-gray-500 dark:text-gray-400"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                                                    {{ $user-&amp;gt;email }}
                                                &lt;span class="nt"&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;/a&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;/div&amp;gt;&lt;/span&gt;
                            &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
                        @endforeach
                    &lt;span class="nt"&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;/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;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/x-app-layout&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the updated &lt;em&gt;dashboard.blade.php&lt;/em&gt;, the list of users profiled on the system is returned, such that a logged-in user can chat with any of them.&lt;/p&gt;

&lt;p&gt;Also in &lt;em&gt;resources/views&lt;/em&gt;, create a new file &lt;em&gt;chat.blade.php&lt;/em&gt; and update it with the following content.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;
&lt;span class="nt"&gt;&amp;lt;x-app-layout&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;x-slot&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"header"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;h2&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"font-semibold text-xl text-gray-800 dark:text-gray-200 leading-tight"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            {{$user-&amp;gt;name}}
        &lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/x-slot&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"py-12"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"max-w-7xl mx-auto sm:px-6 lg:px-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"bg-white dark:bg-gray-800 overflow-hidden shadow-sm sm:rounded-lg"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"p-6 text-gray-900 dark:text-gray-100"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;'app'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;                       
                    &lt;span class="nt"&gt;&amp;lt;chat-box&lt;/span&gt;
                        &lt;span class="na"&gt;:receiver = &lt;/span&gt;&lt;span class="s"&gt;"{{ $user }}"&lt;/span&gt;
                        &lt;span class="na"&gt;:sender = &lt;/span&gt;&lt;span class="s"&gt;"{{ Auth::user() }}"&lt;/span&gt;
                    &lt;span class="nt"&gt;/&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;/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;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/x-app-layout&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This file holds the Vue.js component responsible for the chat functionality. It sets up the layout and includes the &lt;code&gt;chat-box\&lt;/code&gt; component, passing the authenticated user as the sender and the selected user as the receiver as props to it. &lt;/p&gt;

&lt;h2&gt;
  
  
  Test the chat application
&lt;/h2&gt;

&lt;p&gt;It’s finally time to see your chat app in action. By default &lt;a href="https://laravel.com/docs/11.x/events" rel="noopener noreferrer"&gt;Laravel events&lt;/a&gt; are dispatched on queues, therefore you’ll need to start up a queue worker instance so your event can be processed.  Run the command below in your terminal to start your queue.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
php artisan queue:listen

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, register two new users. Log in with one user in a regular browser tab, and log in with the other user in an incognito tab. Then, select each other on both tabs to start chatting.&lt;/p&gt;

&lt;p&gt;Below is a video demonstration of the chat application.&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%2F7lxdfwc2y4xfaybfxkax.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%2F7lxdfwc2y4xfaybfxkax.gif" alt=" " width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  That’s how to build a real-time chat application using Laravel, Pusher and, Vue.js
&lt;/h2&gt;

&lt;p&gt;This tutorial has equipped you with the knowledge to effectively build a real-time chat application. You learned how to set up the backend logic and event broadcast using WebSockets with Laravel, handle real-time communication with Pusher, and build a dynamic frontend using Vue.js to listen for and display events.&lt;/p&gt;

&lt;p&gt;With these skills, you can now create more complex real-time applications, or add additional features to your chat app. The possibilities are endless!&lt;/p&gt;

&lt;p&gt;Keep building!&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>vue</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Rust vs Go? Which Should You Learn in 2026</title>
      <dc:creator>Damilola Oshungboye</dc:creator>
      <pubDate>Tue, 27 Aug 2024 11:55:30 +0000</pubDate>
      <link>https://dev.to/thatcoolguy/rust-vs-go-which-should-you-choose-in-2024-50k5</link>
      <guid>https://dev.to/thatcoolguy/rust-vs-go-which-should-you-choose-in-2024-50k5</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Rust and Go are languages with applications in performance-critical applications. This article breaks down the main features and typical use cases for both languages.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Within the last decade, Rust and Go have grown quite popular. Memory-safe Rust is mainly used in systems programming. Go is favored because of its simplicity and built-in concurrency, which makes it perfect for building scalable web applications and APIs. Interestingly, the largest technology firms, such as FAANG and Fortune 100 companies, use both Rust and Go for different aspects of their applications.&lt;/p&gt;

&lt;p&gt;In this article, you will discover the answer to the question "Should I Rust or Should I Go?". You'll learn how Rust and Go compare to each other in terms of concurrency, and memory safety among others. Also, you'll learn about the different scenarios best suited to each language.&lt;/p&gt;

&lt;p&gt;By the end of this article, you will be well informed of key features and use cases of both languages, leading you to an informed decision in choosing the right one for your project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview of Rust
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.rust-lang.org/" rel="noopener noreferrer"&gt;Rust&lt;/a&gt; is a high-level programming language with a strong focus on memory safety created by Graydon Hoare, a former Mozilla employee as a personal project in 2006. Memory-safe languages like Rust have been &lt;a href="https://stackoverflow.blog/2024/03/04/in-rust-we-trust-white-house-office-urges-memory-safety/" rel="noopener noreferrer"&gt;recommended&lt;/a&gt;  by the United States Department.&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%2Fhackmd.io%2F_uploads%2Frk7PO0kjR.svg" 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%2Fhackmd.io%2F_uploads%2Frk7PO0kjR.svg" alt="Rust Logo" width="144" height="144"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Memory Safety:&lt;/strong&gt; Rust enforces memory safety at compile time without using garbage collection.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance Comparable to C/C++:&lt;/strong&gt; Rust’s is as fast as C and C++.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ownership System:&lt;/strong&gt; Rust supports concurrent operations using its ownership and borrowing system.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Strong Type System and Pattern Matching&lt;/strong&gt;: Rust's type system and pattern matching features enhance code safety.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Overview of Go
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://go.dev/" rel="noopener noreferrer"&gt;Go&lt;/a&gt; is an open-source programming language created at Google by Robert Griesemer, Rob Pike, and Ken Thompson in 2009. It's statically typed and similar to C++ in syntax.  In an &lt;a href="https://evrone.com/blog/rob-pike-interview" rel="noopener noreferrer"&gt;interview&lt;/a&gt;, Rob Pike said Go was created because of the difficulty associated with concurrency operations in C++ at the time.&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%2Fvpe43jlskd3ihkv2py77.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%2Fvpe43jlskd3ihkv2py77.png" alt="Go Logo" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Simplicity:&lt;/strong&gt; Go has a moderate learning curve which makes it easier to work with.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fast Compilation Times:&lt;/strong&gt; Go compiles quickly, allowing for rapid development and iteration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Built-in Concurrency:&lt;/strong&gt; Go’s built-in goroutines and channels allow for concurrency operations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Strong Standard Library:&lt;/strong&gt; Go’s standard library is very robust.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Comparison: Rust vs Go
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Performance
&lt;/h3&gt;

&lt;p&gt;In this section, you'll learn how Rust and Go compare in terms of speed and memory usage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Benchmark comparisons&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://benchmarksgame-team.pages.debian.net/benchmarksgame/fastest/rust-go.html" rel="noopener noreferrer"&gt;Benchmarks Game&lt;/a&gt; compared the runtime and memory usage of both Rust and Go. For all the algorithms tested, it was discovered that the most optimized Rust code has a faster execution time compared to the most optimized Go code.&lt;/p&gt;

&lt;p&gt;For the &lt;code&gt;regex-redux&lt;/code&gt; and &lt;code&gt;binary trees&lt;/code&gt; algorithms, Rust by far outperforms Go as shown in the images below. Rust code uses less memory and executes in a shorter time compared to Go.&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%2F7n2i1k8q4cocjc9y20g1.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%2F7n2i1k8q4cocjc9y20g1.png" alt="Rust vs Go: regex-redux" width="800" height="896"&gt;&lt;/a&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%2Fhvtxobmwmsclt0ywq92b.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%2Fhvtxobmwmsclt0ywq92b.png" alt="Rust vs Go: binary-trees" width="800" height="900"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Memory Management and Efficiency&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Both Rust and Go are memory-safe languages although they achieve this in different ways. Rust by design favours fast execution while Go favours fast compilation. Rust's ownership and borrowing system prevent many common causes of memory leaks at compile time, while Go relies on automatic garbage collection to free up unused memory at runtime. However, both languages can still experience memory leaks under certain circumstances.&lt;/p&gt;

&lt;h3&gt;
  
  
  Concurrency and Parallelism
&lt;/h3&gt;

&lt;p&gt;In this section, you'll learn about the unique approaches of Rust and Go to concurrency and parallelism.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Rust's Approach&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Rust supports concurrency through the use of the async/await paradigm and the use of threads and channels.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Async/Await Paradigm in Rust&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rust's async/await paradigm allows you to write asynchronous code that is easier to read and maintain. Runtimes built on Rust's &lt;code&gt;Future&lt;/code&gt; trait like Tokio or async-std are often used with the async/await paradigm. Here's an example of using async/await:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;tokio&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;time&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;execute_task&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Task has begun."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_secs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Task is done."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[tokio::main]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;task_handle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;tokio&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;spawn&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="nf"&gt;execute_task&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="n"&gt;task_handle&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Main function completed."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above, the &lt;code&gt;execute_task&lt;/code&gt; function simulates a task that takes some time to complete. The Rust &lt;a href="https://tokio.rs/" rel="noopener noreferrer"&gt;Tokio&lt;/a&gt; runtime manages the &lt;code&gt;main&lt;/code&gt; function's execution without blocking the thread, allowing other asynchronous tasks to proceed concurrently. The &lt;code&gt;main&lt;/code&gt; function then waits for the task to finish before printing a completion message. &lt;/p&gt;

&lt;p&gt;Here's the output:&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%2Fa88cdpo55yazgxnk7wt8.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%2Fa88cdpo55yazgxnk7wt8.png" alt="Rust async/await output" width="800" height="203"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Using Threads and Channels&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rust's standard library provides support for threads and message-passing concurrency with channels. Here's an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;sync&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;mpsc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;time&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;mpsc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nn"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;move&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"greetings"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"from"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"the"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"worker"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;];&lt;/span&gt;

        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="nf"&gt;.send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="nn"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_secs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;received_message&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;receiver&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Received: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;received_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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above, a new &lt;code&gt;thread&lt;/code&gt; which runs concurrently with the main thread is created using &lt;code&gt;thread::spawn()&lt;/code&gt;. This &lt;code&gt;thread&lt;/code&gt; sends a series of messages through a &lt;code&gt;channel&lt;/code&gt; created using &lt;code&gt;mpsc::channel()&lt;/code&gt;. As messages are sent from the spawned thread, they are received and printed by the main thread.&lt;/p&gt;

&lt;p&gt;Here's the output:&lt;br&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%2F51sky0pt3gs52141rmyf.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%2F51sky0pt3gs52141rmyf.png" alt="Rust thread output" width="800" height="213"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Go's Approach&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Go achieves concurrency through the use of goroutines and channels. Goroutines are lightweight threads managed by the Go runtime which allows functions to run concurrently. A regular function can be made into a goroutine by adding the &lt;code&gt;go&lt;/code&gt; keyword in front of it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Concurrency with Goroutines&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;displayDigits&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// sleep to demonstrate concurrency&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Digit: %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&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;func&lt;/span&gt; &lt;span class="n"&gt;displayCharacters&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="sc"&gt;'A'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="sc"&gt;'E'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Character: %c&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&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;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Launch the goroutines&lt;/span&gt;
    &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;displayDigits&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;displayCharacters&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c"&gt;// Wait for the goroutines to complete&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;6&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Finished"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In this code above, two goroutines are defined. The first goroutine prints digits from 1 to 5, while the second prints characters from A to E. The &lt;code&gt;main&lt;/code&gt; function launches these goroutines and then waits for 6 seconds so the goroutines have enough time to run before printing "Finished". &lt;/p&gt;

&lt;p&gt;Here's the output&lt;br&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%2Fnelhepoc1zlovmg1my1v.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%2Fnelhepoc1zlovmg1my1v.png" alt="Goroutins output" width="750" height="528"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Goroutines can communicate with each other using channels. Here's an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"fmt"&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;transmitMessages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;msgs&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"Greetings"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Simplicity"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Concurrency"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;msgs&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Properly close the channel after sending all messages&lt;/span&gt;
    &lt;span class="nb"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Launch the transmission of messages concurrently&lt;/span&gt;
    &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;transmitMessages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above, the &lt;code&gt;transmitMessages&lt;/code&gt; function, running as a separate goroutine, sends a series of messages through a channel. Then, the &lt;code&gt;main&lt;/code&gt; function receives these messages and prints them.&lt;/p&gt;

&lt;p&gt;Here's the output:&lt;br&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%2Foxv9w9xvlgvue8xracvn.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%2Foxv9w9xvlgvue8xracvn.png" alt="Go Channels code output" width="328" height="180"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Learning Curve and Development Speed
&lt;/h3&gt;

&lt;p&gt;Here, you'll learn about the learning curve of both languages and the development speed.&lt;/p&gt;

&lt;p&gt;Rust has a much steeper learning curve compared to Go which has been hailed by developers worldwide for its simplicity and easy-to-understand syntax. Rust on the other hand takes a whole lot more time to understand as developers often struggle with important concepts like its memory safety rules, type conversions, and type checks.&lt;/p&gt;

&lt;p&gt;The same can be said about development speed because Go is easier to understand, and developers can begin working with it faster as opposed to Rust which can take a bit of time because of the steep learning curve.&lt;/p&gt;
&lt;h3&gt;
  
  
  Safety and Reliability
&lt;/h3&gt;

&lt;p&gt;In this section, you'll learn about the different measures both languages set to allow for safety and reliability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Rust’s Ownership System&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In Rust, when a value is assigned to a variable or moved to a function, the ownership is transferred, leading to the original variable being inaccessible. This is to prevent &lt;a href="https://owasp.org/www-community/vulnerabilities/Doubly_freeing_memory" rel="noopener noreferrer"&gt;double-free errors&lt;/a&gt; and &lt;a href="https://www.mathworks.com/products/polyspace/static-analysis-notes/what-data-races-how-avoid-during-software-development.html" rel="noopener noreferrer"&gt;data races&lt;/a&gt;. Rust's ownership system ensures memory safety by managing the memory allocation and deallocation process.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&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;let&lt;/span&gt; &lt;span class="n"&gt;c2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Ownership model"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;c3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we have a string &lt;code&gt;c2&lt;/code&gt;. When we assign &lt;code&gt;c2&lt;/code&gt; to &lt;code&gt;c3&lt;/code&gt;, Rust invalidates &lt;code&gt;c2&lt;/code&gt;. If you try to print &lt;code&gt;c2&lt;/code&gt;, you'll get a compile-time error as shown in the image below.&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%2Frxatvp11ezeae0ulcggn.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%2Frxatvp11ezeae0ulcggn.png" alt="Rust complile error" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Go’s error handling&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Unlike in most modern programming languages, errors in Go are not exceptions. They're simply values that implement the &lt;code&gt;error&lt;/code&gt; interface. This approach allows for a more readable and maintainable code. Below is the &lt;code&gt;error&lt;/code&gt; interface used by Go.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Ecosystem and Community
&lt;/h3&gt;

&lt;p&gt;When comparing Rust and Go, it's important to consider their ecosystems, community sizes, and corporate support&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Community size and activity&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Both Rust and Go have active and vibrant communities. Although Go stands out with more GitHub stars and active users compared to Rust. Below is the GitHub Page and the number of Stack Overflow questions asked for both languages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rust&lt;/strong&gt;&lt;br&gt;
Below is the &lt;a href="https://github.com/rust-lang/rust" rel="noopener noreferrer"&gt;Rust Github page&lt;/a&gt; with 96k stars and &lt;a href="https://stackoverflow.com/questions/tagged/rust" rel="noopener noreferrer"&gt;Stack Overflow page&lt;/a&gt; with over 42k questions tagged [rust].&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%2Fo7dsnbw92vr6vfbk0nyk.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%2Fo7dsnbw92vr6vfbk0nyk.png" alt="Rust GitHub Page" width="800" height="237"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Rust GitHub Stars&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbvhzvnwegucl14qwwjhh.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%2Fbvhzvnwegucl14qwwjhh.png" alt="Rust Stackoverflow questions asked" width="800" height="199"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Rust Stack Overflow Questions&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Go&lt;/strong&gt;&lt;br&gt;
Below is the &lt;a href="https://github.com/golang/go" rel="noopener noreferrer"&gt;Go Github page&lt;/a&gt; with 122k stars and&lt;a href="https://stackoverflow.com/questions/tagged/go" rel="noopener noreferrer"&gt; Stack Overflow page&lt;/a&gt; with over 73k questions tagged [go].&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%2F51txdtm74y4bhx963z8q.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%2F51txdtm74y4bhx963z8q.png" alt="Go GitHub page" width="800" height="217"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Go GitHub Stars&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2wodnavo1ijkx66ychrw.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%2F2wodnavo1ijkx66ychrw.png" alt="Go Stackoverflow questions asked" width="800" height="199"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Go Stack Overflow Questions&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;According to a 2024 &lt;a href="https://survey.stackoverflow.co/2024/technology/" rel="noopener noreferrer"&gt;survey&lt;/a&gt; by Stack Overflow, developers voted Rust as the most admired programming language for 8+ years in a row.&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%2F9pno3zyozyie16d8o55i.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9pno3zyozyie16d8o55i.jpg" alt="2024 Survey by Stack Overflow" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Corporate support and adoption&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Rust is backed by Mozilla, and now by the Rust Foundation. Tech companies like Dropbox, Cloudflare, and Meta are using Rust for performance-intensive services.&lt;/p&gt;

&lt;p&gt;Go was created at Google, and it has substantial corporate support and adoption. Major companies like Google, Uber and Dropbox rely on Go for many of their backend services. &lt;a href="https://www.docker.com/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt;, a leading containerization technology was built mainly in Go.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Popular Frameworks and Libraries&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rust:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Actix:&lt;/strong&gt; A powerful, fast web framework.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rocket:&lt;/strong&gt; A web framework focused on ease of use and safety.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Serde:&lt;/strong&gt; A widely-used library for serialization and deserialization.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tokio:&lt;/strong&gt; A runtime for writing asynchronous applications with Rust.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Go:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Gin:&lt;/strong&gt; A lightweight web framework that’s easy to use.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Beego:&lt;/strong&gt; An open-source, high-performance web framework.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GORM:&lt;/strong&gt; The most popular ORM for Go, making it easy to handle databases.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cobra:&lt;/strong&gt; A library for creating powerful CLI applications.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is a table summarizing the key differences between each language.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Aspect&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Rust&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Go&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Memory Safety&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Enforced at compile time without the need for garbage collection.&lt;/td&gt;
&lt;td&gt;Relies on a garbage collector.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Performance&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Comparable to C/C++.&lt;/td&gt;
&lt;td&gt;Slightly lower than Rust but fast enough for many applications.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Concurrency Model&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Utilizes an ownership model with threads and async tasks.&lt;/td&gt;
&lt;td&gt;Built-in support with goroutines and channels.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Type System&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Strong with pattern matching and type inference.&lt;/td&gt;
&lt;td&gt;Statically typed with a simpler type system.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Compilation Times&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Slower due to complex optimizations and safety checks.&lt;/td&gt;
&lt;td&gt;Faster compilation.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ease of Use&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Steeper learning curve due to advanced features.&lt;/td&gt;
&lt;td&gt;Easier to learn.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Standard Library&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Rich but less extensive, focusing more on performance-critical and systems programming features.&lt;/td&gt;
&lt;td&gt;Comprehensive, especially strong in networking, I/O, and web server support.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Community and Ecosystem&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Rapidly growing, especially among systems programmers interested in safety and performance.&lt;/td&gt;
&lt;td&gt;Large and mature, widely used in cloud infrastructure, networking, and DevOps tools.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Error Handling&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Based on &lt;code&gt;Result&lt;/code&gt; and &lt;code&gt;Option&lt;/code&gt; types.&lt;/td&gt;
&lt;td&gt;Uses the &lt;code&gt;error&lt;/code&gt; interface, treating errors as values.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  When to use Rust
&lt;/h2&gt;

&lt;p&gt;Rust particularly excels in performance and memory-critical scenarios or scenarios where a large amount of data is being processed. You can use Rust in the following scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Systems programming:&lt;/strong&gt; Rust because of its memory safety can be used to build system-level programs like operating systems.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;High-Performance Computing:&lt;/strong&gt; Rust is ideal for applications that require exceptional performance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Large-scale distributed system:&lt;/strong&gt; Rust memory safety and speed make it an excellent choice when building distributed systems.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When to use Go
&lt;/h2&gt;

&lt;p&gt;Go can be used in a variety of scenarios. Its built-in concurrency makes it a great choice for applications handling multiple requests. Overall, Go is a good fit if you value code simplicity and readability over performance. You should use Go if you need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Concurrent operations:&lt;/strong&gt; Go allows for concurrent operations using its goroutines.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fast development:&lt;/strong&gt; Go has a straightforward syntax with a standard library which allows for speedy development.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simplicity and readability:&lt;/strong&gt; Go’s easy-to-understand syntax makes it ideal for large teams.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;At the end of the day, both Rust and Go are great choices when it comes to building server-side applications. However, the correct choice will be based on the requirements of your application and what you want to achieve.&lt;/p&gt;

&lt;p&gt;This article covered the key features, use cases and differences between the Rust and Go languages, equipping you with the knowledge to decide on the best one according to your project requirements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;Here are some resources for further reading.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://medium.com/@TechSavvyScribe/ownership-and-borrowing-in-rust-a-comprehensive-guide-1400d2bae02a" rel="noopener noreferrer"&gt;Rust Ownersip Model&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>rust</category>
      <category>go</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Bootstrap vs. Tailwind CSS: A Comparison of Top CSS Frameworks</title>
      <dc:creator>Damilola Oshungboye</dc:creator>
      <pubDate>Fri, 16 Aug 2024 13:26:38 +0000</pubDate>
      <link>https://dev.to/strapi/bootstrap-vs-tailwind-css-a-comparison-of-top-css-frameworks-64i</link>
      <guid>https://dev.to/strapi/bootstrap-vs-tailwind-css-a-comparison-of-top-css-frameworks-64i</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;There are numerous CSS frameworks available today, each with its unique offerings. Selecting the right CSS framework among these options can be challenging, as most users are unsure which framework best suits their web development project.&lt;/p&gt;

&lt;p&gt;In this article, we will compare two of the most popular CSS frameworks - Bootstrap and Tailwind CSS.  You'll learn about their key features, design philosophies, and the  CSS customization options for each one. Also, apart from that, you'll get familiar with the developer experience, performance, and support from the community for each of the frameworks.&lt;/p&gt;

&lt;p&gt;By the end of this article, you will know the ins and outs of each framework in detail to decide which CSS framework best fits your needs for a project.&lt;/p&gt;

&lt;p&gt;Let's get into it!&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;First, let's understand the frameworks Bootstrap Vs Tailwind CSS.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bootstrap
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://getbootstrap.com/" rel="noopener noreferrer"&gt;Bootstrap&lt;/a&gt; is a free, open-source CSS framework for creating responsive web pages. Formerly called Twitter Bootstrap, it was created in mid-2010 by Mark Otto and Jacob Thornton, former Twitter engineers, to improve the consistency of Twitter's (now X) internal tools.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Grid system&lt;/strong&gt;: 12-column grid system that simplifies responsive design.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Component-based&lt;/strong&gt;: Pre-styled components make building and deploying consistent user interfaces easy.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Tailwind CSS
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://tailwindcss.com/" rel="noopener noreferrer"&gt;Tailwind CSS&lt;/a&gt; is a utility-first CSS framework created by Adam Wathan, Jonathan Reinink, David Hemphill, and Steve Schoger. They shared a common frustration with existing CSS frameworks. Due to its utility-first approach, it gained rapid popularity, offering granular control over styling.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Utility-First&lt;/strong&gt;: Tailwind CSS is known for its utility-first approach, offering a wide range of utility classes for styling without needing custom CSS.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customization&lt;/strong&gt;: Thanks to its utility classes, developers can easily customize designs using Tailwind CSS.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is the summary of the key features of each of this frameworks.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Tailwind CSS&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Bootstrap&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Utility-first approach&lt;/td&gt;
&lt;td&gt;Pre-designed UI components&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Responsive design&lt;/td&gt;
&lt;td&gt;Responsive CSS flexbox and grid system&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Very flexible and customizable&lt;/td&gt;
&lt;td&gt;Built-in themes and customization&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Integration with modern tools&lt;/td&gt;
&lt;td&gt;Compatibility with many tools and platforms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Design Philosophy &amp;amp; Approach
&lt;/h2&gt;

&lt;p&gt;In this section, you'll understand the different principles upon which these two frameworks are built. Understanding the principles behind a framework is very important for determining how it fits into your use case.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bootstrap
&lt;/h3&gt;

&lt;p&gt;Bootstrap adopts a &lt;a href="https://www.linkedin.com/pulse/building-scalable-maintainable-front-end-component-based-fngje/" rel="noopener noreferrer"&gt;component-based approach&lt;/a&gt;, offering a set of pre-built and pre-styled components like navbars and buttons that you can easily use while building UIs. This design philosophy has several benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Rapid Development&lt;/strong&gt;: Quickly assemble responsive UIs without extensive CSS customization.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistency&lt;/strong&gt;: Ensures your application's uniform look and feel.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Below is an example of its usage.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class= &lt;/span&gt;&lt;span class="s"&gt;"btn btn-success"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
   Success
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the example above, the &lt;code&gt;btn&lt;/code&gt; and &lt;code&gt;btn-success&lt;/code&gt; classes style the button with Bootstrap's predefined styles for primary buttons.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tailwind CSS
&lt;/h3&gt;

&lt;p&gt;Tailwind CSS, on the other hand, follows a &lt;a href="https://tw-elements.com/learn/te-foundations/tailwind-css/utility-first/" rel="noopener noreferrer"&gt;utility-first approach&lt;/a&gt;, providing an extensive set of utility classes that directly manipulate the styling of HTML elements. This design philosophy has several benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Customization and Flexibility&lt;/strong&gt;: Build custom designs by composing utility classes directly in your HTML.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintainability&lt;/strong&gt;: Reduces the need to write custom CSS, making your styles more maintainable.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Below is an example of its usage.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"bg-red-500 text-black rounded-lg"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Tailwind CSS utility classes
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the example above, the &lt;code&gt;bg-red-500&lt;/code&gt; sets the background color, &lt;code&gt;text-black&lt;/code&gt; sets the text color, and &lt;code&gt;rounded-lg&lt;/code&gt; rounds the corners of the div. This way, you can create custom designs without writing additional CSS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Customization and Theming
&lt;/h2&gt;

&lt;p&gt;While Bootstrap and Tailwind CSS provide CSS customization and theming options, Tailwind CSS excels in this area.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bootstrap
&lt;/h3&gt;

&lt;p&gt;You can customize Bootstrap by overriding the default classes with your custom class. You can modify the color, spacing, and typography to match your design requirements by using &lt;a href="https://www.w3schools.com/css/css3_variables_overriding.asp" rel="noopener noreferrer"&gt;CSS Overrides&lt;/a&gt; or &lt;a href="https://sass-lang.com/" rel="noopener noreferrer"&gt;SASS&lt;/a&gt; variables. Overriding default classes using CSS Overrides is easier than SASS variables, aimed at more advanced users. Here's how you can customize Bootstrap using CSS Overrides:&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, shrink-to-fit=no"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"bootstrap/css/bootstrap.min.css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/css"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"custom.css"&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;Hello, world!&lt;span class="nt"&gt;&amp;lt;/title&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;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As seen in the sample above, your document's HTML file should include a Bootstrap-compiled file and a custom CSS file in the head tag. Create a custom &lt;code&gt;custom.css&lt;/code&gt; file in the same directory as your &lt;code&gt;index.html&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;For example, to style all your buttons with a red background and white text, you can override the default Bootstrap style by adding the below code to your &lt;code&gt;custom.css&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.btn&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#ff0000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* Red background */&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;#ffffff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* White text */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Below is the result.&lt;/p&gt;

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

&lt;p&gt;Bootstrap also allows you to customize the theme using SASS variables. To change the primary theme color in your components, you can add the following in your custom SASS file, as seen below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="nt"&gt;theme-colors&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;
  &lt;span class="s1"&gt;"primary"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;#ff0000&lt;/span&gt;
&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;"node_modules/bootstrap/scss/bootstrap"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will update the primary color across all Bootstrap components that use it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ease of Use&lt;/strong&gt;: Simple overrides with CSS.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SASS Variables&lt;/strong&gt;: Advanced CSS customization through variables.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Limited Flexibility&lt;/strong&gt;: Customizing CSS can be time-consuming due to the need for extensive overrides.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Tailwind CSS
&lt;/h3&gt;

&lt;p&gt;Tailwind CSS allows developers to configure and create new utility classes. Here's an example of customizing a Tailwind CSS utility class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="nt"&gt;tailwind&lt;/span&gt;&lt;span class="nc"&gt;.config.js&lt;/span&gt;
&lt;span class="c"&gt;/** @type {import('tailwindcss').Config} */&lt;/span&gt;
&lt;span class="nt"&gt;module&lt;/span&gt;&lt;span class="nc"&gt;.exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s2"&gt;'./**/*.html'&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="n"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;extend&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;customColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;'#ff0000'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="nt"&gt;plugins&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;[],&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="nt"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"bg-customColor text-white p-4 rounded-lg"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;This&lt;/span&gt; &lt;span class="nt"&gt;is&lt;/span&gt; &lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="nt"&gt;customized&lt;/span&gt; &lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="nt"&gt;using&lt;/span&gt; &lt;span class="nt"&gt;Tailwind&lt;/span&gt; &lt;span class="nt"&gt;CSS&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Below is the result.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4k39hft62eu0s95cidli.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4k39hft62eu0s95cidli.jpg" alt="customized div using Tailwind CSS.jpg" width="790" height="239"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the example above, the &lt;code&gt;bg-customColor&lt;/code&gt; class is a custom utility class defined in the Tailwind CSS configuration file - &lt;code&gt;tailwind.config.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Tailwind CSS also supports theming through its configuration file. Here's an example:&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="c1"&gt;// tailwind.config.js&lt;/span&gt;
&lt;span class="cm"&gt;/** @type {import('tailwindcss').Config} */&lt;/span&gt;
&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;content&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;./**/*.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// &lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;primary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#ff0000&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;secondary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#00ff00&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;spacing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;sm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;8px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;md&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;16px&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="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This configuration above updates the project's primary and secondary colors and spacing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Highly Customizable&lt;/strong&gt;: Extensive utility classes and configuration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexibility&lt;/strong&gt;: Creating and applying custom utilities and themes is easy.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Learning Curve&lt;/strong&gt;: Requires mastering utility classes to create custom layouts.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Developer Experience
&lt;/h2&gt;

&lt;p&gt;Bootstrap's learning curve is moderate compared to Tailwind CSS's steep one. Bootstrap's pre-built components can be easily integrated into an application to create layouts, unlike Tailwind CSS, which requires mastering utility classes to create layouts and styles.&lt;/p&gt;

&lt;h2&gt;
  
  
  Integration with popular front-end frameworks
&lt;/h2&gt;

&lt;p&gt;Bootstrap and Tailwind CSS integrate with popular front-end frameworks such as React and Vue.js. You can easily add Bootstrap and Tailwind CSS to your frontend application by installing from &lt;a href="https://www.npmjs.com/" rel="noopener noreferrer"&gt;npm&lt;/a&gt; or adding a CDN link to the head of your HTML document. Here's how you can add them to your application:&lt;/p&gt;

&lt;h4&gt;
  
  
  Bootstrap
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;//method 1
npm install bootstrap 
&lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"node_modules/bootstrap/dist/css/bootstrap.min.css"&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

//method 2
&lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css"&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using the &lt;a href="https://react-bootstrap.netlify.app/" rel="noopener noreferrer"&gt;React-Bootstrap&lt;/a&gt; framework, Bootstrap also offers easier integration with React. It is a complete re-implementation of the Bootstrap components using React components instead.&lt;/p&gt;

&lt;p&gt;It can be installed from npm like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;react-bootstrap bootstrap
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Tailwind CSS
&lt;/h4&gt;

&lt;p&gt;You can add Tailwind CSS to your project using any of the options below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;//method 1
npm &lt;span class="nb"&gt;install &lt;/span&gt;tailwindcss
npx tailwindcss init
npx tailwindcss build tailwind.css &lt;span class="nt"&gt;-o&lt;/span&gt; tailwind-build.css

//method 2
&amp;lt;script &lt;span class="nv"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://cdn.tailwindcss.com"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;lt;/script&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the first method, we could NPM. And in the second method, we could add it to the &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag of our project.&lt;/p&gt;

&lt;p&gt;Tailwind CSS also offers tighter integration with Vue.js through the &lt;a href="https://www.vue-tailwind.com/" rel="noopener noreferrer"&gt;VueTailwind Component Library&lt;/a&gt;. It offers a set of pre-built, fully customizable Vue components that can be used to jump-start development.&lt;/p&gt;

&lt;p&gt;It can also be installed through npm, as shown below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;vue-tailwind 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Developer Productivity
&lt;/h2&gt;

&lt;p&gt;When it comes to developer productivity, Bootstrap, and Tailwind CSS, each improve developers' productivity in a unique way.&lt;/p&gt;

&lt;p&gt;Bootstrap improves productivity by increasing development speed, allowing developers to design UIs quickly using its pre-built components. Tailwind CSS, on the other hand, will enable developers to spend less time creating custom designs through its utility classes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance and Bundle Size
&lt;/h2&gt;

&lt;p&gt;In this section, we'll compare Bootstrap and Tailwind CSS to see which framework significantly influences page load times and bundle size.&lt;/p&gt;

&lt;h3&gt;
  
  
  Impact on Page Load Times
&lt;/h3&gt;

&lt;p&gt;Bootstrap's pre-built CSS and JavaScript components tend to be large, potentially slowing page load times. You should only include the necessary components to minimize the bundle size, resulting in faster page load times.&lt;/p&gt;

&lt;p&gt;Tailwind CSS, on the other hand, has a relatively faster page load time because it generates CSS on-demand according to the utility class used. &lt;/p&gt;

&lt;p&gt;To demonstrate this, we created two custom HTML files—one for Bootstrap and the other for Tailwind CSS. After measuring the page load time with &lt;a href="https://chromewebstore.google.com/detail/lighthouse/blipmdconlkpinefehnmjammfjpmpbjk" rel="noopener noreferrer"&gt;Chrome Lighthouse&lt;/a&gt;, we found that the Tailwind CSS page loaded faster than the Bootstrap page. Tailwind CSS's faster load times can be attributed to its lightweight utility classes compared to Bootstrap's bulkier files. Below is the performance rating for each framework according to Lighthouse.&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%2F5gcjfbprych4v5zcf0m7.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5gcjfbprych4v5zcf0m7.jpg" alt="bootstrap performance size.jpg" width="800" height="432"&gt;&lt;/a&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%2Ffmnwtcf2lcwty7lwznqt.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffmnwtcf2lcwty7lwznqt.jpg" alt="tailwind performance metrics.jpg" width="800" height="424"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Tailwind CSS's Performance Rating&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Bundle size analysis
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. File size evaluation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Bootstrap's bundle size can be larger than Tailwind CSS's. Below is a screenshot of the bundle size generated by both frameworks.&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%2Fn1530jmsl54pv0ew0kx8.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn1530jmsl54pv0ew0kx8.jpg" alt="bootstrapi bundle size.jpg" width="800" height="432"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Bootstrap Bundle Size&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F16j9ko2ag0mngonbabnv.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F16j9ko2ag0mngonbabnv.jpg" alt="Tailwind CSS Bundle Size.jpg" width="800" height="432"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;TailWind CSS Bundle Size&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Optimization Techniques&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Bootstrap and Tailwind CSS offer optimization techniques to reduce bundle size and improve performance. You can minimize bundle size across both frameworks by &lt;a href="https://www.smashingmagazine.com/2021/05/tree-shaking-reference-guide/" rel="noopener noreferrer"&gt;Tree-Shaking&lt;/a&gt;, which is a process that involves purging unused CSS files from your &lt;code&gt;.css&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Bootstrap can also be optimized further by &lt;a href="https://www.stackpath.com/edge-academy/what-is-minification/" rel="noopener noreferrer"&gt;Minification&lt;/a&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Aspect&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Bootstrap&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Tailwind CSS&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Impact on Page Load Times&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Pre-built components can slow page load times; selective inclusion needed&lt;/td&gt;
&lt;td&gt;Generates CSS on-demand; typically faster page load times&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Bundle Size&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Generally larger bundle size&lt;/td&gt;
&lt;td&gt;Typically smaller bundle size&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Optimization Techniques&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Tree-shaking, Minification (.min.css and .min.js files)&lt;/td&gt;
&lt;td&gt;Tree-shaking, purging unused CSS&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The table above provides an overview of critical performance and bundle size differences between the two frameworks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Design and Aesthetics
&lt;/h2&gt;

&lt;p&gt;In this section, we'll explore the design and aesthetics of Bootstrap and Tailwind CSS. We'll look at the consistency of design in both frameworks, as well as the aesthetic appeal and flexibility of CSS customization.&lt;/p&gt;

&lt;h3&gt;
  
  
  Design consistency
&lt;/h3&gt;

&lt;p&gt;Bootstrap provides a consistent set of default styles for common HTML elements, ensuring a cohesive look and feel across different components. The default styles include typography, colors, Bootstrap buttons, Bootstrap icons, Bootstrap forms, and other elements. &lt;/p&gt;

&lt;p&gt;Tailwind CSS does not have predefined default styles. Users can create custom designs by utilizing the utility classes provided.&lt;/p&gt;

&lt;h3&gt;
  
  
  Flexibility of Design Customization
&lt;/h3&gt;

&lt;p&gt;While Bootstrap allows for CSS customization, it is less flexible than Tailwind CSS, as discussed in the Customization and Theming section. Achieving a fully unique look requires extensive overrides of default styles. Although Bootstrap also has the Bootstrap theme desginer AIs for template generators. Examples Bootstrap theme desginer AIs include &lt;a href="https://bootstrapstudio.io/docs/ai-assistant.html" rel="noopener noreferrer"&gt;Bootstrapi Studio&lt;/a&gt;, &lt;a href="https://mobirise.com/" rel="noopener noreferrer"&gt;Mobirise&lt;/a&gt;, etc.&lt;/p&gt;

&lt;p&gt;Tailwind CSS, on the other hand, allows developers to create customized designs directly in HTML using utility classes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Aesthetic appeal in default styles
&lt;/h3&gt;

&lt;p&gt;Bootstrap offers a polished and professional look and feel out of the box. This you can find in Bootstrap buttons, Bootstrap icons, Bootstrap components etc. Its default styles are aesthetically pleasing, offering solid foundations for web app development with minimal tweaking.&lt;/p&gt;

&lt;p&gt;While Tailwind CSS doesn't have a predefined aesthetic,  its utility-first approach enables a high degree of creativity and variation in design. The images below show that Bootstrap provides a polished, consistent look for the button component, while Tailwind CSS allows for custom button designs.&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%2F4izmatpylmvorenmkwri.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4izmatpylmvorenmkwri.jpg" alt="bootstrap primary button.jpg" width="301" height="115"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Bootstrap's Primary Button Style&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2fe0a9u4cwjk4guaqrpx.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2fe0a9u4cwjk4guaqrpx.jpg" alt="tailwind primary button variants.jpg" width="800" height="149"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Tailwind CSS's Design Variation&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Community and Ecosystem
&lt;/h2&gt;

&lt;p&gt;This section will compare the community and ecosystem in Bootstrap vs Tailwind CSS. &lt;/p&gt;

&lt;h3&gt;
  
  
  Community support
&lt;/h3&gt;

&lt;p&gt;Bootstrap stands out as a large and vibrant community with more users, GitHub stars, and contributors than Tailwind CSS's small but rapidly growing community. Below is the GitHub Page and the number of &lt;a href="https://stackoverflow.com/" rel="noopener noreferrer"&gt;StackOverflow&lt;/a&gt; questions asked for both frameworks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bootstrap&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Below is the &lt;a href="https://github.com/twbs/bootstrap" rel="noopener noreferrer"&gt;Bootstrap Github repository&lt;/a&gt; with 169k stars and &lt;a href="https://stackoverflow.com/questions/tagged/twitter-bootstrap" rel="noopener noreferrer"&gt;Stack Overflow pages&lt;/a&gt; with over 103k questions tagged &lt;code&gt;[twitter-bootstrap]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqfm2tibktk9sr1gnxlgi.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%2Fqfm2tibktk9sr1gnxlgi.png" alt="bootstrapi github stars.png" width="800" height="199"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Bootstrap's GitHub Page&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdw0b6fklcvhov6ldp275.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%2Fdw0b6fklcvhov6ldp275.png" alt="bootstrap Stack Overflow pages.png" width="800" height="280"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Bootstrap's StackOverflow Questions&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tailwind CSS&lt;/strong&gt;&lt;br&gt;
Also, below is &lt;a href="https://github.com/tailwindlabs/tailwindcss" rel="noopener noreferrer"&gt;Tailwind CSS Github Repo&lt;/a&gt; with about 81.2k starts  and about 10k number of &lt;a href="https://stackoverflow.com/questions/tagged/tailwind-css" rel="noopener noreferrer"&gt;questions on Stack Overflow&lt;/a&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%2Fixwqa2dhgthiaylvynqt.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%2Fixwqa2dhgthiaylvynqt.png" alt="Tailwind Github Stars.png" width="800" height="242"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Tailwind CSS's GitHub Page&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgk8u46u2isggo3r4r38y.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%2Fgk8u46u2isggo3r4r38y.png" alt="Tailwind Stack Overflow Pages.png" width="800" height="369"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Tailwind CSS's StackOverflow Questions&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Documentation quality
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://getbootstrap.com/docs/5.3/getting-started/introduction/" rel="noopener noreferrer"&gt;Bootstrap official documentation&lt;/a&gt; is one of the best around, having benefitted from years of continuous iteration; it is well-organized, covering all aspects of the framework. Tailwind CSS also features impressive &lt;a href="https://v2.tailwindcss.com/docs" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;, but it can't be compared to Bootstrap's at the time of writing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Third-Party Resources
&lt;/h3&gt;

&lt;p&gt;Bootstrap and Tailwind CSS have a wealth of online tutorials and guides created by the community and third parties. Some examples include:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bootstrap:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.w3schools.com/bootstrap5/" rel="noopener noreferrer"&gt;Bootstrap 5 Tutorial by W3Schools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=4sosXZsdy-s" rel="noopener noreferrer"&gt;Bootstrap 5 Crash Course by Traversy Media on YouTube&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Tailwind CSS:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; 📹 &lt;a href="https://www.youtube.com/watch?v=rvo-L0cP5NA" rel="noopener noreferrer"&gt;Epic Next.js Tutorial For Beginners: build real life project with Next.js 14, Tailwind, and Strapi.&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://strapi.io/blog/how-to-build-a-job-board-with-next-js-tailwind-css-and-strapi" rel="noopener noreferrer"&gt;How to Build a Job Board with Next.js, Tailwind CSS, and Strapi&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://strapi.io/blog/how-to-build-a-blog-with-astro-strapi-and-tailwind-css" rel="noopener noreferrer"&gt;How to Build a Blog with Astro, Strapi, and Tailwind CSS&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's a table summarizing the community and ecosystem differences between Bootstrap and Tailwind CSS:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Aspect&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Bootstrap&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Tailwind CSS&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Community Support&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Large and established community; extensive user base and contributors.&lt;/td&gt;
&lt;td&gt;Smaller but rapidly growing community; increasing engagement.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Documentation Quality&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Extensive, well-organized, continuously updated documentation.&lt;/td&gt;
&lt;td&gt;Comprehensive and well-maintained documentation; newer compared to Bootstrap.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Third-Party Resources&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Wide range of tutorials, themes, plugins, and extensions available.&lt;/td&gt;
&lt;td&gt;Growing number of tutorials and resources; fewer themes and plugins than Bootstrap.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

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

&lt;p&gt;In this article, we compare two popular front-end frameworks, Bootstrap and Tailwind CSS, examining their strengths and weaknesses. Overall, both frameworks are great choices when building modern applications. The right choice, however, depends on your project requirements.&lt;/p&gt;

&lt;p&gt;You can try out both Bootstrap and Tailwind CSS. Experiment with their features and see which aligns best with your project requirements. Visit the &lt;a href="https://getbootstrap.com/docs/5.3/getting-started/introduction/" rel="noopener noreferrer"&gt;Bootstrap documentation&lt;/a&gt; and the &lt;a href="https://v2.tailwindcss.com/docs" rel="noopener noreferrer"&gt;Tailwind CSS&lt;/a&gt; documentation to get started. &lt;/p&gt;

</description>
      <category>tailwindcss</category>
      <category>bootstrap</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Twilio Challenge: Can You Beat Gemini? AI-Powered Game of Tic Tac Toe</title>
      <dc:creator>Damilola Oshungboye</dc:creator>
      <pubDate>Mon, 17 Jun 2024 00:20:22 +0000</pubDate>
      <link>https://dev.to/thatcoolguy/twilio-challenge-can-you-beat-gemini-tic-tac-toe-1em8</link>
      <guid>https://dev.to/thatcoolguy/twilio-challenge-can-you-beat-gemini-tic-tac-toe-1em8</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/twilio"&gt;Twilio Challenge &lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I built an interactive AI-powered game of Tic-Tac-Toe called "Can You Beat Gemini?" This project allows players to test their Tic-Tac-Toe skills against Gemini AI, providing a challenging and fun experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  Features
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;AI Integration&lt;/strong&gt;: The game uses the Gemini AI model to analyse the game state and predict the best possible moves to challenge the player effectively.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real-Time Interaction&lt;/strong&gt;: Players interact with the game through digits (1-9). The game captures the player's move and processes it. The AI then responds with its move. This interaction is facilitated using Twilio's Programmable Voice capabilities, making the gameplay seamless and engaging.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dynamic Game Board&lt;/strong&gt;: The game state is visually represented, updating in real-time as moves are made. This ensures players can keep track of their and the AI's moves.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;You can try it out by scanning the QR Code in the image or by texting the code &lt;strong&gt;join front-trace&lt;/strong&gt; to the number &lt;strong&gt;+14155238886&lt;/strong&gt; on WhatsApp. Next call number &lt;strong&gt;+1 (806) 615-3056&lt;/strong&gt; to play the Tic Tac Toe game.&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%2Fo39n4watwqkwm2utv81g.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%2Fo39n4watwqkwm2utv81g.png" alt=" " width="800" height="323"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Video of How it Works
&lt;/h3&gt;

&lt;p&gt;&lt;iframe src="https://player.vimeo.com/video/960750355" width="710" height="399"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;In the video description above, a call is made to &lt;strong&gt;+1 (806) 615-3056&lt;/strong&gt; to begin the game. The user selects any number between (1-9) to make their move. Gemini AI then analyzes the game state and responds with its move. The game continues with the user and AI taking turns until a winner emerges.&lt;/p&gt;

&lt;h3&gt;
  
  
  Source Code
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/ThatCoolGuyyy" rel="noopener noreferrer"&gt;
        ThatCoolGuyyy
      &lt;/a&gt; / &lt;a href="https://github.com/ThatCoolGuyyy/Tic-Tac-Toe-Gemini-Twilio" rel="noopener noreferrer"&gt;
        Tic-Tac-Toe-Gemini-Twilio
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Can You Beat Gemini? Tic Tac Toe&lt;/h1&gt;

&lt;/div&gt;
&lt;p&gt;Welcome to the &lt;strong&gt;Can You Beat Gemini? Tic Tac Toe&lt;/strong&gt; project! This is an interactive Tic-Tac-Toe game where you play against an AI opponent named Gemini(Gemini API). The AI is designed to challenge your strategic thinking and make your Tic-Tac-Toe games more interesting.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Video Demo&lt;/h1&gt;

&lt;/div&gt;

  
    
    

    &lt;span class="m-1"&gt;RPReplay_Final1718633328.mov&lt;/span&gt;
    
  

  

  


&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;How it works&lt;/h1&gt;

&lt;/div&gt;
&lt;p&gt;Twilio Programmable Voice is used to get input from the user in digits (1-9), each representing a cell on the Tic-Tac-Toe board. Then, Gemini AI to play against the human user. Finally, Twilio Messaging API (WhatsApp) is used to send the updated board when both AI and human players make their moves. Twilio Functions was used to host the code.&lt;/p&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/ThatCoolGuyyy/Tic-Tac-Toe-Gemini-Twilio" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;h2&gt;
  
  
  Twilio and AI
&lt;/h2&gt;

&lt;p&gt;I used Twilio to get input from the user in digits (1-9), each representing a cell on the Tic-Tac-Toe board. Then, I used &lt;strong&gt;Gemini AI&lt;/strong&gt; to play against the human user. Finally, I used the &lt;strong&gt;Twilio Programmable Messaging (WhatsApp Sandbox)&lt;/strong&gt; to send the updated board when both AI and human players make their moves. I also used &lt;strong&gt;Twilio Functions&lt;/strong&gt; to host the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Additional Prize Categories
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Twilio Times Two&lt;/strong&gt; - The project uses &lt;strong&gt;Twilio Programmable Messaging (WhatsApp Sandbox)&lt;/strong&gt;, &lt;strong&gt;Twilio Programmable Voice&lt;/strong&gt; and, &lt;strong&gt;Twilio Functions.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Entertaining Endeavors&lt;/strong&gt; - The project creatively combines a classic game with advanced AI technology, making it not just a simple Tic Tac Toe game but an engaging battle of wits against an AI opponent. By leveraging Twilio to receive user inputs and send real-time game updates via WhatsApp, the project ensures continuous engagement and keeps the players entertained throughout the game.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>twiliochallenge</category>
      <category>ai</category>
      <category>twilio</category>
    </item>
    <item>
      <title>Twilio Challenge: AI-Powered Voice Assistant</title>
      <dc:creator>Damilola Oshungboye</dc:creator>
      <pubDate>Sun, 16 Jun 2024 15:37:29 +0000</pubDate>
      <link>https://dev.to/thatcoolguy/twilio-challenge-ai-powered-voice-assistant-30j8</link>
      <guid>https://dev.to/thatcoolguy/twilio-challenge-ai-powered-voice-assistant-30j8</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/twilio"&gt;Twilio Challenge &lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I created an AI-powered voice assistant designed to handle complex questions.  Many existing voice assistants struggle with these types of inquiries, which can be frustrating for users.  My assistant aims to bridge this gap.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;To try out this app, make a call to &lt;strong&gt;+1 (423) 454-3174&lt;/strong&gt;. You will be greeted with a prompt, say your request after the initial prompt.&lt;/p&gt;

&lt;h3&gt;
  
  
  Source code
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/ThatCoolGuyyy" rel="noopener noreferrer"&gt;
        ThatCoolGuyyy
      &lt;/a&gt; / &lt;a href="https://github.com/ThatCoolGuyyy/Twilio-Gemini" rel="noopener noreferrer"&gt;
        Twilio-Gemini
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;AI-Powered Voice Assistant&lt;/h1&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;How it works&lt;/h1&gt;

&lt;/div&gt;
&lt;p&gt;Twilio Programmable voice get the user's request and then passes it to Gemini API which then return a response. Twilio Functions was used to host the code&lt;/p&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/ThatCoolGuyyy/Twilio-Gemini" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;Here is an article I wrote that has detailed steps to build the PHP-Laravel version of this voice assistant - &lt;a href="https://www.twilio.com/en-us/blog/build-ai-powered-voice-assistant-twilio-laravel-openai" rel="noopener noreferrer"&gt;https://www.twilio.com/en-us/blog/build-ai-powered-voice-assistant-twilio-laravel-openai&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Twilio and AI
&lt;/h2&gt;

&lt;p&gt;I used &lt;strong&gt;Twilio Programmable voice&lt;/strong&gt; to get the user's request, this request is then passed into &lt;strong&gt;Gemini API&lt;/strong&gt; which processes the request and returns a response. &lt;strong&gt;Twilio Programmable Voice&lt;/strong&gt; is then used to return the response to the user in voice format. &lt;strong&gt;Twilio Functions&lt;/strong&gt; was used to host the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Additional Prize Categories
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Twilio Times Two&lt;/strong&gt; - The project uses &lt;strong&gt;Twilio Programmable Voice&lt;/strong&gt; and &lt;strong&gt;Twilio Functions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Impactful Innovators:&lt;/strong&gt; My AI-powered voice assistant addresses the challenge of accessing information. It helps to bridge the gap between users who might struggle with traditional search methods, like the elderly, people with disabilities, or those with limited literacy skills.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>twiliochallenge</category>
      <category>ai</category>
      <category>twilio</category>
    </item>
    <item>
      <title>How To Build an AI-Powered Voice Assistant With Twilio, Laravel, and OpenAI</title>
      <dc:creator>Damilola Oshungboye</dc:creator>
      <pubDate>Fri, 14 Jun 2024 17:06:30 +0000</pubDate>
      <link>https://dev.to/thatcoolguy/how-to-build-an-ai-powered-voice-assistant-with-twilio-laravel-and-openai-h2o</link>
      <guid>https://dev.to/thatcoolguy/how-to-build-an-ai-powered-voice-assistant-with-twilio-laravel-and-openai-h2o</guid>
      <description>&lt;p&gt;Voice assistants, such as Amazon Alexa and Apple's Siri have become integral to people’s lives, as they're so helpful with mundane tasks, such as setting reminders and turning on smart home devices. However, most voice assistants struggle with complex questions and queries, leaving users disappointed.&lt;/p&gt;

&lt;p&gt;In this tutorial, you will learn how to build an AI-powered voice assistant that can understand and respond to complex questions using Twilio Programmable Voice and OpenAI.&lt;/p&gt;

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

&lt;p&gt;To complete this tutorial, you will need the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A Twilio account, free or paid. If you don't have one, &lt;a href="https://www.twilio.com/try-twilio" rel="noopener noreferrer"&gt;create a Twilio account for free&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;A phone number you own. &lt;a href="https://help.twilio.com/articles/223180048-How-to-Add-and-Remove-a-Verified-Phone-Number-or-Caller-ID-with-Twilio?_ga=2.5842992.288769677.1718382100-1858507213.1708114003&amp;amp;_gl=1*p29jxb*_gcl_au*NzAwOTQ1MDkzLjE3MTU5NjkwMjI.*_ga*MTg1ODUwNzIxMy4xNzA4MTE0MDAz*_ga_RRP8K4M4F3*MTcxODM4MjA5OC44My4xLjE3MTgzODIxNDcuMC4wLjA.#h_01GQT9YZMY444KNH3M5AK065GX" rel="noopener noreferrer"&gt;Add it to your Twilio account&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;PHP 8.2 (or higher) installed&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://getcomposer.org/" rel="noopener noreferrer"&gt;Composer&lt;/a&gt; installed globally&lt;/li&gt;
&lt;li&gt;An OpenAI account. &lt;a href="https://openai.com/" rel="noopener noreferrer"&gt;Create a free account here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ngrok.com/" rel="noopener noreferrer"&gt;ngrok&lt;/a&gt; and a free ngrok account&lt;/li&gt;
&lt;li&gt;Basic knowledge of the &lt;a href="https://laravel.com/docs/10.x/installation" rel="noopener noreferrer"&gt;Laravel&lt;/a&gt; framework would be nice, although it’s not required&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Build the AI-powered voice assistant
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Create a new Laravel project
&lt;/h4&gt;

&lt;p&gt;To create a new Laravel project using Composer, you need to run the command below in your terminal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer create-project laravel/laravel voice-assistant
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, navigate to the project’s working directory and start the application development server by running the commands below in the terminal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;voice-assistant
php artisan serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the application server is up, open &lt;a href="http://localhost:8000/" rel="noopener noreferrer"&gt;http://localhost:8000/&lt;/a&gt; in your browser to access the default Laravel welcome page, as shown in the image below.&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%2Fd3qoq7s1jt2fz4emrnqs.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%2Fd3qoq7s1jt2fz4emrnqs.png" alt="Laravel Welcome Page" width="800" height="612"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The next step is to open the project in your preferred IDE or text editor.&lt;/p&gt;

&lt;h4&gt;
  
  
  Install the Twilio PHP Helper Library
&lt;/h4&gt;

&lt;p&gt;The &lt;a href="https://www.twilio.com/docs/libraries/reference/twilio-php/" rel="noopener noreferrer"&gt;Twilio PHP Helper Library&lt;/a&gt; provides functionality for interacting with Twilio's APIs. With this library, you can easily interact with &lt;a href="https://www.twilio.com/docs/voice" rel="noopener noreferrer"&gt;Twilio Programmable Voice&lt;/a&gt; in the application. Twilio Programmable Voice uses &lt;a href="https://www.twilio.com/docs/voice/twiml" rel="noopener noreferrer"&gt;Twilio Markup language(TwiML)&lt;/a&gt;, to specify the desired behaviour when receiving an incoming call or SMS. &lt;br&gt;
In your project’s working directory, run the command below in a new terminal window or tab to install the library.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require twilio/sdk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Retrieve your Twilio API credentials
&lt;/h4&gt;

&lt;p&gt;You will need your &lt;strong&gt;Account SID&lt;/strong&gt; and &lt;strong&gt;Auth Token&lt;/strong&gt; to interact with Twilio Programmable Voice using the Twilio PHP Helper Library. You can find them in the &lt;strong&gt;Account Info&lt;/strong&gt; panel on your &lt;a href="https://console.twilio.com/?_ga=2.75769622.288769677.1718382100-1858507213.1708114003&amp;amp;_gl=1*135cmdu*_gcl_au*NzAwOTQ1MDkzLjE3MTU5NjkwMjI.*_ga*MTg1ODUwNzIxMy4xNzA4MTE0MDAz*_ga_RRP8K4M4F3*MTcxODM4MjA5OC44My4xLjE3MTgzODIxNDcuMC4wLjA." rel="noopener noreferrer"&gt;Twilio Console dashboard&lt;/a&gt;, as shown in the image below. Copy the respective values.&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%2F2ph8jtd10btvb8mo8hrg.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%2F2ph8jtd10btvb8mo8hrg.png" alt="Twilio Dashboard" width="800" height="470"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Store the Twilio access token in your .env file
&lt;/h4&gt;

&lt;p&gt;After retrieving your Twilio access tokens, you need to ensure that they are stored securely in your project using environment variables.&lt;br&gt;
In your project’s root directory, locate the &lt;em&gt;.env&lt;/em&gt; file. This file is used to securely store sensitive data and other configuration data. Update it with the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TWILIO_SID=&amp;lt;your_twilio_account_sid&amp;gt;
TWILIO_AUTH_TOKEN=&amp;lt;your_twilio_account_auth_token&amp;gt;
TWILIO_PHONE_NUMBER=&amp;lt;your twilio_account_phone_number&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, replace the placeholders with your corresponding Twilio access token values which you just copied.&lt;/p&gt;

&lt;h4&gt;
  
  
  Install the OpenAI Laravel Helper Library
&lt;/h4&gt;

&lt;p&gt;OpenAI is a leading AI research lab known for creating advanced language models trained on extensive amounts of data. The OpenAI Laravel package allows you to easily use OpenAI models in your application. Install the package by running the command below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require openai-php/laravel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, set up the package configurations by executing the below command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan openai:install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will create a new file called &lt;em&gt;openai.php&lt;/em&gt; in the &lt;em&gt;config&lt;/em&gt; folder. The file contains the configurations required to connect to the OpenAI API. &lt;br&gt;
To use the OpenAI API, you'll need an API key for authentication. &lt;a href="https://platform.openai.com/docs/overview" rel="noopener noreferrer"&gt;Log in to your OpenAI account&lt;/a&gt; and navigate to the &lt;strong&gt;API Keys&lt;/strong&gt; section. Click &lt;strong&gt;Create new secret key&lt;/strong&gt; to generate your key.&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%2Fr5isu84a4t2r27xncxwy.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%2Fr5isu84a4t2r27xncxwy.png" alt="OpenAI Dashboard" width="800" height="316"&gt;&lt;/a&gt;&lt;br&gt;
After retrieving the key, store it and add the below line to your &lt;em&gt;.env&lt;/em&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OPENAI_API_KEY=&amp;lt;your_openAI_api_key&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remember also to replace the placeholder with your corresponding API Key.&lt;/p&gt;

&lt;h4&gt;
  
  
  Update the routes
&lt;/h4&gt;

&lt;p&gt;Run the command below in your terminal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="n"&gt;php&lt;/span&gt; &lt;span class="n"&gt;artisan&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;api&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will create a new file named &lt;em&gt;api.php&lt;/em&gt; in the &lt;em&gt;routes&lt;/em&gt; folder. Add the below &lt;code&gt;import&lt;/code&gt; statement at the beginning of the new file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Http\Controllers\VoiceController&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, update the file contents to include the following routes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/voice'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;VoiceController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'voiceInput'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/chat'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;VoiceController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'speechtoText'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here you are defining the routes for the voice and chat endpoints.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: In Laravel, API &lt;a href="https://laravel.com/docs/11.x/routing" rel="noopener noreferrer"&gt;routes&lt;/a&gt; defined in the api.php file have a prefix of &lt;code&gt;api/&lt;/code&gt;. This means the route defined as &lt;code&gt;/voice&lt;/code&gt; will be accessible at &lt;code&gt;/api/voice&lt;/code&gt;. The same applies to &lt;code&gt;/chat&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Create the controller
&lt;/h4&gt;

&lt;p&gt;The next step is to create a controller class that will house all the application logic. To create the controller, run the command below in your terminal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan make:controller VoiceController
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will create a new file called &lt;em&gt;VoiceController.php&lt;/em&gt; in the &lt;em&gt;app/Http/Controllers&lt;/em&gt; folder.&lt;br&gt;
Open the &lt;em&gt;VoiceController.php&lt;/em&gt; file and replace the content with the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Http\Controllers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Http\Request&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Twilio\TwiML\VoiceResponse&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;OpenAI\Laravel\Facades\OpenAI&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;VoiceController&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Controller&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nv"&gt;$response&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;VoiceResponse&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; 

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;voiceInput&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$gather&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;gather&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'input'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'speech'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'action'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'/api/chat'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="nv"&gt;$gather&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;say&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Hello, I am your personal assistant. How can I help you today?'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;speechtoText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
            &lt;span class="s1"&gt;'model'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'gpt-3.5-turbo'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'messages'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'role'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'user'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'content'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nc"&gt;SpeechResult&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="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;say&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;gather&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'input'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'speech'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'action'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'/api/chat'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above, the necessary imports required for the voice assistant are added. In the &lt;code&gt;voiceInput()&lt;/code&gt; function, the TwiML (Twilio Markup Language) &lt;code&gt;gather()&lt;/code&gt; method listens for the caller's input, and specifies the action to take on receiving it. Next, the TwiML &lt;code&gt;say()&lt;/code&gt; method is used to prompt the caller. The &lt;code&gt;gather()&lt;/code&gt; method converts the audio received into text and adds the transcribed audio to the &lt;code&gt;$request&lt;/code&gt; object using the parameter &lt;code&gt;speechResult&lt;/code&gt;. &lt;br&gt;
After gathering the user's input, the &lt;code&gt;$request&lt;/code&gt; object is sent as a POST request to the &lt;code&gt;/api/chat&lt;/code&gt; endpoint, corresponding to the &lt;code&gt;speechToText()&lt;/code&gt; function. The &lt;code&gt;speechToText()&lt;/code&gt; function retrieves the transcribed audio from the request using the &lt;code&gt;speechResult&lt;/code&gt; parameter and then forwards this transcribed audio to OpenAI Chat API for processing. &lt;br&gt;
OpenAI's Chat API requires a role parameter containing a message with a system role and content for the intended actions. The model must also be configured, it is set to &lt;code&gt;gpt-3.5-turbo&lt;/code&gt; in this tutorial. Finally, TwiML is used to return the response from OpenAI to the user in audio format.&lt;/p&gt;
&lt;h3&gt;
  
  
  Set up the Ngrok server
&lt;/h3&gt;

&lt;p&gt;To make your voice assistant accessible from the internet, you can use a tool called &lt;a href="https://ngrok.com/" rel="noopener noreferrer"&gt;Ngrok&lt;/a&gt;. Ngrok allows you to expose your local Laravel server to the internet.&lt;br&gt;
Run the command below in your project's root directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ngrok http 8000 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command creates a secure tunnel that allows you to access your local Laravel server running on port 8000 from a public URL provided by Ngrok.&lt;br&gt;
After executing the command, you should see the following in your terminal.&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%2F19c48g9arq4mhgh82x2o.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%2F19c48g9arq4mhgh82x2o.png" alt="Ngrok" width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy the Forwarding URL displayed here.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configure TwiML
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Create a New TwiML App
&lt;/h4&gt;

&lt;p&gt;Next, you need to create a new TwiML app. This is to ensure reusability across multiple phone numbers. You would be able to easily add the created TwiML app to any number in your Twilio account.&lt;br&gt;
In your &lt;a href="https://console.twilio.com/?_ga=2.5818416.288769677.1718382100-1858507213.1708114003&amp;amp;_gl=1*k7cuvg*_gcl_au*NzAwOTQ1MDkzLjE3MTU5NjkwMjI.*_ga*MTg1ODUwNzIxMy4xNzA4MTE0MDAz*_ga_RRP8K4M4F3*MTcxODM4MjA5OC44My4xLjE3MTgzODIxNDcuMC4wLjA." rel="noopener noreferrer"&gt;Twilio Console&lt;/a&gt;, navigate to &lt;strong&gt;Explore Products &amp;gt; Voice &amp;gt; Manage &amp;gt; TwiML apps&lt;/strong&gt;, and select &lt;strong&gt;Create new TwiML App&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%2Fiskvpxtem45dgge4etah.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%2Fiskvpxtem45dgge4etah.png" alt="twilio console" width="800" height="634"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, fill out the form, as in the screenshot above, and replace &lt;code&gt;&amp;lt;your_ngrok_address&amp;gt;&lt;/code&gt; with the Ngrok Forwarding URL you copied earlier, append "&lt;strong&gt;/api/voice&lt;/strong&gt;" to the end of it, and click &lt;strong&gt;Create&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Add TwiML to your number
&lt;/h4&gt;

&lt;p&gt;You must also add the created TwiML app to your phone number to ensure that Twilio executes your code when a call is made to/from the phone number.&lt;br&gt;
In the Twilio Console, navigate to &lt;strong&gt;Phone Numbers &amp;gt; Manage &amp;gt; Active numbers&lt;/strong&gt;, and click on your Twilio number.&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%2Fag1qsmd1bib268rpecwp.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%2Fag1qsmd1bib268rpecwp.png" alt="twilio console" width="800" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, in the &lt;strong&gt;Voice Configuration&lt;/strong&gt; section for your phone number, set &lt;strong&gt;Configure with&lt;/strong&gt; to &lt;strong&gt;TwiML App&lt;/strong&gt;, set &lt;strong&gt;TwiML App&lt;/strong&gt; to your TwiML app, and then click &lt;strong&gt;Save&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%2Fowc1bjnkl3z5tjux255i.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%2Fowc1bjnkl3z5tjux255i.png" alt="twilio console" width="800" height="268"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Test the application
&lt;/h3&gt;

&lt;p&gt;It’s finally time to see your AI-powered voice assistant in action! You can test it by calling your Twilio phone number from your verified phone number.&lt;br&gt;
When you successfully set up the system, a call will be made to your Twilio phone number. A voice prompt will ask for your request and the system will intelligently respond to it.&lt;/p&gt;

&lt;h3&gt;
  
  
  What’s next for building an AI-powered voice assistant with Twilio, Laravel, and OpenAI?
&lt;/h3&gt;

&lt;p&gt;Congratulations on successfully creating your very own AI-powered voice assistant using Twilio Programmable Voice and OpenAI! &lt;/p&gt;

&lt;p&gt;This comprehensive tutorial guided you through setting up the necessary tools, integrating Twilio and OpenAI, and building a voice assistant using the Laravel framework. Now, your voice assistant is ready to respond intelligently to any questions you might have.&lt;/p&gt;

&lt;p&gt;So, what's next on your journey? Here are a few suggestions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Integration with External APIs&lt;/strong&gt;: You can improve your voice assistant by integrating with external APIs. For example, you could integrate with e-commerce platforms to enable voice-based shopping experiences.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interaction History&lt;/strong&gt;: You can also implement a feature that allows your voice assistant to remember previous interactions, and extract context from it. This would allow your voice assistant to provide more tailored and relevant responses.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cheers to building and learning!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>openai</category>
      <category>laravel</category>
      <category>php</category>
    </item>
  </channel>
</rss>
