<?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: Abuka-Victor</title>
    <description>The latest articles on DEV Community by Abuka-Victor (@abukavictor).</description>
    <link>https://dev.to/abukavictor</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%2F881181%2F02bb7981-c9cd-4625-92f8-5d3aabe564b7.jpeg</url>
      <title>DEV Community: Abuka-Victor</title>
      <link>https://dev.to/abukavictor</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/abukavictor"/>
    <language>en</language>
    <item>
      <title>How to harden your VPS security</title>
      <dc:creator>Abuka-Victor</dc:creator>
      <pubDate>Sun, 24 Aug 2025 00:04:13 +0000</pubDate>
      <link>https://dev.to/abukavictor/how-to-harden-your-vps-security-2e0p</link>
      <guid>https://dev.to/abukavictor/how-to-harden-your-vps-security-2e0p</guid>
      <description>&lt;p&gt;This guide was originally posted on my personal blog titled &lt;a href="https://www.victorabuka.com/posts/ultimate-vps-security-for-dummies/" rel="noopener noreferrer"&gt;"Secure a VPS for Claude Code"&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Credit: Photo by &lt;a href="https://unsplash.com/@albertstoynov?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" rel="noopener noreferrer"&gt;Albert Stoynov&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/a-close-up-of-a-network-with-wires-connected-to-it-dyUp7WPu5q4?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I think everyone on Tech Twitter by now knows who Pieter Levels is. If you do not, you need to spend more time getting into tech twitter first then come back here and grab all the jokes. Google him or something. &lt;/p&gt;

&lt;p&gt;So this guy, Pieter Levels is championing an idea. The idea is dead simple. Deploy stuff on a cheap VPS and scale from there as you need to. Don't over engineer anything you build at least from the get go. Which seems like pretty obvious advice until you get into it and see that on average it's typical to use an EKS to release version 0.1 of a todo app.&lt;/p&gt;

&lt;p&gt;So a lot of people now have gone into the "raw dogging" tech stack which is simply a cheap VPS with claude code installed. Which works well for magic until you start spilling tea.&lt;/p&gt;

&lt;p&gt;This is the point of this guide. Think of it as VPS security for dummies. Any other security expert advice can build on top of this framework with minor tweaks here and there. Whenever you buy a new VPS just come here to tick all the boxes one by one to be sure you can sleep well at night knowing that no one would succeed with just brute forcing their way into your server.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This guide does not tell you how to not share passwords through get requests and other related mishaps that can come from the code itself. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Step 1 - Set a very long and stupid password.
&lt;/h2&gt;

&lt;p&gt;Make it at least 24 characters. Some providers allow you set it when you buy the VPS while others set it for you and email you the credentials. However it happened here is a very simple way to reset it and make it very long and stupid like I'm recommending. &lt;/p&gt;

&lt;p&gt;First you need to ssh into the server using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh root@&amp;lt;server_ip_address&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;some providers might use administrator instead of root. It's usually something like that though so whatever it is, find it and replace "root" with what you have.&lt;/p&gt;

&lt;p&gt;when you're in you need to run this:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Then you type the new password and confirm it. Alternatively you could disable password login entirely and use ssh keys* but if you have multiple servers then you have to think of a way to back up and manage all of your keys. If that's too much hassle just use password based auth jeje. ;)&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;With ssh keys a file is saved on your machine that lets your vps  basically perform that login handshake with only you. Anybody without that file cannot login to your vps at all.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Step 2 - Get the latest updates
&lt;/h2&gt;

&lt;p&gt;There would always be security patches and updates to make to software just like some other people will always find new ways to break into stuff. My guess here is that you have a linux based server, if you're still reading this then that's probably true. The package manager is apt. You can get the latest updates by running the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt upgrade &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The update part pulls the latest versions of all packages and services that your VPS uses and the upgrade part goes ahead to install those things. The -y flag just says yes to any question that might come up during the update and upgrade.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3 - Create a new user
&lt;/h2&gt;

&lt;p&gt;Most attacks would try to login to your vps as root, admin or something similar so lets fix that. The goal here is to disable root login so those attacks are completely useless. You need to use a very nonsense name and not something that's related to you in anyway. Some attackers might be people that know you if they've done a little social engineering so don't use anything related to you. For instance, I use Ojuelegba as my username. Lol, I don't, or do I, who knows?&lt;/p&gt;

&lt;p&gt;To add a user you use the adduser command like so&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;adduser &amp;lt;user_name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will ask you for password after this step and again the password should be long and stupid. Ideally above 24 characters. Remember the most secure thing online is stuff that is not online. Keep a paper under the bed of your cat with the passwords so that whoever hacks you must be a hacker and a burglar at the same time. Whoever can do those very well is free to steal from me. I won't even be mad.&lt;/p&gt;

&lt;p&gt;So next we need to add this new user to the sudo group so the user can get root permissions and still do root stuff even though you wouldn't be signing in as root (remember this is the goal). To do this run the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;usermod &lt;span class="nt"&gt;-aG&lt;/span&gt; &lt;span class="nb"&gt;sudo&lt;/span&gt; &amp;lt;user_name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can test by switching the user with su  or even logging out and back in with the new credentials. To get into root mode you can do&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;sudo&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You're going to need the password of the  you just created of course if that's what you signed in as. You can use the same method to provision permissions for your dev and whoever else needs access to your VPS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4 - Disable Root Login
&lt;/h2&gt;

&lt;p&gt;This is pretty straightforward we only need to edit a field in a config file. That's /etc/ssh/sshd_config you can use vi to open it like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vi /etc/ssh/sshd_config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At the bottom of the file you should see PermitRootLogin yes set this to no. use i to enable insert and when you're done esc then :x with the colons included. This saves your work in the file and closes it.&lt;/p&gt;

&lt;p&gt;You're almost done we have two more steps to go.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5 - Install and activate Fail2Ban
&lt;/h2&gt;

&lt;p&gt;This helps you to lock out people trying to gain unauthorised access for some time (could be 2 years or 2 seconds - up to you). It puts their ip in some kind of jail and further attempts are just ignored.&lt;/p&gt;

&lt;p&gt;Install it with&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;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;fail2ban &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that's done you'd need config file to get it running but no worries the installation comes with a sample config file that we can tweak and use. Just copy the sample to the main file like so&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;sudo cp&lt;/span&gt; /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then open the file up with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vi /etc/fail2ban/jail.local
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's a pretty long file and it has a lot of comments that can let you know exactly what setting you're looking at but we're not doing too much here. What you're looking for is two things - bantime and findtime. &lt;/p&gt;

