<?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: Ijas Ahammed</title>
    <description>The latest articles on DEV Community by Ijas Ahammed (@ijas9118).</description>
    <link>https://dev.to/ijas9118</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%2F2883458%2Fc9d22a86-cca2-4592-87e6-1fa4330631ca.jpeg</url>
      <title>DEV Community: Ijas Ahammed</title>
      <link>https://dev.to/ijas9118</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ijas9118"/>
    <language>en</language>
    <item>
      <title>How to Use Terraform to Create an AWS S3 Bucket: A Beginner’s Guide</title>
      <dc:creator>Ijas Ahammed</dc:creator>
      <pubDate>Fri, 06 Feb 2026 16:57:36 +0000</pubDate>
      <link>https://dev.to/ijas9118/how-to-use-terraform-to-create-an-aws-s3-bucket-a-beginners-guide-3ak8</link>
      <guid>https://dev.to/ijas9118/how-to-use-terraform-to-create-an-aws-s3-bucket-a-beginners-guide-3ak8</guid>
      <description>&lt;h2&gt;
  
  
  What is Terraform?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Terraform&lt;/strong&gt; is an open-source tool that lets you write code to create and manage cloud infrastructure. Instead of clicking through AWS console to create resources manually, you write configuration files that describe what you want, and Terraform builds it for you.&lt;/p&gt;

&lt;p&gt;Think of it like this: Instead of building a LEGO house brick by brick, you write down instructions, and Terraform builds it automatically every time.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Infrastructure as Code (IaC)?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Infrastructure as Code (IaC)&lt;/strong&gt; means managing your servers, databases, networks, and other infrastructure using code files instead of manual configuration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benefits:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Repeatable&lt;/strong&gt;: Create the same infrastructure multiple times without errors&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Version Control&lt;/strong&gt;: Track changes using Git, just like application code&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Documentation&lt;/strong&gt;: Your code becomes living documentation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Collaboration&lt;/strong&gt;: Teams can review and collaborate on infrastructure changes&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Use Cases:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Setting up development, staging, and production environments that are identical&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Quickly spinning up infrastructure for new projects&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Disaster recovery - rebuild everything from code if something breaks&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sharing infrastructure setups across teams&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is a Terraform Provider?
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;provider&lt;/strong&gt; is a plugin that allows Terraform to interact with a specific cloud platform or service (like AWS, Azure, Google Cloud, etc.).&lt;/p&gt;

&lt;p&gt;Think of providers as translators - they translate your Terraform code into API calls that the cloud platform understands.&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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1770391336394%2F5fa129d8-a57c-453e-9983-bfe2c05b5183.png%2520align%3D" 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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1770391336394%2F5fa129d8-a57c-453e-9983-bfe2c05b5183.png%2520align%3D" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;h3&gt;
  
  
  1. Create IAM User with S3 Full Access
&lt;/h3&gt;

&lt;p&gt;Before we can create S3 buckets, we need AWS credentials with proper permissions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Steps:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Log into AWS Console&lt;/strong&gt; → Go to IAM service&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Click "Users"&lt;/strong&gt; → "Create user"&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Username&lt;/strong&gt;: Enter &lt;code&gt;terraform-demo-user&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Click "Next"&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Attach policies directly&lt;/strong&gt; → Search and select &lt;code&gt;AmazonS3FullAccess&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Click "Next"&lt;/strong&gt; → &lt;strong&gt;"Create user"&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Click on the user&lt;/strong&gt; → Go to "Security credentials" tab&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Click "Create access key"&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Select "Command Line Interface (CLI)"&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Check the confirmation box&lt;/strong&gt; → "Next"&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;"Create access key"&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;IMPORTANT&lt;/strong&gt;: Save both:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* Access Key ID

* Secret Access Key (you won't see this again!)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  2. Configure AWS CLI
&lt;/h3&gt;

&lt;p&gt;Install AWS CLI (if not already installed):&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="c"&gt;# For Mac (using Homebrew)&lt;/span&gt;
brew &lt;span class="nb"&gt;install &lt;/span&gt;awscli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Configure with your access keys:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;You'll be prompted to enter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;AWS Access Key ID: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;paste &lt;/span&gt;your access key]
AWS Secret Access Key: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;paste &lt;/span&gt;your secret key]
Default region name: ap-south-1
Default output format: json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify it works:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3 &lt;span class="nb"&gt;ls&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Create Terraform Alias (Optional)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Add to your shell config file (~/.zshrc for Mac)&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'alias tf="terraform"'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.zshrc

&lt;span class="c"&gt;# Reload your shell&lt;/span&gt;
&lt;span class="nb"&gt;source&lt;/span&gt; ~/.zshrc

&lt;span class="c"&gt;# Test it&lt;/span&gt;
tf version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Setup VS Code
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Open VS Code&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go to Extensions (Cmd+Shift+X)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Search for "HashiCorp Terraform"&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install the official extension&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Benefits:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Syntax highlighting&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Auto-completion&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Format on save&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Validation&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Understanding the Terraform Configuration
&lt;/h2&gt;