&lt;p&gt;The bantime is pretty self explanatory, this sets how long that ip is banned. The findtime on the other hand is the retry window. So basically if somebody tries your password a certain number of times consecutively within a certain time window then it bans the ip. This time window is the findtime. The certain number of times is the maxretry value, you can also set that if you want.&lt;/p&gt;

&lt;p&gt;So set these values to what seems like a reasonable punishment to you. Note that the findtime needs to be a large enough window like 10h or so. If it's really small like 3s then I can just wait 3s after every try and I would never be banned. Also be careful not to test this out carelessly cuz you might be banned from your own server for say like 2 years.&lt;/p&gt;

&lt;p&gt;So now that we're done with the config lets start the fail2ban engine with&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;sudo &lt;/span&gt;systemctl start fail2ban
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;fail2ban
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fail2ban is now active on your VPS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6 - Setup a firewall
&lt;/h2&gt;

&lt;p&gt;Your VPS is exposed to the internet (well and to itself too) through ports. Now you don't want to have too many of these holes open because somebody/bot will potentially exploit one of them soon enough. Now it might be a bit complicated to track this but the easy way to do this is to setup a firewall. There are a number of them but I'm basing this on UFW. &lt;/p&gt;

&lt;p&gt;You probably have it installed already if you're on an ubuntu distro but it doesn't hurt to run the install with&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;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;ufw
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you have it installed it'll say so, if not it'll install it.&lt;/p&gt;

&lt;p&gt;Now you want the bare minimum number of ports exposed to the internet. My current list of bare minimum ports has just &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ssh - port 22&lt;/li&gt;
&lt;li&gt;http/https - port 80/ port 443 resp.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So first to setup our rules we want to deny all incoming connections and allow all outgoing connection with&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;sudo &lt;/span&gt;ufw default deny incoming
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw default allow outgoing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then allow the ssh and http/https ports with&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;sudo &lt;/span&gt;ufw allow 22
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow 80
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow 443
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For ssh, http and https respectively.&lt;/p&gt;

&lt;p&gt;Finally we need to enable our firewall that we've setup. But first we check the rules we've put in place just to confirm&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;sudo &lt;/span&gt;ufw status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It should show the ports 22, 80 and 443 as allowed. Then we're good to go to enable the firewall with&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;sudo &lt;/span&gt;ufw &lt;span class="nb"&gt;enable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Congratulations
&lt;/h2&gt;

&lt;p&gt;You have just completed the bare minimum of server security. If you made it this far thank you very much for reading.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>cybersecurity</category>
      <category>devops</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Setup OpenGL on Mx Mac with C and not C++ - Sanity Checklist</title>
      <dc:creator>Abuka-Victor</dc:creator>
      <pubDate>Thu, 07 Aug 2025 23:42:10 +0000</pubDate>
      <link>https://dev.to/abukavictor/setup-opengl-on-mx-mac-with-c-and-not-c-sanity-checklist-1f0n</link>
      <guid>https://dev.to/abukavictor/setup-opengl-on-mx-mac-with-c-and-not-c-sanity-checklist-1f0n</guid>
      <description>&lt;p&gt;I have struggled with finding resources for this today and all the ones I saw were tailored to C++ not C. Somehow I have finally found a way to get a window displayed with just C. &lt;/p&gt;

&lt;p&gt;The thing that unlocked it for me is that I realised the necessary libraries come with Xcode tools so if you have that installed that is half your problems solved already. &lt;/p&gt;

&lt;p&gt;From what I saw on forums online, using GLFW is better than using GLUT for some reason but that's another installation step cuz then you have to use homebrew to install GLFW and use CMAKE to link the library to your code. So in this guide we'd just stick to GLUT also because I don't know jack about this yet, I'm just trying to find my way and I don't really know why GLFW is better than GLUT for myself yet apart from that someone on the internet said so.&lt;/p&gt;

&lt;p&gt;This checklist guides you through setting up a basic OpenGL program using Visual Studio Code so you don't pull out your hair. Towards the end I talk about fixes for some errors I face.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Xcode: Install from the Mac App Store.&lt;/li&gt;
&lt;li&gt;Command Line Tools: Run xcode-select --install in Terminal.&lt;/li&gt;
&lt;li&gt;Visual Studio Code: Installed with C/C++ extension.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Checklist
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Create Project Directory
&lt;/h3&gt;

&lt;p&gt;Open VS Code, create a new folder, and add a file named main.c.&lt;/p&gt;

&lt;h3&gt;
  
  
  Write Basic OpenGL/GLUT Code
&lt;/h3&gt;

&lt;p&gt;Use correct headers for macOS (, ) and&lt;br&gt;
include a display callback to avoid "no display callback" errors. Just copy this and paste it in your file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;OpenGL/gl.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;GLUT/glut.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;display&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="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;glClearColor&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="mi"&gt;0&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="mi"&gt;0&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="mi"&gt;0&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;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;glClear&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GL_COLOR_BUFFER_BIT&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;glFlush&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;glutInit&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;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;glutInitDisplayMode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GLUT_SINGLE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;GLUT_RGB&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;glutInitWindowSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;glutCreateWindow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello World"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;glutDisplayFunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;display&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;glutMainLoop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Compile with Correct Flags
&lt;/h3&gt;

&lt;p&gt;In the terminal, navigate to your project folder and compile with OpenGL and GLUT frameworks for arm64 (Your Mx processor). &lt;/p&gt;

&lt;p&gt;If you do not do this it'll use Intel when linking and you'll get an error saying symbol not found for arm64.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gcc &lt;span class="nt"&gt;-o&lt;/span&gt; main main.c &lt;span class="nt"&gt;-framework&lt;/span&gt; OpenGL &lt;span class="nt"&gt;-framework&lt;/span&gt; GLUT &lt;span class="nt"&gt;-arch&lt;/span&gt; arm64
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the Program&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Expect a 500x500 black window. If it closes immediately, ensure glutMainLoop() is included.&lt;/p&gt;

&lt;h3&gt;
  
  
  Set Up VS Code Build Task (Optional)
&lt;/h3&gt;

&lt;p&gt;I did this because I didn't want to have to type that long code every time I changed something and wanted to compile.&lt;/p&gt;

&lt;p&gt;Just create a .vscode folder and then inside a tasks.json file and paste the following code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"tasks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"label"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"shell"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"gcc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"-o"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"main.c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"-framework"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"OpenGL"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"-framework"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"GLUT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"-arch"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"arm64"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"group"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"kind"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"isDefault"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"problemMatcher"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"$gcc"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Press Cmd+Shift+B to build.&lt;/p&gt;

&lt;h2&gt;
  
  
  Errors I faced
&lt;/h2&gt;

&lt;h3&gt;
  
  
  "No such file or directory"
&lt;/h3&gt;

&lt;p&gt;Use &lt;code&gt;&amp;lt;OpenGL/gl.h&amp;gt;&lt;/code&gt;, not &lt;code&gt;&amp;lt;GL/gl.h&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  "Undefined symbols"
&lt;/h3&gt;

&lt;p&gt;Ensure that -framework OpenGL -framework GLUT is in the compile command.&lt;/p&gt;

&lt;h3&gt;
  
  
  "GLUT Fatal Error: redisplay needed"
&lt;/h3&gt;

&lt;p&gt;Add glutDisplayFunc(display) before glutMainLoop().&lt;/p&gt;

&lt;h2&gt;
  
  
  Suppress Deprecation Warnings (Optional)
&lt;/h2&gt;

&lt;p&gt;Oh yeah so something is definitely deprecated. I think its OpenGL on Mac but according to my findings it still supports OpenGL 4.1. I just don't think Apple wants to go beyond that or actively even maintain the 4.1 support.&lt;/p&gt;

&lt;p&gt;The deprecation warnings were getting annoying so you can shut them up by adding &lt;code&gt;-Wno-deprecated-declarations&lt;/code&gt; to the compile command like so&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gcc &lt;span class="nt"&gt;-o&lt;/span&gt; main main.c &lt;span class="nt"&gt;-framework&lt;/span&gt; OpenGL &lt;span class="nt"&gt;-framework&lt;/span&gt; GLUT &lt;span class="nt"&gt;-arch&lt;/span&gt; arm64 &lt;span class="nt"&gt;-Wno-deprecated-declarations&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or &lt;code&gt;#define GL_SILENCE_DEPRECATION&lt;/code&gt; before headers in main.c file&lt;/p&gt;

&lt;p&gt;This setup gets you a working OpenGL environment in C not C++. Happy Hacking! If you run into any problems with this you can drop it in the comments. Feel free to reach out on X @abukaofficial.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>c</category>
      <category>opengl</category>
      <category>graphicsprogramming</category>
    </item>
    <item>
      <title>Add AI features to your application with Genkit</title>
      <dc:creator>Abuka-Victor</dc:creator>
      <pubDate>Sat, 02 Aug 2025 16:44:49 +0000</pubDate>
      <link>https://dev.to/abukavictor/add-ai-features-to-your-application-with-genkit-28gn</link>
      <guid>https://dev.to/abukavictor/add-ai-features-to-your-application-with-genkit-28gn</guid>
      <description>&lt;p&gt;This article is adapted from my session at Google Developer Group's Build With AI event in the University of Ibadan where I introduced attendees to Genkit and talked on some of the possibilities of building with Genkit.&lt;/p&gt;

&lt;p&gt;In this article we talk about the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is Genkit?&lt;/li&gt;
&lt;li&gt;Getting Started&lt;/li&gt;
&lt;li&gt;Workflows&lt;/li&gt;
&lt;li&gt;Developer UI&lt;/li&gt;
&lt;li&gt;Tool Calling and RAG&lt;/li&gt;
&lt;li&gt;Deployments&lt;/li&gt;
&lt;li&gt;Real Life Challenge For You To Try&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Genkit is an open source framework that allows developers to build AI powered applications. It does this by providing developers an SDK complete with testing and debugging tools that empowers you to interact with any AI model from supported providers.&lt;/p&gt;

&lt;p&gt;Typically to use ChatGPT in your application, you would have to read through the relevant documentation, create an api key, and connect to the relevant endpoints for what you need to get done. If you wanted to connect to ChatGPT and Claude you'd do the same process for both. What about ChatGPT, Claude and Gemini?&lt;/p&gt;

&lt;p&gt;I think you can already see where I'm going with this. Genkit unifies this experience by providing you a centralised interface to interact with as many of these models as you have a use case for.&lt;/p&gt;

&lt;p&gt;Right now, Genkit has a stable release for everything Node.js but at the time I'm writing this, it's in beta for Go and in alpha for Python.&lt;/p&gt;

&lt;p&gt;Genkit is very powerful and we would not touch on every single thing it can do but I’ll do my best to give you a pretty solid idea. Coming up is an actual application I built from scratch and integrated with Genkit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;For this article I would be using Javascript. You can setup a simple application with a package.json and one javascript file. To get started with Genkit in your javascript based application, you first of all need to install it with the following command&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;genkit @genkit-ai/googleai
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The main engine you need is genkit. We installed @genkit-ai/googleai as well because we want to use Gemini. If we wanted to use ChatGPT we would have installed genkitx-openai. So whatever provider you want to use, you can find the correct package to install (or maybe write your own plugin 😀 - yes Genkit can be extended).&lt;/p&gt;

&lt;p&gt;Then in your javascript file you can import the genkit engine and the provider you want to use and then register the provider and the models with the engine. It looks something like this&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;genkit&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="s2"&gt;genkit&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;googleAI&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="s2"&gt;@genkit-ai/googleai&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;ai&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;genkit&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;googleAI&lt;/span&gt;&lt;span class="p"&gt;()],&lt;/span&gt;
      &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;googleAI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gemini-2.0-flash&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The provider is basically the company that created the different models, like Google, OpenAI, etc. Then model examples include gemini 2.5 pro, gemini 2.0 flash (like in this case), o3 mini, etc.&lt;/p&gt;

&lt;p&gt;The most relatable use case I can think of is generating text from a prompt so lets see how that can be done. Building on our setup we can add 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;async&lt;/span&gt; &lt;span class="kd"&gt;function&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello, Gemini! You're live at Build with AI at Opolo Hub University of Ibadan.&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now when we run this code by simply doing node index.js or npm run dev. We can see something like the following output&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Hello! It&lt;span class="se"&gt;\'&lt;/span&gt;s fantastic to be here, live at Build with AI at Opolo Hub, University of Ibadan! The energy from Nigeria&lt;span class="se"&gt;\'&lt;/span&gt;s tech community is always inspiring.

What can I &lt;span class="nb"&gt;help &lt;/span&gt;you with today? Are you looking to dive into some AI concepts, discuss project ideas, or perhaps brainstorm some innovative applications? Let&lt;span class="se"&gt;\'&lt;/span&gt;s build something amazing together!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You also have the option of streaming this text to the user so the responses come out in chunks just like it happens on the websites for these models.&lt;/p&gt;