&lt;p&gt;Create a file named &lt;a href="http://main.tf" rel="noopener noreferrer"&gt;&lt;code&gt;main.tf&lt;/code&gt;&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform &lt;span class="o"&gt;{&lt;/span&gt;
  required_providers &lt;span class="o"&gt;{&lt;/span&gt;
    aws &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="nb"&gt;source&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"hashicorp/aws"&lt;/span&gt;
      version &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"~&amp;gt; 6.0"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# Configure the AWS Provider&lt;/span&gt;
provider &lt;span class="s2"&gt;"aws"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  region  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ap-south-1"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# Create S3 Bucket&lt;/span&gt;
resource &lt;span class="s2"&gt;"aws_s3_bucket"&lt;/span&gt; &lt;span class="s2"&gt;"my_first_bucket"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  bucket &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ijas-tf-test-bucket-12345"&lt;/span&gt;

  tags &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    Name        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"My bucket"&lt;/span&gt;
    Environment &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Dev"&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;terraform {}&lt;/code&gt; block is used to configure Terraform itself. Inside it, &lt;code&gt;required_providers&lt;/code&gt; tells Terraform which providers are needed for the project. In this case, &lt;code&gt;aws&lt;/code&gt; is the name we use to refer to the AWS provider, and &lt;code&gt;source&lt;/code&gt; specifies that it should be downloaded from HashiCorp’s official registry.&lt;/p&gt;

&lt;p&gt;The line &lt;code&gt;version = "~&amp;gt; 6.0"&lt;/code&gt; means Terraform can use any 6.x version of the provider, allowing minor updates but not major ones. The &lt;code&gt;~&amp;gt;&lt;/code&gt; symbol is called a pessimistic constraint, which lets Terraform update safely without breaking changes.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;provider "aws"&lt;/code&gt; block is used to set up the AWS provider. Inside it, the &lt;code&gt;region&lt;/code&gt; tells Terraform where to create your AWS resources, in this case, Mumbai. Terraform automatically uses the login details you already set up earlier with &lt;code&gt;aws configure&lt;/code&gt;, so you don’t need to write your credentials again.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;resource&lt;/code&gt; keyword is used to define an infrastructure item in Terraform. &lt;code&gt;"aws_s3_bucket"&lt;/code&gt; specifies that you’re creating an S3 bucket using the AWS provider. &lt;code&gt;"my_first_bucket"&lt;/code&gt; is just a local name you give this resource inside your Terraform code. The &lt;code&gt;bucket&lt;/code&gt; field sets the real S3 bucket name in AWS, which must be globally unique. Finally, &lt;code&gt;tags&lt;/code&gt; are optional labels you add to help organize resources and track costs.&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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1770392315453%2F1ea9fc9b-81c5-47b0-ba2a-fc02ec743d4a.png%2520align%3D" 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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1770392315453%2F1ea9fc9b-81c5-47b0-ba2a-fc02ec743d4a.png%2520align%3D" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Terraform Workflow
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Initialise Terraform
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform init
&lt;span class="c"&gt;# or using alias&lt;/span&gt;
tf init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What happens:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Downloads the AWS provider plugin&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sets up the backend (where state is stored)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Prepares the working directory&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Output you'll see:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Initializing the backend...
Initializing provider plugins...
- Finding hashicorp/aws versions matching &lt;span class="s2"&gt;"~&amp;gt; 6.0"&lt;/span&gt;...
- Installing hashicorp/aws v6.x.x...
Terraform has been successfully initialized!
&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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1770393321083%2F1c632f34-02da-4fc9-bd8d-2b68e5cce644.png%2520align%3D" 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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1770393321083%2F1c632f34-02da-4fc9-bd8d-2b68e5cce644.png%2520align%3D" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Plan the Changes
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform plan
&lt;span class="c"&gt;# or&lt;/span&gt;
tf plan
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Compares your code with the current state&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Shows what will be created, modified, or destroyed&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Like a "preview" before making actual changes&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Terraform will perform the following actions:

  &lt;span class="c"&gt;# aws_s3_bucket.my_first_bucket will be created&lt;/span&gt;
  + resource &lt;span class="s2"&gt;"aws_s3_bucket"&lt;/span&gt; &lt;span class="s2"&gt;"my_first_bucket"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      + bucket                      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ijas-tf-test-bucket-12345"&lt;/span&gt;
      + tags                        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
          + &lt;span class="s2"&gt;"Environment"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Dev"&lt;/span&gt;
          + &lt;span class="s2"&gt;"Name"&lt;/span&gt;        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"My bucket"&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
      ...
    &lt;span class="o"&gt;}&lt;/span&gt;

Plan: 1 to add, 0 to change, 0 to destroy.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Symbols:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;+&lt;/code&gt; = Will be created&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;~&lt;/code&gt; = Will be modified&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;-&lt;/code&gt; = Will be destroyed&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Optional: Save the Plan
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;tf plan &lt;span class="nt"&gt;-out&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;tfplan
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why use this?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Saves the exact plan to a file&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When you run &lt;code&gt;tf apply tfplan&lt;/code&gt;, it executes exactly what was planned&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Prevents surprises if something changes between plan and apply&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Good practice for production environments&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 3: Apply the Changes
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform apply
&lt;span class="c"&gt;# or&lt;/span&gt;
tf apply

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

&lt;/div&gt;



&lt;p&gt;Terraform will show the plan again and ask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Do you want to perform these actions?
  Enter a value:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Type &lt;code&gt;yes&lt;/code&gt; and press Enter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Skip the confirmation:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;tf apply &lt;span class="nt"&gt;-auto-approve&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What happens:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Terraform makes API calls to AWS&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Creates the S3 bucket&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Saves the state to &lt;code&gt;terraform.tfstate&lt;/code&gt; file&lt;/p&gt;&lt;/li&gt;
&lt;/ol&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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1770393852097%2F527e10db-b7e1-4768-bd58-a9d37451af05.png%2520align%3D" 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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1770393852097%2F527e10db-b7e1-4768-bd58-a9d37451af05.png%2520align%3D" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Verify in AWS Console
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Go to AWS Console → S3&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You'll see your bucket: &lt;code&gt;ijas-tf-test-bucket-12345&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click on it → Properties tab → Tags&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You'll see the tags you defined&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 5: Modify and Reapply
&lt;/h3&gt;

&lt;p&gt;Let's change a tag in &lt;a href="http://main.tf" rel="noopener noreferrer"&gt;&lt;code&gt;main.tf&lt;/code&gt;&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;resource &lt;span class="s2"&gt;"aws_s3_bucket"&lt;/span&gt; &lt;span class="s2"&gt;"my_first_bucket"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  bucket &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ijas-tf-test-bucket-12345"&lt;/span&gt;

  tags &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    Name        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"My bucket"&lt;/span&gt;
    Environment &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Development"&lt;/span&gt;  &lt;span class="c"&gt;# Changed from "Dev"&lt;/span&gt;
    Owner       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Ijas"&lt;/span&gt;          &lt;span class="c"&gt;# Added new tag&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;You'll see:&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="c"&gt;# aws_s3_bucket.my_first_bucket will be updated in-place&lt;/span&gt;
  ~ resource &lt;span class="s2"&gt;"aws_s3_bucket"&lt;/span&gt; &lt;span class="s2"&gt;"my_first_bucket"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      ~ tags &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
          ~ &lt;span class="s2"&gt;"Environment"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Dev"&lt;/span&gt; -&amp;gt; &lt;span class="s2"&gt;"Development"&lt;/span&gt;
          + &lt;span class="s2"&gt;"Owner"&lt;/span&gt;       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Ijas"&lt;/span&gt;
            &lt;span class="s2"&gt;"Name"&lt;/span&gt;        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"My bucket"&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

Plan: 0 to add, 1 to change, 0 to destroy.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply the changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;tf apply &lt;span class="nt"&gt;-auto-approve&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go back to AWS Console → refresh → see the updated tags!&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6: Destroy Resources
&lt;/h2&gt;

&lt;p&gt;When you're done experimenting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform destroy
&lt;span class="c"&gt;# or&lt;/span&gt;
tf destroy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Terraform shows what will be destroyed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Plan: 0 to add, 0 to change, 1 to destroy.

Do you really want to destroy all resources?
  Enter a value:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Type &lt;code&gt;yes&lt;/code&gt; or use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;tf destroy &lt;span class="nt"&gt;-auto-approve&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What happens:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Terraform deletes the S3 bucket from AWS&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Updates the state file (now empty)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Key Concepts Summary
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Concept&lt;/th&gt;
&lt;th&gt;Simple Explanation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Terraform&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Tool to write code that builds cloud infrastructure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;IaC&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Managing infrastructure through code files instead of clicking&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Provider&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Plugin that connects Terraform to cloud platforms (AWS, Azure, etc.)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Resource&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A piece of infrastructure you want to create (S3 bucket, EC2 instance)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;State&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Terraform's memory of what exists in the cloud&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Plan&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Preview of changes before applying them&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Apply&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Actually create/update/delete resources&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Destroy&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Delete all resources managed by Terraform&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Common Commands Cheat Sheet
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Initialize project (run once)&lt;/span&gt;
tf init

&lt;span class="c"&gt;# Preview changes&lt;/span&gt;
tf plan
tf plan &lt;span class="nt"&gt;-out&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;tfplan  &lt;span class="c"&gt;# Save plan to file&lt;/span&gt;

&lt;span class="c"&gt;# Apply changes&lt;/span&gt;
tf apply
tf apply &lt;span class="nt"&gt;-auto-approve&lt;/span&gt;  &lt;span class="c"&gt;# Skip confirmation&lt;/span&gt;
tf apply tfplan  &lt;span class="c"&gt;# Apply saved plan&lt;/span&gt;

&lt;span class="c"&gt;# Show current state&lt;/span&gt;
tf show

&lt;span class="c"&gt;# List resources&lt;/span&gt;
tf state list

&lt;span class="c"&gt;# Destroy everything&lt;/span&gt;
tf destroy
tf destroy &lt;span class="nt"&gt;-auto-approve&lt;/span&gt;

&lt;span class="c"&gt;# Format code (clean up spacing/indentation)&lt;/span&gt;
tf &lt;span class="nb"&gt;fmt&lt;/span&gt;

&lt;span class="c"&gt;# Validate syntax&lt;/span&gt;
tf validate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>terraform</category>
      <category>devops</category>
      <category>aws</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Understanding HR Domain</title>
      <dc:creator>Ijas Ahammed</dc:creator>
      <pubDate>Sat, 17 Jan 2026 15:00:42 +0000</pubDate>
      <link>https://dev.to/ijas9118/understanding-hr-domain-5h1n</link>
      <guid>https://dev.to/ijas9118/understanding-hr-domain-5h1n</guid>
      <description>&lt;h2&gt;
  
  
  What We'll Cover
&lt;/h2&gt;

&lt;p&gt;Before diving into architecture and code, we need to gain a deep understanding of the HR domain. In this post, I'll break down the six core HR processes that every modern HR Management System must handle:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Recruitment &amp;amp; Hiring&lt;/li&gt;
&lt;li&gt;Employee Onboarding&lt;/li&gt;
&lt;li&gt;Attendance &amp;amp; Time Tracking&lt;/li&gt;
&lt;li&gt;Leave Management&lt;/li&gt;
&lt;li&gt;Payroll Processing&lt;/li&gt;
&lt;li&gt;Performance Management&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By the end, you'll have a clear mental model of how these processes work and their key challenges.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Domain Understanding Matters
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Before I learned this:&lt;/strong&gt; I thought I could jump straight into designing microservices. Big mistake! Without understanding the domain, you'll:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Miss critical features&lt;/li&gt;
&lt;li&gt;Create wrong service boundaries (Split services wrongly)&lt;/li&gt;
&lt;li&gt;Build systems that don't match real-world workflows&lt;/li&gt;
&lt;li&gt;Struggle with naming and consistency&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;The Truth&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;60%&lt;/strong&gt; of system design is understanding the problem.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;40%&lt;/strong&gt; is implementing the technical solution.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  1️⃣ Recruitment &amp;amp; Hiring
&lt;/h1&gt;

&lt;h3&gt;
  
  
  The Workflow
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;Process&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;📄 Job Requisition&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;📢 Job Posting&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;📥 Applications Received&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;🔍 Screening&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;🗣️ Interviews&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;📑 Offer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;✅ Acceptance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;🚀 Onboarding&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The process begins with &lt;strong&gt;Job Requisition&lt;/strong&gt;, where a department identifies the need for a new hire and gets approval to fill the position.&lt;/p&gt;

&lt;p&gt;Next, the role is shared publicly during &lt;strong&gt;Job Posting&lt;/strong&gt;, allowing potential candidates to learn about the opportunity and apply.&lt;/p&gt;

&lt;p&gt;Once applications come in, they are collected under &lt;strong&gt;Applications Received&lt;/strong&gt;, creating a pool of interested candidates.&lt;/p&gt;

&lt;p&gt;During &lt;strong&gt;Screening&lt;/strong&gt;, resumes and applications are reviewed to shortlist candidates who best match the job requirements.&lt;/p&gt;

&lt;p&gt;Shortlisted candidates move to &lt;strong&gt;Interviews&lt;/strong&gt;, where their skills, experience, and fit for the role are evaluated through discussions.&lt;/p&gt;

&lt;p&gt;After interviews, a selected candidate receives an &lt;strong&gt;Offer&lt;/strong&gt;, which includes job details such as role, salary, and joining date.&lt;/p&gt;

&lt;p&gt;If the candidate agrees, &lt;strong&gt;Acceptance&lt;/strong&gt; confirms their decision to join the organisation.&lt;/p&gt;

&lt;p&gt;Finally, &lt;strong&gt;Onboarding&lt;/strong&gt; helps the new employee settle in through documentation, training, and introductions to the team.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Components
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Stakeholders&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hiring Manager&lt;/strong&gt; — Initiates and owns the job requisition.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recruiter&lt;/strong&gt; — Manages the end-to-end recruitment process.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interview Panel&lt;/strong&gt; — Assesses candidate skills, experience, and suitability.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HR Administrator&lt;/strong&gt; — Handles final approvals and employment formalities.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Critical Features&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Complexity&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Job Posting&lt;/td&gt;
&lt;td&gt;Publish job openings across multiple platforms like the company website and job portals&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Application Tracking&lt;/td&gt;
&lt;td&gt;Track and manage candidates through different hiring stages&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Interview Scheduling&lt;/td&gt;
&lt;td&gt;Schedule interviews using calendar integration and meeting rooms&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Candidate Scoring&lt;/td&gt;
&lt;td&gt;Collect and compare interviewer feedback using standard forms&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Offer Management&lt;/td&gt;
&lt;td&gt;Create offers, manage approvals, and collect digital signatures&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Business Rules
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Approval Before Posting&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Every job requisition must receive budget and management approval before it can be published.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Minimum Candidate Screening&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
A defined minimum number of candidates must be screened to ensure fair and competitive selection.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Mandatory Interview Feedback&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
All interview panel members must submit feedback before a hiring decision can be made.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Offer Validity Period&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Job offers are valid only for a fixed time frame (usually 7–15 days) after which they expire automatically.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Background Verification Required&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Final hiring confirmation is completed only after successful background and document verification.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Real-World Challenge
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Scenario:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
A single candidate may apply for multiple job openings using the same or different details, leading to duplicate records.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Create a centralised candidate profile using a unique identifier (such as email or phone number). Each candidate has one master profile in the system. Multiple job applications are linked to the same profile.  &lt;/p&gt;


&lt;h1&gt;
  
  
  2️⃣ Employee Onboarding
&lt;/h1&gt;
&lt;h3&gt;
  
  
  The Workflow
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;Stage Name&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Offered&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Document Submission&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Background Check&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Account Creation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Asset Assignment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;First Day Setup&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;Active&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The onboarding begins when the candidate receives and accepts the job offer, officially confirming their entry into the organisation.&lt;/p&gt;

&lt;p&gt;Once the offer is accepted, the candidate is asked to submit all required documents for verification and record-keeping purposes.&lt;/p&gt;

&lt;p&gt;After the documents are collected, the company performs a background verification to ensure all provided information is accurate.&lt;/p&gt;

&lt;p&gt;When verification is completed successfully, official company accounts and system access are created for the new employee.&lt;/p&gt;

&lt;p&gt;With digital access ready, necessary work assets such as laptops, ID cards, or other tools are assigned.&lt;/p&gt;

&lt;p&gt;On the first working day, basic system setup, orientation, and introductions are completed to help the employee get started smoothly.&lt;/p&gt;

&lt;p&gt;Finally, the onboarding process concludes as the employee becomes fully active and begins normal work responsibilities.&lt;/p&gt;
&lt;h3&gt;
  
  
  Data to Collect
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Examples&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Personal&lt;/td&gt;
&lt;td&gt;Name, DOB, Gender, Address, Emergency contacts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Professional&lt;/td&gt;
&lt;td&gt;Previous employment, Education, Certifications&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Financial&lt;/td&gt;
&lt;td&gt;Bank account, PAN/Tax ID, Salary account&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Compliance&lt;/td&gt;
&lt;td&gt;Work permits, Right to work documents&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  Edge Cases
&lt;/h3&gt;

&lt;p&gt;❗ &lt;strong&gt;What if the background check fails after offer acceptance?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the background check fails after the offer is accepted, the company may withdraw the offer based on its internal policy. Legal and compliance teams usually review the case before taking a final decision.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;❗ &lt;strong&gt;What if the employee doesn't submit documents on time?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the employee does not submit documents on time, a short grace period is usually given. If delays continue, the issue may be escalated, and the onboarding process can be temporarily paused.&lt;/li&gt;
&lt;/ul&gt;


&lt;h1&gt;
  
  
  3️⃣ Attendance &amp;amp; Time Tracking
&lt;/h1&gt;
&lt;h3&gt;
  
  
  Attendance Methods
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;No.&lt;/th&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Biometric (Fingerprint / Face)&lt;/td&gt;
&lt;td&gt;Attendance is marked using fingerprint or face scan at the office.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;RFID Card Swipe&lt;/td&gt;
&lt;td&gt;Employees swipe their ID card on a machine to record attendance.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Mobile App (GPS-based)&lt;/td&gt;
&lt;td&gt;Attendance is marked through a mobile app with location tracking.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Web Portal (Manual)&lt;/td&gt;
&lt;td&gt;Employees manually log in to a website to mark attendance.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Beacon / Bluetooth (Office Entry)&lt;/td&gt;
&lt;td&gt;Attendance is automatically captured when entering the office using Bluetooth.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Shift Management:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fixed shifts (9 AM - 6 PM)&lt;/li&gt;
&lt;li&gt;Flexible hours (core hours + flexible)&lt;/li&gt;
&lt;li&gt;Rotating shifts (for 24/7 operations)&lt;/li&gt;
&lt;li&gt;Night shifts (with allowances)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Attendance Status:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Present (On time)&lt;/li&gt;
&lt;li&gt;Late (Grace period: 15-30 mins)&lt;/li&gt;
&lt;li&gt;Half Day (Less than X hours)&lt;/li&gt;
&lt;li&gt;Absent&lt;/li&gt;
&lt;li&gt;Work from Home&lt;/li&gt;
&lt;li&gt;On Leave&lt;/li&gt;
&lt;li&gt;Holiday&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Overtime Calculation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Regular hours: 8 hours/day&lt;/li&gt;
&lt;li&gt;Overtime: &amp;gt; 8 hours&lt;/li&gt;
&lt;li&gt;Weekend work: 2x multiplier&lt;/li&gt;
&lt;li&gt;Holiday work: 3x multiplier&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Business Rules
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Employees can be up to 15 minutes late without penalty.&lt;/li&gt;
&lt;li&gt;A full day counts only if 8 hours are worked.&lt;/li&gt;
&lt;li&gt;Working 4–6 hours is counted as a half day.&lt;/li&gt;
&lt;li&gt;Overtime is valid only with manager approval.&lt;/li&gt;
&lt;li&gt;Attendance issues must be corrected within 3–5 days.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  The Tricky Part: Timezone Handling
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Challenge:&lt;/strong&gt; Global team with employees in multiple time zones.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HQ in India (IST)&lt;/li&gt;
&lt;li&gt;Employee working from the USA (EST)&lt;/li&gt;
&lt;li&gt;Check-in at 9 AM EST = 7:30 PM IST (previous day!)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Store all timestamps in UTC, convert time only for display and reports based on each employee’s assigned time zone.&lt;/p&gt;


&lt;h1&gt;
  
  
  4️⃣ Leave Management
&lt;/h1&gt;

&lt;p&gt;Leave Types Hierarchy&lt;/p&gt;
&lt;h3&gt;
  
  
  Annual Leave Quota
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Leave Type&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Earned Leave&lt;/td&gt;
&lt;td&gt;Leave accumulated monthly based on days worked.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Casual Leave&lt;/td&gt;
&lt;td&gt;Short-term leave granted annually for personal needs.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sick Leave&lt;/td&gt;
&lt;td&gt;Leave provided annually for illness or medical reasons.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Compensatory Off&lt;/td&gt;
&lt;td&gt;Leave earned by working extra hours or on holidays.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Maternity Leave&lt;/td&gt;
&lt;td&gt;Leave granted to female employees as per company policy and law.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Paternity Leave&lt;/td&gt;
&lt;td&gt;Leave granted to male employees around childbirth, as per policy.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Loss of Pay&lt;/td&gt;
&lt;td&gt;Unpaid leave taken when no other leave balance is available.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  The Leave Request Workflow
&lt;/h3&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%2Fqd0wveh6g19bw4kwz4fk.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%2Fqd0wveh6g19bw4kwz4fk.png" alt="Leave Request Workflow" width="800" height="807"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Leave Balance Calculation
&lt;/h3&gt;

&lt;p&gt;Below is an example of how leave balance and accrual logic might be adopted in an HR management system. Accrual means that leave gets added little by little over time. Instead of giving all leave at once, the system adds some every month.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Earned Leave&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every month, you earn &lt;strong&gt;1.5 days&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Over a full year: &lt;code&gt;1.5 × 12 = 18 days&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If you don’t use all your earned leave, you can carry it forward:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can carry forward &lt;strong&gt;only up to 10 days&lt;/strong&gt; into the next year&lt;/li&gt;
&lt;li&gt;Anything above &lt;strong&gt;10 days&lt;/strong&gt; is removed or settled&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Encashment&lt;/strong&gt; means converting unused leave into money  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Earned Leave &lt;strong&gt;can be converted into salary&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Example: &lt;strong&gt;5 unused days → paid as money&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Casual Leave&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is for short, unexpected needs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You get 12 days per year&lt;/li&gt;
&lt;li&gt;All 12 days are given at once on January 1st&lt;/li&gt;
&lt;li&gt;Cannot be carried to next year&lt;/li&gt;
&lt;li&gt;Cannot be converted to money&lt;/li&gt;
&lt;li&gt;If not used → it expires&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Leave Type&lt;/th&gt;
&lt;th&gt;Days / Year&lt;/th&gt;
&lt;th&gt;Carry Forward&lt;/th&gt;
&lt;th&gt;Encashment&lt;/th&gt;
&lt;th&gt;Expiry&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Earned Leave&lt;/td&gt;
&lt;td&gt;18&lt;/td&gt;
&lt;td&gt;Up to 10 days&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Excess removed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Casual Leave&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Expires yearly&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  Business Rules
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Advance notice required&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Some leaves must be applied early&lt;/li&gt;
&lt;li&gt;Example:

&lt;ul&gt;
&lt;li&gt;Casual Leave → 2 days before&lt;/li&gt;
&lt;li&gt;Earned Leave → 7 days before&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Blackout periods&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;During important times (year-end, major projects)&lt;/li&gt;
&lt;li&gt;Leave may not be allowed&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Maximum continuous leave&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can’t take too many days in a row&lt;/li&gt;
&lt;li&gt;Example: max 10 consecutive days&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Half-day leave&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The company decides whether half-day leave is allowed&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Leave cancellation rules&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Leave may need to be cancelled before a certain date&lt;/li&gt;
&lt;li&gt;Late cancellation may still count as leave&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;


&lt;h1&gt;
  
  
  5️⃣ Payroll Processing
&lt;/h1&gt;
&lt;h3&gt;
  
  
  Salary Structure
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CTC (Total yearly pay):&lt;/strong&gt; $100,000
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fixed Pay (80%)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Basic Salary: $40,000
&lt;/li&gt;
&lt;li&gt;HRA: $20,000
&lt;/li&gt;
&lt;li&gt;Special Allowance: $20,000
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Variable Pay (15%)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Bonuses and incentives (performance-based)
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Benefits (5%)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Provident fund, insurance, meal vouchers
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Payroll Process (Monthly)
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Collect attendance data
&lt;/li&gt;
&lt;li&gt;Calculate working and leave days
&lt;/li&gt;
&lt;li&gt;Identify Loss of Pay (LOP)
&lt;/li&gt;
&lt;li&gt;Calculate gross salary
&lt;/li&gt;
&lt;li&gt;Add bonuses or overtime
&lt;/li&gt;
&lt;li&gt;Deduct PF, tax, and other deductions
&lt;/li&gt;
&lt;li&gt;Calculate net salary
&lt;/li&gt;
&lt;li&gt;Generate payslip
&lt;/li&gt;
&lt;li&gt;Transfer salary to the bank
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Deductions
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Mandatory&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Income tax
&lt;/li&gt;
&lt;li&gt;Provident Fund (12% of basic)
&lt;/li&gt;
&lt;li&gt;Professional tax
&lt;/li&gt;
&lt;li&gt;Insurance (if applicable)
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Optional&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Loan or advance recovery
&lt;/li&gt;
&lt;li&gt;Meal charges
&lt;/li&gt;
&lt;li&gt;LOP deductions
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Tax Calculation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Tax is calculated using slabs (higher income → higher tax rate)
&lt;/li&gt;
&lt;li&gt;Allowed deductions reduce taxable income (insurance, loans, donations)
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Payroll Cycle
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Day 1–25:&lt;/strong&gt; Attendance tracking
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Day 26–30:&lt;/strong&gt; Data freeze
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Next month Day 1–5:&lt;/strong&gt; Payroll processing &amp;amp; approval
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Day 7:&lt;/strong&gt; Salary paid
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Day 10:&lt;/strong&gt; Payslip shared
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Important Edge Cases
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Mid-month joining → salary paid proportionally
&lt;/li&gt;
&lt;li&gt;Mid-month resignation → final settlement
&lt;/li&gt;
&lt;li&gt;Salary revision → arrears calculation
&lt;/li&gt;
&lt;li&gt;Recoveries → adjusted in last salary
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Payroll ensures employees are paid accurately, on time, and legally compliant.&lt;/p&gt;


&lt;h1&gt;
  
  
  6️⃣ Performance Management
&lt;/h1&gt;

&lt;p&gt;Performance management is how a company checks how well an employee is doing their job.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;At the start, employees are told what they need to work on.&lt;/li&gt;
&lt;li&gt;During the year, progress is checked.&lt;/li&gt;
&lt;li&gt;Employees and managers both give feedback.&lt;/li&gt;
&lt;li&gt;HR reviews everything to keep it fair.&lt;/li&gt;
&lt;li&gt;Finally, feedback is shared in a one-on-one meeting.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Based on performance&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Good performance leads to a salary increase or promotion.&lt;/li&gt;
&lt;li&gt;Average performance gets a normal increment.&lt;/li&gt;
&lt;li&gt;Poor performance may need improvement training or further action.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This process helps employees grow and improves overall company performance.&lt;/p&gt;
&lt;h3&gt;
  
  
  Rating Scale
&lt;/h3&gt;

&lt;p&gt;Employees are rated on a scale of 1 to 5, where 5 is excellent and 1 is poor performance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;5: Exceptional (Top 5%)
4: Exceeds Expectations (25%)
3: Meets Expectations (60%)
2: Needs Improvement (9%)
1: Unsatisfactory (1%)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  360-Degree Feedback
&lt;/h3&gt;

&lt;p&gt;The final rating comes from 360-degree feedback:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Manager: 50%&lt;/li&gt;
&lt;li&gt;Peers: 20%&lt;/li&gt;
&lt;li&gt;Direct reports: 15%&lt;/li&gt;
&lt;li&gt;Self-review: 15%&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Link to Compensation
&lt;/h3&gt;

&lt;p&gt;This final rating decides salary increment and promotion:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rating 5 → 15–20% hike + eligible for promotion&lt;/li&gt;
&lt;li&gt;Rating 4 → 10–15% hike&lt;/li&gt;
&lt;li&gt;Rating 3 → 5–8% hike&lt;/li&gt;
&lt;li&gt;Rating 2 → 0–3% hike + improvement plan&lt;/li&gt;
&lt;li&gt;Rating 1 → No hike + possible exit discussion&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Domain Model Summary
&lt;/h1&gt;

&lt;p&gt;Here's a quick reference of the entities we discovered:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Domain&lt;/th&gt;
&lt;th&gt;Key Entities&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Recruitment&lt;/td&gt;
&lt;td&gt;Job, Candidate, Application, Interview, Offer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Onboarding&lt;/td&gt;
&lt;td&gt;Employee, Document, Task, Asset&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Attendance&lt;/td&gt;
&lt;td&gt;AttendanceRecord, Shift, Timesheet, Overtime&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Leave&lt;/td&gt;
&lt;td&gt;LeaveRequest, LeaveBalance, LeaveType&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Payroll&lt;/td&gt;
&lt;td&gt;Payslip, SalaryComponent, Deduction, Tax&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Performance&lt;/td&gt;
&lt;td&gt;Review, Goal, Feedback, Rating&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>systemdesign</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Designing HR Management System: A Learning Journey</title>
      <dc:creator>Ijas Ahammed</dc:creator>
      <pubDate>Sat, 17 Jan 2026 14:58:16 +0000</pubDate>
      <link>https://dev.to/ijas9118/designing-hr-management-system-a-learning-journey-d28</link>
      <guid>https://dev.to/ijas9118/designing-hr-management-system-a-learning-journey-d28</guid>
      <description>&lt;p&gt;Hey, welcome to the course. I hope this course provides a great learning experience!&lt;/p&gt;

</description>
      <category>systemdesign</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Git Cheatsheet</title>
      <dc:creator>Ijas Ahammed</dc:creator>
      <pubDate>Sun, 28 Sep 2025 02:48:24 +0000</pubDate>
      <link>https://dev.to/ijas9118/git-cheatsheet-9j4</link>
      <guid>https://dev.to/ijas9118/git-cheatsheet-9j4</guid>
      <description>&lt;p&gt;A quick reference for the most common and useful Git commands.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠 Setup &amp;amp; Initialization
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git init&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Initialize a new Git repository in the current directory.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git clone [repo-url]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Clone an existing repository.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git remote -v&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List remote repositories connected to your project.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git remote add origin [url]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Link a local repo to a remote repo.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git branch -M [new-name]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Rename the current branch (commonly &lt;code&gt;main&lt;/code&gt;).&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  📂 Working with Files
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git add [file/dir]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Stage a file or directory for commit.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git add .&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Stage all changes in the current directory.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git rm [file]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Remove a file and stage the removal.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git mv [old] [new]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Rename or move a file.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  💾 Saving Changes
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git commit -m "msg"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Commit staged changes with a message.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git commit -am "msg"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Stage &lt;strong&gt;and&lt;/strong&gt; commit tracked files in one step.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git reset --soft [hash]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Undo commits but keep changes staged.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git reset [hash]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Undo commits and unstage changes (keep in working dir).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git reset --hard [hash]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Reset everything to a specific commit (⚠ destructive).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git revert [hash]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Create a new commit that undoes a specific commit.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git revert --continue&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Continue revert if conflicts occur.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git revert --abort&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Cancel an in-progress revert.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🌿 Branching &amp;amp; Merging
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git branch&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List all branches, &lt;code&gt;*&lt;/code&gt; shows current branch.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git branch [name]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Create a new branch.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git branch [new] [existing]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Create new branch from another.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git checkout [branch]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Switch to an existing branch.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git checkout -b [name]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Create &lt;strong&gt;and&lt;/strong&gt; switch to a new branch.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git merge [branch]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Merge a branch into the current branch.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git push --set-upstream origin [branch]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Push new branch and set remote tracking.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🔄 Sync with Remote
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git pull&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Fetch and merge from remote.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git fetch&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Download changes but don’t merge yet.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git push&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Push commits to remote.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git push -u origin main&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Push and set default upstream (first push).&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  📊 Check Status &amp;amp; History
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git status&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show staged/unstaged/untracked files.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git log&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show commit history.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git log --oneline --graph --decorate --all&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Pretty, compact commit history.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git diff [file]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show unstaged changes for a file.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git diff --staged&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show staged changes (ready to commit).&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🗄 Stash &amp;amp; Temporary Work
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git stash&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Save uncommitted changes temporarily.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git stash list&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show list of stashed changes.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git stash apply [id]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Apply stashed changes (keeps in stash).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git stash pop&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Apply and remove from stash.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  ⚔️ Resolving Merge Conflicts
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout main
git pull origin main
git checkout your-branch
git merge main
&lt;span class="c"&gt;# Resolve conflicts manually in files&lt;/span&gt;
git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"fix merge conflict"&lt;/span&gt;
git push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Database Replication</title>
      <dc:creator>Ijas Ahammed</dc:creator>
      <pubDate>Sat, 27 Sep 2025 05:24:23 +0000</pubDate>
      <link>https://dev.to/ijas9118/database-replication-5dmj</link>
      <guid>https://dev.to/ijas9118/database-replication-5dmj</guid>
      <description>&lt;p&gt;Database replication can be used in DBMS with a master/slave relationship, where a original master DB syncs and controls the slave DB.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Master DB usually is WRITE intensive, and all the write operations like Create, Update, Delete, Mutate, must be sent only to Master DB.&lt;/li&gt;
&lt;li&gt;All the slave DBs are READ intensive.&lt;/li&gt;
&lt;li&gt;Most applications have a high read to write ratio, and thus the number of slave databases can be increased to support it.&lt;/li&gt;
&lt;/ul&gt;

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




&lt;h2&gt;
  
  
  Advantages
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Better Performance
&lt;/h3&gt;

&lt;p&gt;All the write operations will happen on master, and read operations will happen on slaves. It improves performance because more query operations can be done parallely.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reliability
&lt;/h3&gt;

&lt;p&gt;If any of the DB is destroyed in a natural disaster, the data will be safe, as there are replicas.&lt;/p&gt;

&lt;h3&gt;
  
  
  High Availability
&lt;/h3&gt;

&lt;p&gt;By deploying the DB replicas in different locations, we ensure that the user always gets the data, even when the DB closer to him is offline.&lt;/p&gt;




&lt;h2&gt;
  
  
  What if one of the DB goes down?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;If the only slave DB goes down, the Master DB will now handle read operation as well. And once the issue is sorted out, a new slave DB will replace the old one.&lt;/li&gt;
&lt;li&gt;In case of multiple slave DBs, and one of them fails, all the query requests will be forwarded to healthy slaves.&lt;/li&gt;
&lt;li&gt;If the master DB goes down, one of the slave DBs is elected and promoted as the new Master. And immediately a new slave DB is created and replaced.&lt;/li&gt;
&lt;/ul&gt;

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

</description>
      <category>database</category>
      <category>systemdesign</category>
      <category>webdev</category>
    </item>
    <item>
      <title>SSH Key Authentication in Linux</title>
      <dc:creator>Ijas Ahammed</dc:creator>
      <pubDate>Tue, 16 Sep 2025 03:44:50 +0000</pubDate>
      <link>https://dev.to/ijas9118/ssh-key-authentication-in-linux-3aoo</link>
      <guid>https://dev.to/ijas9118/ssh-key-authentication-in-linux-3aoo</guid>
      <description>&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;What is SSH Keys?&lt;/li&gt;
&lt;li&gt;Working Of SSH Keys&lt;/li&gt;
&lt;li&gt;Creation of SSH Keys&lt;/li&gt;
&lt;li&gt;Copying Key to Remote Server&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Normally, when we connect to a server using ssh, we use the password for that user. Do you use simple password which include "123" or your name? Do you think it is safe? Absolutely not!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/danielmiessler/SecLists/tree/master/Passwords" rel="noopener noreferrer"&gt;SecLists&lt;/a&gt;, a popular open-source project by Daniel Miessler &amp;amp; others, is a collection of various wordlists and lists used in security testing (penetration testing, red teaming, etc.). The lists include things like common usernames, URLs, known password strings, etc. The goal is to provide testers with ready-made lists that can be used for bruteforce attacks, scanning for vulnerabilities, password cracking, etc.&lt;/p&gt;

&lt;p&gt;So the best way to create a secure authenticated connection is using SSH key pairs. You don't have to remember your passwords know, just use the ssh keys instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is SSH Keys?
&lt;/h2&gt;

&lt;p&gt;SSH keys contain two keys, Private key and a Public key. The pirvate key should be super secret and you must know where you are storing it in your machine. The public is key, is public! No matter if you share it with anyone.&lt;/p&gt;

&lt;p&gt;Let's say you have two machine, home and a remote machine, which you want to login using ssh keys. First of all, check if any ssh keys exists in the machine using the command: &lt;code&gt;ls -l ~/.ssh&lt;/code&gt;. This will list all the existing ssh files. You may choose to backup if any exist.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ijas@debian:~&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; ~/.ssh
&lt;span class="nb"&gt;ls&lt;/span&gt;: cannot access &lt;span class="s1"&gt;'/home/ijas/.ssh'&lt;/span&gt;: No such file or directory
&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;ijas@ubuntu:~&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; ~/.ssh
&lt;span class="nb"&gt;ls&lt;/span&gt;: cannot access &lt;span class="s1"&gt;'/home/ijas/.ssh'&lt;/span&gt;: No such file or directory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In my debian and ubuntu machines, no ssh keys are present.&lt;/p&gt;

&lt;h2&gt;
  
  
  Working Of SSH Keys
&lt;/h2&gt;

&lt;p&gt;SSH keys comes with pair (Private and Public). The public key is generated using the private key, in a way, they are linked together (but you can't get the private key from public key). The public key will be sent to the remote machine or server and it stores the key. &lt;/p&gt;

&lt;p&gt;Whenever a user try to log in to that remote server from the host machine, the remote server creates a random string of characters (like 8&amp;amp;vw^afdsE...) and encrypt it using the public key. Now, this encrypted text can only be decrypted using the private key. The host now must prove that he can decrypt the encrypted string using the private key. Once decrypted, host sends back the result to the remote server and if they match, then the host is authenticated and can login to the remote server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creation of SSH Keys
&lt;/h2&gt;

&lt;p&gt;To create ssh key pair in your machine, use the command &lt;code&gt;ssh-keygen&lt;/code&gt;. ssh-keygen generates, manages and converts authentication keys for ssh.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ijas@debian:~&lt;span class="nv"&gt;$ &lt;/span&gt;ssh-keygen &lt;span class="nt"&gt;-b&lt;/span&gt; 4096
Generating public/private rsa key pair.
Enter file &lt;span class="k"&gt;in &lt;/span&gt;which to save the key &lt;span class="o"&gt;(&lt;/span&gt;/home/ijas/.ssh/id_rsa&lt;span class="o"&gt;)&lt;/span&gt;: 
Created directory &lt;span class="s1"&gt;'/home/ijas/.ssh'&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
Enter passphrase &lt;span class="o"&gt;(&lt;/span&gt;empty &lt;span class="k"&gt;for &lt;/span&gt;no passphrase&lt;span class="o"&gt;)&lt;/span&gt;: 
Enter same passphrase again: 
Your identification has been saved &lt;span class="k"&gt;in&lt;/span&gt; /home/ijas/.ssh/id_rsa
Your public key has been saved &lt;span class="k"&gt;in&lt;/span&gt; /home/ijas/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:IVrtM2J36uO57J5vwhI7c4+Bd4pRwAZHngYmDxqnuwc ijas@debian
The key&lt;span class="s1"&gt;'s randomart image is:
+---[RSA 4096]----+
|. + +.o          |
| = = * o         |
|o   . X o        |
| .   = + .       |
|E   . o S .      |
| o   ..= =       |
|. .   o++ .      |
| .    =*=B.      |
|      .O%Bo      |
+----[SHA256]-----+
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Use -b flag to specify the bit size. I have used 4096, which is actually much stronger than default.&lt;/li&gt;
&lt;li&gt;You can choose a location to store the keys, best to go with default.&lt;/li&gt;
&lt;li&gt;Passphrase is for an additional layer of security. You can add a strong passphrase if you want, but remember, if you lost it, there is no way to retrieve it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now you can see pair of ssh keys. The .pub is public key.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ijas@debian:~&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; ~/.ssh
total 8
&lt;span class="nt"&gt;-rw-------&lt;/span&gt; 1 ijas ijas 3381 Sep 16 07:49 id_rsa
&lt;span class="nt"&gt;-rw-r--r--&lt;/span&gt; 1 ijas ijas  737 Sep 16 07:49 id_rsa.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can view the content of public key using &lt;code&gt;cat ~/.ssh/id_rsa.pub&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Copying Key to Remote server
&lt;/h2&gt;

&lt;p&gt;To copy the public to the remote server, use this command: &lt;code&gt;ssh-copy-id username@ip-address&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;ijas@debian:~&lt;span class="nv"&gt;$ &lt;/span&gt;ssh-copy-id ijas@192.168.139.147
/usr/bin/ssh-copy-id: INFO: Source of key&lt;span class="o"&gt;(&lt;/span&gt;s&lt;span class="o"&gt;)&lt;/span&gt; to be installed: &lt;span class="s2"&gt;"/home/ijas/.ssh/id_rsa.pub"&lt;/span&gt;
/usr/bin/ssh-copy-id: INFO: attempting to log &lt;span class="k"&gt;in &lt;/span&gt;with the new key&lt;span class="o"&gt;(&lt;/span&gt;s&lt;span class="o"&gt;)&lt;/span&gt;, to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key&lt;span class="o"&gt;(&lt;/span&gt;s&lt;span class="o"&gt;)&lt;/span&gt; remain to be installed &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;you are prompted now it is to &lt;span class="nb"&gt;install &lt;/span&gt;the new keys
ijas@192.168.139.147&lt;span class="s1"&gt;'s password: 

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh '&lt;/span&gt;ijas@192.168.139.147&lt;span class="s1"&gt;'"
and check to make sure that only the key(s) you wanted were added.

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

&lt;/div&gt;



&lt;p&gt;Once copied, you can see the copied public key (authorized_keys) in the remote server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ijas@ubuntu:~&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; ~/.ssh
total 4
&lt;span class="nt"&gt;-rw-------&lt;/span&gt; 1 ijas ijas 737 Sep 16 09:07 authorized_keys
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now when you try to ssh into the remote server, it won't ask for password. (Ensure you are SSHing at the directory where the private key is stored)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ijas@debian:~&lt;span class="nv"&gt;$ &lt;/span&gt;ssh ijas@192.168.139.147
Welcome to Ubuntu 25.04 &lt;span class="o"&gt;(&lt;/span&gt;GNU/Linux 6.15.11-orbstack-00539-g9885ebd8e3f4 aarch64&lt;span class="o"&gt;)&lt;/span&gt;

 &lt;span class="k"&gt;*&lt;/span&gt; Documentation:  https://help.ubuntu.com
 &lt;span class="k"&gt;*&lt;/span&gt; Management:     https://landscape.canonical.com
 &lt;span class="k"&gt;*&lt;/span&gt; Support:        https://ubuntu.com/pro
Last login: Tue Sep 16 09:06:43 2025 from 192.168.139.177
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;SSH keys give you better security, faster logins, and peace of mind, making them the best practice for managing Linux systems.&lt;/p&gt;

&lt;p&gt;Congrats!🎉 You are now one step ahead in your linux journey. Thanks for reading! &lt;/p&gt;

</description>
      <category>linux</category>
      <category>programming</category>
      <category>security</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Fetching Data in React</title>
      <dc:creator>Ijas Ahammed</dc:creator>
      <pubDate>Sun, 23 Feb 2025 11:11:15 +0000</pubDate>
      <link>https://dev.to/ijas9118/fetching-data-in-react-3p65</link>
      <guid>https://dev.to/ijas9118/fetching-data-in-react-3p65</guid>
      <description>&lt;p&gt;Fetching data from an API is a fundamental part of web development. In this guide, we’ll explore how to fetch data efficiently using React, handle loading states, manage errors, and prevent race conditions.&lt;/p&gt;

&lt;h2&gt;
  
  
  📌 Initial Setup
&lt;/h2&gt;

&lt;p&gt;To begin, create a new React application in your code editor. For demonstration purposes, we’ll use the &lt;a href="https://jsonplaceholder.typicode.com/" rel="noopener noreferrer"&gt;JSONPlaceholder API&lt;/a&gt; to fetch posts.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;BASE_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://jsonplaceholder.typicode.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we hit the &lt;code&gt;/posts&lt;/code&gt; endpoint, the API returns data in the following format:&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;"userId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sunt aut facere repellat provident occaecati excepturi optio reprehenderit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"body"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"quia et suscipit..."&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;h2&gt;
  
  
  🏗 Creating State and Interface
&lt;/h2&gt;

&lt;p&gt;Since we’re using TypeScript (which is highly recommended 😜), let’s define an interface for our posts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Post&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, create a state to store the fetched posts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setPosts&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Post&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🔄 Fetching Data with &lt;code&gt;useEffect&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;To fetch data, we’ll use the &lt;code&gt;useEffect&lt;/code&gt; hook, ensuring the request runs once when the component mounts.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetchData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&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;fetch&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;BASE_URL&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/posts`&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;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
    &lt;span class="nf"&gt;setPosts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="nf"&gt;fetchData&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;h3&gt;
  
  
  📝 Key Points:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;fetch&lt;/code&gt; API retrieves data from the endpoint.&lt;/li&gt;
&lt;li&gt;The response is converted to JSON.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;useEffect&lt;/code&gt; dependency array is empty, ensuring the function runs only on mount.&lt;/li&gt;
&lt;li&gt;The fetched posts are stored in state.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🎨 Rendering Posts
&lt;/h2&gt;

&lt;p&gt;Using the &lt;code&gt;map&lt;/code&gt; function, we’ll display the posts in a list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"App"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Data Fetching in React&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;. &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;🔑 &lt;strong&gt;Always provide a unique &lt;code&gt;key&lt;/code&gt;&lt;/strong&gt; when rendering lists in React to avoid rendering issues.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  ⏳ Adding a Loading State
&lt;/h2&gt;

&lt;p&gt;Fetching data takes time, so we should display a loading indicator while waiting for the response.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isLoading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsLoading&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetchData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setIsLoading&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;BASE_URL&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/posts`&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;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
    &lt;span class="nf"&gt;setPosts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;setIsLoading&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="nf"&gt;fetchData&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;Now, update the UI to show a loading message:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"App"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Data Fetching in React&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;isLoading&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Loading...&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;. &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ⚠ Handling Errors
&lt;/h2&gt;

&lt;p&gt;Errors can occur due to network issues or API failures. Let’s handle errors using a state variable and a &lt;code&gt;try-catch&lt;/code&gt; block.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setError&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&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="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetchData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setIsLoading&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="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;BASE_URL&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/posts`&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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Failed to fetch data&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;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
      &lt;span class="nf"&gt;setPosts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;setError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="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="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;setIsLoading&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="nf"&gt;fetchData&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;Modify the UI to display errors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Error: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🏎 Handling Race Conditions
&lt;/h2&gt;

&lt;p&gt;Race conditions occur when multiple API calls return in an unexpected order. To prevent this, we use &lt;code&gt;AbortController&lt;/code&gt; to cancel previous requests.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setPage&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&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;abortControllerRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useRef&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;AbortController&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&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="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetchData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;abortControllerRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;abort&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Cancel previous request&lt;/span&gt;
    &lt;span class="nx"&gt;abortControllerRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&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;AbortController&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nf"&gt;setIsLoading&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="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;BASE_URL&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/posts?page=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;page&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;signal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;abortControllerRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;signal&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;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
      &lt;span class="nf"&gt;setPosts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&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;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;AbortError&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;setError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="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="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;setIsLoading&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="nf"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  📌 Adding Pagination
&lt;/h3&gt;

&lt;p&gt;We’ll add a button to update the page number, triggering a new API request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setPage&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;prev&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  Next Page (&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;)
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;And that’s it! 🚀 You’ve learned how to fetch data efficiently in React, manage loading states, handle errors, and prevent race conditions.&lt;/p&gt;

&lt;p&gt;You can explore the full working example on &lt;a href="https://codesandbox.io/p/sandbox/fetch-data-lxlt8c" rel="noopener noreferrer"&gt;CodeSandbox&lt;/a&gt;. Happy coding! 😃&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>react</category>
    </item>
  </channel>
</rss>