&lt;p&gt;Right off the bat, you can see how much simpler this is. If you wanted to get a response from ChatGPT instead you just swap out the models. You can even register multiple models and specify the model you want to use in the generate function for each function call.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;NOTE: You’ll need API keys in the .env file for each provider. Check the Genkit documentation for the exact key names (e.g., GEMINI_API_KEY for Google AI).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;According to the docs there are names you should call each api key for each provider so do well to check that out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Workflows
&lt;/h2&gt;

&lt;p&gt;Genkit also allows you to define pretty complex workflows. In order to get how this works, think of AI agents or N8N automations. Basically, the result of one task cascades into another task as its input, and after a number of flows, you get an output.&lt;/p&gt;

&lt;p&gt;For example, imagine a recipe generator: a user uploads an image of a meal, a model analyzes ingredients, and another crafts a step-by-step recipe—perfect for food app developers. In order to use this feature, you first need to define the workflow. You can define workflows one by one and call them in order, or tie them into one giant workflow executed at once.&lt;/p&gt;

&lt;p&gt;In defining workflows, you might want to use an input and output schema, like an API response, so each workflow knows what it’s handling. Genkit supports this with Zod. Let’s define a simple workflow that suggests a social game for an event based on its theme. Add this to your code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;genkit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;z&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;genkit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// z here comes from zod&lt;/span&gt;

&lt;span class="c1"&gt;// Define the workflow&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;eventSuggestionFlow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;defineFlow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;eventSuggestionFlow&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;inputSchema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&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="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="na"&gt;outputSchema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;eventItem&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&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;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;theme&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;googleAI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gemini-2.0-flash&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Give a suggestion for a playable game that can be done at a &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; themed event.`&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;eventItem&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Call the workflow&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;eventItem&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;eventSuggestionFlow&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Halloween&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;eventItem&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Of course, in your app, you could display this to users or send it via email, depending on your needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Developer UI
&lt;/h2&gt;

&lt;p&gt;The Developer UI is like the web browser console for your AI workflows. You can visualise in realtime all of the steps and processes that happen in the workflow. You can pause it, debug any inputs or outputs you observe from any workflow etc. Its a versatile observability tool for everything you have used Genkit to do in your application.&lt;/p&gt;

&lt;p&gt;In order to use it you would have to install the genkit cli with the following command&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; &lt;span class="nt"&gt;-g&lt;/span&gt; genkit-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you can start the Developer UI alongside your code with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx genkit start &lt;span class="nt"&gt;--&lt;/span&gt; npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Run&lt;/p&gt;


&lt;pre class="highlight shell"&gt;&lt;code&gt;npx genkit start &lt;span class="nt"&gt;--&lt;/span&gt; node index.js
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;if no dev script is defined.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;if you just want to start the Developer UI alone you can do&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx genkit start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since genkit-cli is installed globally, you don't need npx so try it without it first.&lt;/p&gt;

&lt;p&gt;You can also run the workflows in your code individually straight from the cli. Let's run our eventSuggestionFlow for example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx genkit flow:run eventSuggestionFlow &lt;span class="s1"&gt;'{"theme": "Workplace"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Tool Calling and RAG
&lt;/h2&gt;

&lt;p&gt;In my opinion these are the most exciting features of genkit and coupled with workflows you are literally unstoppable. Genkit allows you to call external tools like other existing apis in order to fetch data to be processed from the user prompt and the given context. It can also interact with documents for RAG purposes by providing abstractions for Indexers, Embedders and Retrievers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deployments
&lt;/h2&gt;

&lt;p&gt;Aside integrating your workflow in an existing app or building an app around your AI functions, you can also deploy your workflow as a standalone agent on Firebase or on any platform that supports an Node/Express app deployment. Then in your client application you can consume that workflow kind of like an api with the runflow function imported from "genkit/beta/client".&lt;/p&gt;

&lt;h2&gt;
  
  
  Real Life Challenge For You To Try
&lt;/h2&gt;

&lt;p&gt;In order to test Genkit AI in a real life application we would be building Chatty. &lt;/p&gt;

&lt;p&gt;Note: This project is adapted from an existing chat application to be used as a practical base for educational purposes. I extend my gratitude to the original creator for their work, which provides a solid foundation for further development and learning. You can find the original video from youtube here &lt;a href="https://www.youtube.com/watch?v=ntKkVrQqBYY&amp;amp;t=7340s" rel="noopener noreferrer"&gt;Codesistency&lt;/a&gt;. &lt;a href="https://github.com/burakorkmez/fullstack-chat-app" rel="noopener noreferrer"&gt;Github Repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The original project is written in plain javascript but this version has included Typescript support on the frontend. Please do check out the Codesistency Youtube channel for other awesome tutorials. The starter files for this tutorial is found &lt;a href="https://linkly.link/2CNBP" rel="noopener noreferrer"&gt; here (Chatty Starter Files)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The project is setup as a mono repo and serves the frontend from the backend. After cloning or downloading the project you should see the backend and frontend with the following structures.&lt;/p&gt;

&lt;p&gt;Backend Structure&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;CHATTY/
├── backend/
│   ├── node_modules/
│   └── src/
│       ├── controllers/
│       ├── lib/
│       ├── middleware/
│       ├── models/
│       ├── routes/
│       ├── index.js
│       └── .env
├── .gitignore
├── package-lock.json
└── package.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Frontend Structure&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;frontend/
├── dist/
├── node_modules/
├── public/
├── src/
│   ├── components/
│   ├── constants/
│   ├── lib/
│   ├── pages/
│   ├── store/
│   ├── App.tsx
│   ├── index.css
│   ├── main.tsx
│   └── vite-env.d.ts
├── .env
├── .gitignore
├── custom.d.ts
├── eslint.config.js
├── index.html
├── package-lock.json
├── package.json
├── postcss.config.js
├── README.md
├── tailwind.config.js
├── tsconfig.app.json
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The .env files were not pushed to Github but in the frontend repo we have&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;REACT_APP_API_BASE_URL="http://localhost:8080/api"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and for the backend we have&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MONGODB_URI=&amp;lt;YOUR_MONGO_URI&amp;gt;
PORT=8080
JWT_SECRET=&amp;lt;SOME_SECRET_STRING&amp;gt;
NODE_ENV="development"
CLOUDINARY_CLOUD_NAME=&amp;lt;YOUR_CLOUDINARY_NAME&amp;gt;
CLOUDINARY_API_KEY=&amp;lt;YOUR_CLOUDINARY_API_KEY&amp;gt;
CLOUDINARY_API_SECRET=&amp;lt;YOUR_CLOUDINARY_API_SECRET&amp;gt;
GEMINI_API_KEY=&amp;lt;YOUR_GEMININ_API_KEY&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Caution: Replace placeholders (e.g., ) with actual values from your providers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can run the application from the root folder with&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Our goal is to make a chatbot by adding Genkit AI features to this chat application. Kind of like Meta AI on Whatsapp. So in order to do this we begin by installing the genkit engine again here on the backend.&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;backend/
npm &lt;span class="nb"&gt;install &lt;/span&gt;genkit @genkit-ai/googleai
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The approach we want to take is to create a model for the chatbot messages and write endpoints that the frontend can hit to send and receive messages from the AI model we setup. So the steps for you to try are as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a chatbot model for the chats between the user and the chatbot.&lt;/li&gt;
&lt;li&gt;Create an ai.js file in the lib folder, setup genkit here and write simple functions that can take the user input in text and return the ai output text.&lt;/li&gt;
&lt;li&gt;Create endpoints to getChatbotMessages and sendChatBotMessage.&lt;/li&gt;
&lt;li&gt;Create ChatbotContainer and ChatbotMessageInput on the frontend just like we have for normal users. (This is where the user will interact with the chatbot by calling the chatbot get and send message api's)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can make your solution as simple or as complex as you choose. My own solution for this can be found in the "final" branch of the starter repo or with &lt;a href="https://linkly.link/2CNCv" rel="noopener noreferrer"&gt;this link (Chatty Final)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feel free to reach out to tag me to look through your solution through &lt;a href="https://x.com/abukaofficial" rel="noopener noreferrer"&gt;my X&lt;/a&gt; and in the comment section as well.&lt;/p&gt;

&lt;p&gt;If you read this far. Thank you very much for your time and attention. I hope you have learned something today.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Understanding Caching in Software Engineering: Technical Concepts Made Easy Series</title>
      <dc:creator>Abuka-Victor</dc:creator>
      <pubDate>Tue, 28 Mar 2023 12:44:13 +0000</pubDate>
      <link>https://dev.to/abukavictor/understanding-caching-in-software-engineering-technical-concepts-made-easy-series-530p</link>
      <guid>https://dev.to/abukavictor/understanding-caching-in-software-engineering-technical-concepts-made-easy-series-530p</guid>
      <description>&lt;p&gt;Have you ever wondered why some websites and applications load so much faster than others? The answer lies in caching, a technique used in software engineering to speed up the delivery of data and resources. In this article, we'll explore caching in detail, with a focus on the techniques used in caching data within a computer system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Caching?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Caching is the process of storing frequently accessed data in a temporary storage location called a cache. When a user requests data or resources, the system checks the cache first to see if it's already there. If it is, the data is served from the cache, eliminating the need to retrieve it from the original source. This results in faster load times and improved performance.&lt;/p&gt;

&lt;p&gt;To visualise this, imagine you're a librarian and somebody comes to you asking for a popular book. Instead of going to the shelves and retrieving the book every time someone requests it, you keep a few copies behind the counter and when someone asks for the book, you check behind the counter first to see if it's available. If it is, you hand it over, saving time and effort.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Types of Caching&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are  different ways to classify caching. One way you can classify them is based on whether the data is saved on the client-side or on the server-side: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;client-side and server-side caching.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Client-side caching is when the cache is stored on the user's device, such as in their web browser. Often used for static resources like images, CSS, and JavaScript files. Server-side caching is when the cache is stored on the server. Used for dynamic data that changes frequently, such as database queries or API responses.&lt;/p&gt;

&lt;p&gt;Furthermore, another way to classify caching is based on the technique used when caching. In order words, here we are interested in how exactly the caching is done. In this article, we will discuss three major types. They are spatial caching, temporal caching and distributed caching.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Spatial Caching&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When I teach I usually refer to this as regional caching because it feels more in line with the meaning. Here a section of related data is cached. I know that doesn’t sound very explanatory but lets look at it this way. &lt;/p&gt;

&lt;p&gt;Imagine I run a big store in Nigeria called WindowMart, we sell all sorts of things. We also happen to have good data analysts and from our data we found that customers from places like Ondo, Osun and Ogun buy farming tools the most. Hence we made a decision to supply our branches in those regions with more things like treated seeds and fertilisers. &lt;/p&gt;

&lt;p&gt;Let’s bring this to our computer system, so basically when Mr Code goes to fetch info from the database he looks around him and says “hmm I think they’ll probably need these too” and he takes it into the cache. In other words, a section of related data is cached.&lt;/p&gt;

&lt;p&gt;So how is this applicable to building the fast and performant systems you intend to build? Good question. Storing related data in CDNs (Content Delivery Network) can reduce latency and improve the performance of your product. Note that although this form of caching is very useful, it is mostly data driven.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Temporal Caching&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This type of caching involves storing data or resources for a specific period of time. For example, a web browser may cache a webpage for a few hours or days, so that it loads faster the next time the user visits it. This caching is based on how often those pieces of data are used. Temporal caching is usually implemented in levels with the highest level containing pieces of data that are the most frequently used and the lowest level containing those that are less frequently requested. It goes without saying that the higher levels will be the fastest in terms of access time and the lower levels will take longer time to access the data contained. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Distributed Caching&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Just as the name implies, this type of cache exactly mirrors the database. It involves storing data or resources in multiple caches, which are spread across different locations or servers. This allows the system to handle a larger volume of requests and reduces the risk of a single point of failure.&lt;/p&gt;

&lt;p&gt;There are a lot of different implementations of a distributed cache. Amazon does it one way and Microsoft does it another. One implementation is called the write-through method. In this method, data is written through the cache to the database. To put it simply, you write data to the cache first and then write the same data to the database. Of course you will need to use your ninja software engineering skills to determine a way to make these transactions ACID. &lt;/p&gt;

&lt;p&gt;Conclusively, caching is an essential technique for improving the performance of websites and applications. By storing frequently accessed data and resources in a cache, the system can deliver them faster, resulting in a better user experience. I really hope this article has helped you understand caching in software engineering. Whether it's spatial, temporal or distributed caching, choose a technique that fits your problem so your software can perform at its best. It is also very possible to have a hybrid of these different techniques. That’s all for now, till next time. Happy Hacking!&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>tutorial</category>
      <category>programming</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Understanding the React Context API</title>
      <dc:creator>Abuka-Victor</dc:creator>
      <pubDate>Tue, 28 Feb 2023 16:20:55 +0000</pubDate>
      <link>https://dev.to/abukavictor/understanding-the-react-context-api-2gg0</link>
      <guid>https://dev.to/abukavictor/understanding-the-react-context-api-2gg0</guid>
      <description>&lt;p&gt;The React Context API allows you to have a general data store for state management. In simple terms it acts as a bank of states that components can directly access. &lt;/p&gt;

&lt;p&gt;Now, how might this be useful. We know that React lets you split up your application into components and some of these components are subject to conditional rendering. That is, they show different stuff based on the current state of the application. By “state”, I mean any variable piece of information that can be monitored in your application, such as whether a user is signed in or not, the number of likes on a post, etc stuff like that. Now, depending on the logical arrangement of your components, some components may need to react to state changes of other components that a very far away from them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7DLinjn---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0ebdlqz637z5omnyjmem.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7DLinjn---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0ebdlqz637z5omnyjmem.png" alt="Component Logic Hierarchy" width="880" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To explain this, I have this diagram above. Root is of course the root component and A and B are children of it. C, D and E are children of A and G,H and I are children of B. This is our imaginary setup for our company. If component C is supposed to react to a state change in component H, how do you think that can happen. Without the context API, we could create the state in the Root component and pass it down to H using props, and also pass it down to C using props. That way when we setState() in component H then a re-render fires in component C. This is called &lt;strong&gt;Prop Drilling&lt;/strong&gt; and it will work for what we have currently but imagine you have thousands of components just like C and H, just thinking about how messy it will be to do it this way gives me goosebumps.&lt;/p&gt;

&lt;p&gt;So what is the native solution?, you guessed it, The React Context API. I said native because tools like Redux and Mobx do the same thing only that you have to install them first. But They help you manage state better by providing sort of a central data store that all components have access to. So how exactly does it work and how do you set it up. Trust me this is the easy part.&lt;/p&gt;

&lt;p&gt;When I work, I like to put my contexts in a context folder just like you keep components or screens in different folders. So first of all create a new folder called “contexts”. You can create different data stores for different things. One to store user details from authentication, another to store maybe a users cart or you can really just make one huge data store for everything, that’s entirely up to you. In this folder, create a file called “user.context.js”, this is just an example, you can name it whatever you want but I want to create a context that stores user data so it makes sense for me to name it like so. In this folder let's have the code below.&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;createContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&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;react&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createContext&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;span class="na"&gt;currentUser&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;setCurrentUser&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="kc"&gt;null&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 only imports the createContext function that we can use to initialise a data store, we will make use of useState later. Just like useState, we initialise it with some default or starting values which is null. Next We add these.&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;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;UserProvider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;currentUser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCurrentUser&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&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;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;currentUser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCurrentUser&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;userContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Provider&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/userContext.Provider&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;This creates a component that be wrapped around the root component. Any child of this component will be able to access the data we have initialised. As you must have guessed, react context leverages on useState to function. The last step is to wrap this provider round our app component in index.js. This is only the setup.&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;UserProvider&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;./contexts/user.context&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

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

&lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;render&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;UserProvider&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/UserProvider&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To use the data we have in store in our component we use the useContext hook like so.&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;useContext&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;react&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;userContext&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;./../contexts/user.context&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="nx"&gt;SomeComponent&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;currentUser&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userContext&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;Ah yes, we can decide to only collect what we need from the context. In some components we may need the setCurrentUser function in some others we may need both. &lt;/p&gt;

&lt;p&gt;There you have it folks. React Context in simple terms. If you enjoyed reading this article and you want to understand more stuff like these please let me know in the comment section, including what you would love to learn next. If you spot any errors, please I would love to know as well.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How the web works</title>
      <dc:creator>Abuka-Victor</dc:creator>
      <pubDate>Sun, 09 Oct 2022 21:01:29 +0000</pubDate>
      <link>https://dev.to/abukavictor/how-the-web-works-359i</link>
      <guid>https://dev.to/abukavictor/how-the-web-works-359i</guid>
      <description>&lt;p&gt;&lt;strong&gt;TLDR&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Whenever we send a request to a website like Unsplash, our browser sends a request to a DNS server, this server responds to our browser with an IP address, this IP address points to a load balancing server owned by Unsplash. When our request hits the server, our session is immediately encrypted with the SSL certificate. The load balancer forwards our request to the freest server it can find in Unsplash’s pool of servers. The web server then reads our request and consults the database or the application server where appropriate in order to generate a response which is then sent back to our browser and we can then see the Unsplash page.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Main&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you have ever wondered what really happens when we type a url in our browser and press enter, then you are in luck because you are about to become a digital surgeon. Join me, let’s dissect the web. Spatula please!&lt;/p&gt;

&lt;p&gt;From the foundations of the earth, computers and computing has always been a merry game of numbers. This, as far as I know, is the only thing that is set in stone. Even Thanos cannot change that. So how exactly do we crunch numbers that give us websites like Youtube and Dev.to?&lt;/p&gt;

&lt;p&gt;To understand that, you must first understand that not all computers are the same. If I decide to classify computers based on the type of work that they do, I can say that some of them are &lt;strong&gt;SERVERS&lt;/strong&gt; while others are &lt;strong&gt;CLIENTS&lt;/strong&gt;.  A server is a special type of computer that manages resources. &lt;/p&gt;

&lt;p&gt;Think of it this way. I work at a large company and in the office we have only one printer. Whenever I have something to print and go down to the printing room I will most likely meet someone there. It rarely ever happens that I am the first down there. On a particular day, I wanted to print just one page of a document and when I got there I met someone from advertising who was printing 1000 pages of fliers. You will find that waiting for someone to print 1000 pages before you print just a page is not a pleasant experience. On another day, I had a squabble with a colleague who claimed she was there before me. The printer easily became a source of conflict in the office. Then the company decided to hire someone to control printer usage. Now whenever I want to print something, I would send a request to this printer receptionist, she handles it and gets my documents to me. If I was a computer, this printer receptionist is my server and I am her client. A server manages a resource, the printer receptionist managed the office printer. &lt;/p&gt;

&lt;p&gt;Great! Now we know what servers are. Each server, like a house, has an address. And this address is a number. All numbers. It looks sort of like this - 8.8.8.8. The people living in that house are the files that you need to access. It could be any type of file, from the video files on Youtube to the pictures on Unsplash. If I was communicating with a friend via email, I have to know his email address and if he wanted to send a message back to me, he needs to know mine. Same goes for computers. If I wanted to get pictures from Unsplash, I need to know the address of the server and for Unsplash to reply me with the pictures I need, Unsplash server needs to know my computer address. Yes, your computer has an address too. This address is known as IP address and what I just described is a very basic version of the popular request and response pattern. You are now familiar with a lot of things, well done. But that’s not all, there was a problem with this pattern.&lt;/p&gt;

&lt;p&gt;A lot of intelligent computer people found that human beings would rarely remember the addresses of the servers they wanted to use so they came up with some sort of phonebook for the web. So humans can look up say the address of Bing or Youtube. This phonebook is called a Domain Name System or DNS. This is the first step. When you type a url in your browser and press enter, the browser immediately goes to DNS to check what address this url translates to and then sends a request to that address.&lt;/p&gt;

&lt;p&gt;If you are still here congratulations, I feel we are now close enough for me to tell you my life secrets. I might have told a bit of a lie, it’s a very small lie. I may have led you to believe that one server stores the data that the client requests and handles everything involved in sending a response. This is not true. Whenever you interact with the web you interact with whole systems of computers, there is a lot of software and hardware engineering magic that happens under the hood. Some of which I will reveal to you now because we are friends.&lt;/p&gt;

&lt;p&gt;This first one may come as a shocker but stay with me, I promise I won’t lead you astray again. A server can be either software or hardware. When it is hardware, then it is a physical computer somewhere, but when it is a software then it is a program that helps to “manage and serve” some content. Examples are Apache and Nginx. Another twist to this story, is that there are different types of servers. Apache and Nginx are web servers. There are also application servers, database servers, mail servers, and so much more. From the name of the server you can already guess what resource it manages. For this scope of this operation, I will only tamper with your knowledge on web servers, application servers and database servers. I will leave your other organs as they are. &lt;/p&gt;

&lt;p&gt;Web servers help us manage access to static files. There are some websites we term as static and others we term as dynamic. This is the basic distinction between the two, static sites are those sites you go to and you see the same thing that anybody who goes to the site will see. There is no unique feed for you as a user. Dynamic sites do just that, when you go to a dynamic site, you have content that is user-centric, tailored to just you. Anybody who goes to that site wouldn’t see the same kind of things you would see. E.g on Facebook, my timeline is based on the type of friends I keep. We do not all have the same friends so we would all see different things on our Facebook timelines. Now those files that are accessed on a static website are called static files, they do not change. A web server handles just that. &lt;/p&gt;

&lt;p&gt;Application server on the other hand helps us to apply logic to our user/client requests. For example, if somebody posts something on Facebook, I cannot delete that post because I do not have the permissions to. If somehow by witchcraft, I send a request to Facebook to delete my friends post, the application server intercepts the request and checks if I am the one who made the post in question. It does the necessary extra checks and draws a conclusion that it will not allow me to delete my friends post. This is the work of the application server. They help implement the business logic that makes up dynamic websites. So you rest assured that Youtube has an application server since it is a dynamic site. A site can have both a web server and application server. If the web server receives a request it cannot handle it typically passes it on to the application server to handle it.&lt;/p&gt;

&lt;p&gt;A database server just as the name implies, manages data resources. These data assets could be our user details like username, password, emails, etc, it could also be data to keep track of files that the user has uploaded or even metrics about usage. It could be any type of data. All these work together to make our websites like Youtube and Unsplash possible.&lt;/p&gt;

&lt;p&gt;Now we have entered the second step, when we type a url and press enter, the request goes to the DNS server, comes back to our browser as an IP address and then from our browser it goes out to a web server at that particular address which may communicate with an application server and even a database before getting us back a response. If you understand this, you have come a long way, but there is still yet another problem to solve.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eVuCHs9Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1d8yjjatsev013cg42yp.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eVuCHs9Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1d8yjjatsev013cg42yp.jpeg" alt="Basic web infra" width="290" height="174"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Imagine we have a lot of users like say 10 million users. If each of them sends a request to our server, at some point our server will reach its limit and will crash. Our service or website will then be seen as unavailable or even worse, unreliable. In order to prevent this we replicate our service across many servers sometimes tens of thousands of servers to handle the load of these requests. We also connect all these servers with another server called a load balancer. The work of this load balancer is to direct requests to the servers that it deems the freest. It uses a kind of algorithm known as a load balancing algorithm to determine which of our servers are free at a point in time and then forwards the clients request to them. The next step is that we need to secure our pool of servers now so that requests can only come in through the load balancer. We do not want anyone directly accessing any of our servers simply because they know the IP address. To improve the security, we secure the connection that our servers have with our clients by encrypting requests with an SSL certificate. This way the communication between our server and client cannot be leaked and even if it is, it is hardly useful to third parties.&lt;/p&gt;

&lt;p&gt;This is the third and final step as regards this article. Whenever we send a request to a website like Unsplash, our browser sends a request to a DNS server, this server responds to our browser with an IP address, this IP address points to a load balancing server owned by Unsplash. When our request hits the server, our session is immediately encrypted with the SSL certificate. The load balancer forwards our request to the freest server it can find in Unsplash’s pool of servers. The web server then reads our request and consults the database or the application server where appropriate in order to generate a response which is then sent back to our browser and we can then see the Unsplash page. All these processes happen in split seconds and as the years go by it becomes more and more difficult to appreciate the wonder of the internet we have in this age.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UCrwyzEn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/imuj6m41uktt9h84a3mw.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UCrwyzEn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/imuj6m41uktt9h84a3mw.jpg" alt="distributed web infra" width="880" height="366"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What makes the request and response cycle work so smoothly is a protocol called the TCP/IP protocol. IP takes care of the addressing system while TCP makes sure that the right packages/requests reach the right addresses. Thank you so much for reading this far, we have come to the end of our operation. Till next time.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>career</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Can't install older versions of Node on Apple's M1 MacBook?</title>
      <dc:creator>Abuka-Victor</dc:creator>
      <pubDate>Fri, 16 Sep 2022 07:50:33 +0000</pubDate>
      <link>https://dev.to/abukavictor/cant-install-older-versions-of-node-on-apples-m1-macbook-48gd</link>
      <guid>https://dev.to/abukavictor/cant-install-older-versions-of-node-on-apples-m1-macbook-48gd</guid>
      <description>&lt;p&gt;Apparently the binaries for older versions of node &amp;lt; 15.x do not natively compile on the M1 chip so you are going to need to use a Rosetta terminal to install it.&lt;/p&gt;

&lt;p&gt;To open a rosetta shell, run this command in your terminal&lt;/p&gt;

&lt;p&gt;&lt;code&gt;arch -x86_64 zsh&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then you can freely install the version you were trying to&lt;/p&gt;

&lt;p&gt;&lt;code&gt;nvm install vXX&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Credits:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/nvm-sh/nvm/issues/2350#issuecomment-734132550"&gt;nvm install node fails to install on macOS Big Sur M1 Chip - Github&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>node</category>
      <category>m1</category>
    </item>
    <item>
      <title>CrashLoopBackOff Error in Kubernetes - Sanity Checklist</title>
      <dc:creator>Abuka-Victor</dc:creator>
      <pubDate>Mon, 12 Sep 2022 01:45:27 +0000</pubDate>
      <link>https://dev.to/abukavictor/crashloopbackoff-error-in-kubernetes-sanity-checklist-5gbf</link>
      <guid>https://dev.to/abukavictor/crashloopbackoff-error-in-kubernetes-sanity-checklist-5gbf</guid>
      <description>&lt;p&gt;This is a very common problem when working with Kubernetes and I am writing this article fresh out of 31 hours of debugging. The fix in my case was very simple which I will make sure to talk about at the end. But for those who didn't come here to read my stories let's dive into what this error is and how to resolve it.&lt;/p&gt;

&lt;p&gt;The CrashLoopBackOff error basically means that your pod keeps restarting for some reason. There is no stable state. This could be due to the following reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Permission Issues&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you are working in a cloud environment like AWS, you need to make sure that the appropriate roles are assigned to your cluster and your worker nodes so that they can interact properly. If you are working locally in something like Minikube still make sure that the appropriate permissions are set.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Clashing Ports&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You may be trying to access ports that are in use by other processes. Try changing the ports. If two or more containers are trying to access the same port in the same pod. That can cause this issue as well.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Network Issues&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;One possible reason I saw while reading docs on AWS was that sometimes your subnets may have run out of free IP addresses. So do ensure that this is not the case. Some other times, it may be that the subnets do not automatically allocate IP addresses or maybe they just do not allow egress to resources your pod might be trying to access. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;External Resources&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Check that the external resources or dependencies that your pod or container needs to access are in a healthy state. It could be a file, a database, or even libraries from "npm install". If you are using something like AWS RDS, ensure that the security group configurations are properly set.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Configuration Files&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This goes without saying. Please do check your config files. Sometimes it could just be a typo somewhere. Also try to carefully check the commands that you have used so far in deployment. Maybe you misspelled a name or something.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;System Specifications&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now sometimes, you may not have enough resources like memory or whatnot on the nodes you may have allocated to run your pods so check that the specs of your machines are right. &lt;/p&gt;

&lt;p&gt;The best tool for finding errors&lt;/p&gt;

&lt;p&gt;&lt;code&gt;kubectl logs [pod name]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you have read up to this point and you are not interested in reading about my experience, you can stop here.&lt;/p&gt;

&lt;p&gt;Amazing, so you do want to hear about it. Okay so this is what happened. I had a cluster set up on AWS EKS and some node groups created. I had done everything to ensure that my steps were golden but still I had the CrashLoopBackOff error. So I noticed that whenever I tried to get the logs for my pod I got a format error that looked like this &lt;/p&gt;

&lt;p&gt;&lt;code&gt;exec /usr/local/bin/docker-entrypoint.sh: exec format error&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;A little more research here, a little stack overflow there and I found that it was because I built my docker image with a Mac M1 pro and my worker nodes ran a Linux OS. I never thought that would cause a conflict. So I fixed the build using&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker build -t [image-name] . --platform=linux/amd64&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;When I pushed it to docker hub and checked the pods again, the error was gone. So there ye have it, another possible reason to get the CrashLoopBackOff Error. Check that your docker image build is compatible with your worker node OS. To achieve reproducibility I suggest writing a script. Thanks for reading.&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>cloud</category>
      <category>devops</category>
      <category>aws</category>
    </item>
    <item>
      <title>Understanding from scratch, The Event Loop in Node JS</title>
      <dc:creator>Abuka-Victor</dc:creator>
      <pubDate>Mon, 01 Aug 2022 16:21:08 +0000</pubDate>
      <link>https://dev.to/abukavictor/understanding-from-scratch-the-event-loop-in-node-js-15kg</link>
      <guid>https://dev.to/abukavictor/understanding-from-scratch-the-event-loop-in-node-js-15kg</guid>
      <description>&lt;p&gt;There are two major components of Node that make Node what it is. These components are the V8 engine and the Libuv library. The V8 engine is basically an interpreter/compiler. It converts the code you write in Javascript to machine code that your computer can understand. The Libuv library is an open source library that facilitates asynchronous I/O operations. It also provides access to the event loop and the thread pool.&lt;/p&gt;

&lt;p&gt;The event loop is what is responsible for executing callback functions. In many places it is described as an orchestrator because it receives events/triggers (i.e a promise resolving, a network request, etc) , and runs the callback associated with that event. Now you may ask where does the thread pool come in? Sometimes, the tasks to be carried out are too heavy for the event loop to run on its own, i.e Cryptography operations, compression, so in these instances the event loop offloads these heavy tasks to the thread pool to run. The event loop decides automatically which tasks it deems too heavy so the developer really doesn’t have to bother about that. But of course, you can bother yourself if you really want to, that is fine as well.&lt;/p&gt;

&lt;p&gt;The reason the event loop is called such is because it does exactly what it’s name implies. It loops through certain classes of events to determine the priority of callbacks to execute. It first checks, are there any callbacks in the Timer class to run? By timer class I mean, stuff like setTimeout and other similar functions. Next, it goes on to check if there are any I/O callbacks to execute. After that it checks for setImmediate callbacks to run. The setImmediate callbacks are callbacks that you intend to run immediately after an I/O operation is complete. Lastly the event loop checks for close callbacks, i.e closing a server, closing a network connection, etc.&lt;/p&gt;

&lt;p&gt;You may want to ask where Promises fit into these classes, well that is actually a special case. The event loop really loves promises so it really doesn’t matter what’s next. As soon as a promise is resolved or rejected, the event loop immediately runs the callback associated with it. &lt;/p&gt;

&lt;p&gt;It is important to note that the event loop in all its glory can still be blocked and it is recommended that you do not write code that blocks the event loop for the sake of user experience. But like all recommendations, you can totally ignore this and write terrible code. All the same I will be sharing tips to help guide you in writing non-blocking code for the event loop.&lt;/p&gt;

&lt;p&gt;Do not use synchronous versions of functions within callbacks. &lt;br&gt;
Do not do complex computation within callbacks - a loop within a loop within a loop.&lt;br&gt;
Be careful with very large objects. It takes time to stringify or parse large objects to or from JSON.&lt;/p&gt;

&lt;p&gt;So that’s it for now from me guys. I really hope you learned something new from this. Happy Coding. &lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
