<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Asela's Blog]]></title><description><![CDATA[Asela's Blog]]></description><link>https://blog.zasela.site</link><generator>RSS for Node</generator><lastBuildDate>Thu, 09 Apr 2026 23:34:05 GMT</lastBuildDate><atom:link href="https://blog.zasela.site/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How to Deploy MERN Application with DigitalOcean]]></title><description><![CDATA[So today, let's have a look at how to deploy the full MERN application.
You can deploy the complete MERN application on a Digital Ocean VPS using the same workflow, even if you choose MySQL instead of]]></description><link>https://blog.zasela.site/how-to-deploy-mern-application-with-digitalocean</link><guid isPermaLink="true">https://blog.zasela.site/how-to-deploy-mern-application-with-digitalocean</guid><dc:creator><![CDATA[Asela Priyadarshana]]></dc:creator><pubDate>Thu, 26 Feb 2026 19:32:11 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/62f5e98069fa1793160beb32/2db8ec44-17e2-4c37-a15c-610ff7dd8b20.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>So today, let's have a look at how to deploy the full MERN application.</p>
<p>You can deploy the complete MERN application on a Digital Ocean VPS using the same workflow, even if you choose MySQL instead of MongoDB. The only part that changes is the database configuration—everything else in the deployment process remains identical.</p>
<p>I will skip the server creation part in this article, you can use any droplet to follow me along.</p>
<p>First Login to your digital ocean server</p>
<pre><code class="language-c">ssh root@&lt;server-ip&gt; -i &lt;private-key&gt;
</code></pre>
<h2>Initial Server Setup with Ubuntu 20.04</h2>
<p>Before we jump into the actual deployment, we need to handle a few essential setup tasks on the server. The first step is creating a user account with limited privileges so we don’t rely on the root user for everyday operations. This is an important security practice because it reduces the risk of accidental system‑wide changes or unauthorized access.</p>
<h3>Creating a user account with limited privileges</h3>
<p>Before we continue with the deployment, let’s create a new user account that we’ll use for day‑to‑day server operations. This is safer than using the <code>root</code> account directly.</p>
<pre><code class="language-plaintext">adduser &lt;user-name&gt;
</code></pre>
<p>This command creates a regular user with limited privileges, which is the recommended way to manage a Linux server</p>
<p><strong>Granting administrative privileges (without becoming full root)</strong></p>
<p>Even though this user is non‑root, we still need the ability to install packages, manage services, and perform system‑level tasks during setup. For that, we can add the user to the <strong>sudo</strong> group.</p>
<p>This does <em>not</em> give full root privileges permanently. Instead, it allows the user to run specific commands as root using <code>sudo</code>, which is safer because every privileged action requires confirmation</p>
<pre><code class="language-plaintext">usermod -aG sudo &lt;user-name&gt;
</code></pre>
<p>Now the new user can perform administrative tasks when needed, but still operates as a normal user by default</p>
<p><strong>Copying your SSH key to the new user</strong></p>
<p>To log in as this new user using SSH, we need to make sure they have the same SSH key we used earlier. The easiest way is to copy your existing <code>.ssh</code> directory to the new user’s home folder and set the correct ownership.</p>
<pre><code class="language-plaintext">rsync --archive --chown=asela:asela ~/.ssh /home/asela
</code></pre>
<p>This ensures:</p>
<ul>
<li><p>The new user can log in using your existing SSH key.</p>
</li>
<li><p>File permissions remain correct.</p>
</li>
<li><p>You don’t need to generate a new key unless you prefer to.</p>
</li>
</ul>
<p>If you want to use a separate SSH key for this user, you can generate a new one and place it in <code>/home//.ssh/authorized_keys</code> instead.</p>
<hr />
<p>Next, we’ll enable SSH access through UFW (Uncomplicated Firewall). If you’re new to UFW, think of it as a simple tool that controls which network traffic is allowed into your server. By default, most servers keep all ports closed for safety, and UFW helps you explicitly open only the ones you need. For example, SSH uses port 22, so enabling SSH in UFW ensures you can connect to your server remotely without exposing unnecessary services to the internet.</p>
<p><strong>Checking available UFW application profiles</strong></p>
<p>UFW comes with predefined profiles for common services. You can list them with:</p>
<pre><code class="language-shell">ufw app list
</code></pre>
<blockquote>
<p>This shows entries like <code>OpenSSH</code>, <code>Nginx Full</code>, <code>Nginx HTTP</code>, etc. Each profile contains the ports that service needs.</p>
</blockquote>
<p><strong>Allowing SSH connections</strong></p>
<p>If <code>OpenSSH</code> appears in the list, you can allow it directly:</p>
<pre><code class="language-shell">ufw allow OpenSSH
</code></pre>
<p>This opens port 22 so you can continue connecting to your server via SSH. If this rule isn’t added, enabling the firewall would block SSH and disconnect you.</p>
<p><strong>Enabling UFW and verifying status</strong></p>
<p>Once SSH is allowed, you can safely enable the firewall:</p>
<pre><code class="language-plaintext">ufw enable
</code></pre>
<p>After enabling, check the status to confirm your rules are active:</p>
<pre><code class="language-plaintext">ufw status
</code></pre>
<p>This should show the services that enabled by the ufw.</p>
<p>Later in the article, we’ll configure UFW more precisely for your application—opening only the required ports and keeping everything else locked down. And if all of this sounds unfamiliar, don’t worry. I’ll walk you through UFW step by step, explain what each rule does, and show you how to keep your server secure without needing deep networking knowledge.</p>
<p><strong>Alright, Now let's switch the user and start doing the server setup</strong></p>
<h2>Switching to the new user</h2>
<p>Now that the user account is created and SSH access is configured, switch into that user so all remaining setup happens under a safer, non‑root environment.</p>
<pre><code class="language-plaintext">su - asela
</code></pre>
<blockquote>
<p>The <code>-</code> ensures you load the user’s full environment, including their home directory and shell configuration</p>
</blockquote>
<h3>Updating package lists</h3>
<p>Before installing anything, refresh your package index so the server knows about the latest versions available in the repositories</p>
<pre><code class="language-plaintext">sudo apt-get update
</code></pre>
<blockquote>
<p>This doesn’t install updates yet—it simply updates the list of available packages. It’s a good habit to run this before any installation.</p>
</blockquote>
<h3>Checking server status with <code>htop</code></h3>
<p>To get a quick overview of your server’s performance—CPU usage, memory usage, running processes—you can use .</p>
<pre><code class="language-plaintext">htop
</code></pre>
<blockquote>
<p><code>htop</code> gives you a live, interactive dashboard that’s much easier to read than the traditional <code>top</code> command. It’s especially useful right after deployment to confirm your server is running smoothly and not overloaded.</p>
</blockquote>
<h2>Installing Node.js</h2>
<p>Node.js isn’t included in Ubuntu’s default repositories in its latest LTS form, so the recommended approach is to use the official NodeSource repository. This ensures you always get the correct and up‑to‑date version.</p>
<p>Start by moving to your home directory:</p>
<pre><code class="language-shell">cd ~
</code></pre>
<p>Then download and run the NodeSource setup script for Node.js 20.x (the current LTS release):</p>
<pre><code class="language-shell">curl -sL https://deb.nodesource.com/setup_20.x | sudo -E bash
</code></pre>
<blockquote>
<p>This script adds the NodeSource PPA and updates your package list automatically. Once that’s done, install Node.js:</p>
</blockquote>
<p>Install the nodejs to the server.</p>
<pre><code class="language-plaintext">sudo apt-get install -y nodejs
</code></pre>
<h3>Installing build tools for npm package</h3>
<p>Some npm packages need to compile native code during installation. To support that, install the <strong>build-essential</strong> package, which includes GCC, G++, and make.</p>
<pre><code class="language-plaintext">sudo apt install build-essential
</code></pre>
<blockquote>
<p>This ensures your environment can handle any package that requires compilation.</p>
</blockquote>
<h3>Cloning the project repository</h3>
<p>With Node.js installed and the server ready, the next step is to bring our project code onto the machine. Use <code>git clone</code> to download your repository:</p>
<pre><code class="language-plaintext">git clone https://github.com/zaselalk/MERN-Workshop---7th-Batch.git
</code></pre>
<blockquote>
<p>This creates a new folder containing both the backend and frontend code for your MERN application.</p>
</blockquote>
<h3>Installing backend dependencies</h3>
<p>Before running anything, move into the backend directory and install the required Node packages.</p>
<pre><code class="language-plaintext">cd client
npm install
</code></pre>
<p>At this point, you may notice errors—especially if your backend expects a database connection. That’s completely normal because the database isn’t installed yet. Let’s fix that next.</p>
<h3>Installing MySQL Server</h3>
<p>Your backend needs a database to store and retrieve data. Install MySQL Server using:</p>
<pre><code class="language-plaintext">sudo apt install mysql-server
</code></pre>
<p>Once installed, run the security script to configure your MySQL instance</p>
<pre><code class="language-plaintext">sudo mysql_secure_installation
</code></pre>
<p>This helps you set a root password, remove anonymous users, disable remote root login, and apply other recommended security settings</p>
<h3>Creating the project database</h3>
<pre><code class="language-plaintext">CREATE DATABASE mern_project;
</code></pre>
<h3>Checking existing MySQL users</h3>
<p>Now we want to know the username and password to access the mysql instance via the application.</p>
<p>let's see which users currently exist in your MySQL instance, for that run,</p>
<pre><code class="language-plaintext">SELECT User, Host FROM mysql.user;
</code></pre>
<p>By running above command you can see that there are number of system users available, Let's create new user to use application database, then we can only give the permission for our database.</p>
<h3>Creating a dedicated MySQL user</h3>
<p>update the user name with your own name and also make sure to add secure password.</p>
<pre><code class="language-plaintext">CREATE USER 'asela'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';
</code></pre>
<h3>Granting database privileges</h3>
<p>Once the user exists, you need to give them permission to work with your project database:</p>
<pre><code class="language-plaintext">GRANT ALL ON mern_project.* TO 'asela'@'localhost';
</code></pre>
<blockquote>
<p>This grants full access (SELECT, INSERT, UPDATE, DELETE, etc.) to all tables inside the database, but only for this database. The user cannot touch other databases on the server.</p>
</blockquote>
<h3>Applying the changes</h3>
<p>MySQL caches privilege information, so you must reload it:</p>
<pre><code class="language-shell">FLUSH PRIVILEGES;
</code></pre>
<blockquote>
<p>This ensures the new permissions take effect immediately</p>
</blockquote>
<p>Now let's try to up the server by providing the database information. Once the server is on the vps, we can test that using the <code>curl</code> command.</p>
<hr />
<p>Now let's available our application for outside users as well. for that we need a web server. let's install the <code>nginx</code>.</p>
<h2>Installing Nginx as the web server</h2>
<p>Nginx will act as the front-facing web server for your application. Install it using:</p>
<pre><code class="language-plaintext">sudo apt install nginx
</code></pre>
<p>After installation, confirm that the service is running, You should see it listed as active (running).</p>
<pre><code class="language-plaintext">systemctl status nginx
</code></pre>
<h3>Enabling UFW and allowing necessary services</h3>
<p>Before enabling the firewall, make sure SSH is allowed so you don’t lock yourself out. Since you already enabled SSH earlier, now you can safely turn on UFW:</p>
<pre><code class="language-shell">sudo ufw enable
</code></pre>
<p>To see the available application profiles</p>
<pre><code class="language-plaintext">sudo ufw app list
</code></pre>
<p>You’ll typically see profiles like:</p>
<ul>
<li><p>Nginx Full</p>
</li>
<li><p>Nginx HTTP</p>
</li>
<li><p>Nginx HTTPS</p>
</li>
<li><p>OpenSSH</p>
</li>
</ul>
<p>Since we plan to serve application through Nginx, let's allow the full profile:</p>
<pre><code class="language-plaintext">sudo ufw allow 'Nginx Full'
</code></pre>
<p>Then verify the firewall status by <code>sudo ufw status</code> , confirms that Nginx and SSH are allowed while all other ports remain protected</p>
<h3>Opening a custom port (for testing only)</h3>
<p>Let's do experiment with temporarily expose our Node.js server directly, you can open port 3000 by using following command.</p>
<pre><code class="language-shell">sudo ufw allow 3000/tcp
</code></pre>
<p>This allows external access to your Node.js app running on port 3000.</p>
<p><strong>Why exposing port 3000 directly is not ideal</strong></p>
<p>Direct exposure is fine for development or internal tools, but not great for production because:</p>
<ul>
<li><p>No HTTPS</p>
</li>
<li><p>No caching or rate limiting</p>
</li>
<li><p>No protection from malformed requests</p>
</li>
<li><p>No domain support</p>
</li>
</ul>
<p>That’s why most production setups use <strong>Nginx as a reverse proxy</strong>. Let's remove that rule and enable the reverse proxy,</p>
<h4>Remove the rule</h4>
<p>Find the specific number of the rule by running the first command and then delete that rule using the second command.</p>
<pre><code class="language-plaintext">sudo ufw status numbered
sudo ufw delete &lt;number&gt;
</code></pre>
<h3>Config the Nginx Reverse Proxy</h3>
<h4>Navigate to the Nginx sites‑available directory and create a new configuration file for our app:</h4>
<pre><code class="language-plaintext">sudo nano /etc/nginx/sites-available/mern
</code></pre>
<p>Add the following server block:</p>
<pre><code class="language-plaintext">server {
    listen 80;
    server_name [ip or domain];

    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}
</code></pre>
<blockquote>
<p>This tells Nginx to listen on port 80 (HTTP) and forward all incoming requests to your Node.js app running on localhost:3000. The headers ensure WebSocket support and proper request forwarding.</p>
</blockquote>
<h3>Enabling the configuration</h3>
<p>Nginx only loads configurations that exist inside sites‑enabled. Create a symbolic link from your new config file:</p>
<pre><code class="language-plaintext">sudo ln -s /etc/nginx/sites-available/myapi /etc/nginx/sites-enabled/
</code></pre>
<p>This activates the configuration without duplicating files</p>
<h3>Testing and reloading Nginx</h3>
<p>Before applying changes, test the configuration for syntax errors and if there is no any error run the reload command to reload the configurations.</p>
<pre><code class="language-plaintext">sudo nginx -t
sudo systemctl reload nginx
</code></pre>
<p>If that process success, the server should be working properly. Then we can also map the domain and setup SSL, for that we need to map the domain to the api</p>
<p>Setup the DNS record to the VPS public IP and update the server block to that newly pointed domain. after we can also install the SSL for the site.</p>
<pre><code class="language-plaintext">sudo apt install certbot python3-certbot-nginx
</code></pre>
<p>make sure that server name on the block has set properly. the run the following command to setup the SSL.</p>
<pre><code class="language-plaintext"> sudo certbot --nginx -d mern.zasela.site
</code></pre>
<hr />
<h3>Let's build the react app.</h3>
<p>Before building the app make sure to update the backend URL with new URL.</p>
<pre><code class="language-plaintext">npm run build
</code></pre>
<pre><code class="language-plaintext">sudo cp -r dist/ /var/www/mern-client/
</code></pre>
<p>We also want to create a server block for the client as well. make sure to update the server name.</p>
<pre><code class="language-plaintext">server {
    listen 80;
    server_name [server_ip];

    root /var/www/mern-client;
    index index.html;

    location / {
        try_files $uri /index.html;
    }
}
</code></pre>
<p>After enable the config as we did in the API</p>
<pre><code class="language-plaintext">sudo ln -s /etc/nginx/sites-available/mern-client /etc/nginx/mern-client
</code></pre>
<p>reload the server to see the site.</p>
<pre><code class="language-plaintext">sudo systemctl reload nginx
</code></pre>
<p>You might notice that we need to stop the server because it's running on the terminal, we can run that in background using pm2, with more capabilities.</p>
<h3>Installing PM2</h3>
<p>Next let’s install PM2, a process manager for Node.js applications. PM2 makes it possible to daemonize applications so that they will run in the background as a service.</p>
<pre><code class="language-plaintext">sudo npm install pm2@latest -g
</code></pre>
<p>Now you can start Application by <code>pm2 start hello.js</code></p>
]]></content:encoded></item><item><title><![CDATA[DevContainer - Yes you can ship your laptop to another developer ! 🫡]]></title><description><![CDATA[After a short break from my writing journey, today I plan to share my experience with dev containers and what I’ve learned about them. I’m still fairly new to the concept, so I hope to share more insights as I continue to explore it in the future.
I ...]]></description><link>https://blog.zasela.site/devcontainer-yes-you-can-ship-your-laptop-to-another-developer</link><guid isPermaLink="true">https://blog.zasela.site/devcontainer-yes-you-can-ship-your-laptop-to-another-developer</guid><category><![CDATA[devcontainer]]></category><dc:creator><![CDATA[Asela Priyadarshana]]></dc:creator><pubDate>Sat, 14 Feb 2026 12:17:08 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1771071103864/ac929c57-1d5d-448d-9f5b-771eda8478d1.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>After a short break from my writing journey, today I plan to share my experience with dev containers and what I’ve learned about them. I’m still fairly new to the concept, so I hope to share more insights as I continue to explore it in the future.</p>
<p>I usually use Docker when I want to maintain the same runtime for both production and development environments.</p>
<p>One day, I came across a tool called “DevContainer.” I had first learned about it a few months earlier and wondered why it was necessary for maintaining a consistent environment across devices when we already have Docker for that purpose.</p>
<p>And so, on that day, I thought there might be something to this, but it wasn’t useful for me at the time. I decided to remember the name for the day I’d want to use DevContainer. That day is today.</p>
<p>Now I realize DevContainer isn’t just a Docker wrapper, but a feature-rich tool that makes it easy to replicate our development environment.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1771071146893/445833e6-dd22-40a4-a77c-a69a83650f45.png" alt class="image--center mx-auto" /></p>
<p>If you’ve spent enough time wrestling with inconsistent dev setups, you eventually reach a point where I was also struggle.</p>
<p>That’s where Dev Containers really change the game. While doing my research, I ran into the hassle of installing countless tools just to recreate the supporting environment. It was a nightmare, so I decided to check out the Dev Container.</p>
<p>The Docker doesn’t care about your editor, your extensions, your debugging tools, or your onboarding experience. It’s not supposed to — But Dev Container does.</p>
<p>Inside a Dev Container, we can define: programming language versions, build tools,VS Code extensions etc.</p>
<p>In simple term <strong>DevContainer</strong> is fully configured workstation is with the help of container that any other developer can replicate easily, without sending hundred of WA message for you asking “why this package is not running on my laptop - who knows actually 😒.</p>
<h2 id="heading-dev-containers-your-entire-development-environment-in-a-box"><strong>Dev Containers: Your entire development environment in a box</strong></h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1771071346458/e71a5189-bc17-4893-b702-66027fc472f2.png" alt class="image--center mx-auto" /></p>
<p>A Dev Container takes the idea of “environment consistency” and pushes it all the way to your editor.</p>
<p>It doesn’t just run your app. It runs <strong>you</strong> — your tools, your workflow, your coding habits.</p>
<p>Inside a Dev Container, you can define:</p>
<ul>
<li><p>Programming language versions</p>
</li>
<li><p>Build tools</p>
</li>
<li><p>Linters and formatters</p>
</li>
<li><p>VS Code extensions</p>
</li>
<li><p>debugging configuration</p>
</li>
<li><p>environment variables</p>
</li>
<li><p>Post‑create automation scripts</p>
</li>
<li><p>Even your Git settings</p>
</li>
</ul>
<p>It’s your development laptop, but reproducible, shareable, and version‑controlled. That’s why in the earlier I said this is a way to ship your laptop to another developer.</p>
<p>And the best part is that, VS Code orchestrates everything. You open the project, and it builds the environment for you. No manual Docker commands. No “install this first.” No “works on my machine.”</p>
<h2 id="heading-the-philosophical-difference"><strong>The philosophical difference</strong></h2>
<p>I know that at first the concept might not be familiar, and you still wonder why we need a devcontainer when we already have Docker to maintain a consistent environment. I was also</p>
<p>Here’s the simplest way I internalize it:</p>
<ul>
<li><p><strong>Docker cares about the application.</strong></p>
</li>
<li><p><strong>Dev Containers care about the developer.</strong></p>
</li>
</ul>
<p>Refer the full table to get broad idea about the difference between docker and dev container.</p>
<h1 id="heading-docker-vs-dev-container"><strong>Docker vs Dev Container</strong></h1>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Category</td><td><strong>Docker</strong></td><td><strong>Dev Container</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>Primary Purpose</strong></td><td>Runs your <strong>application</strong> in an isolated environment</td><td>Runs your <strong>entire development environment</strong> inside a container</td></tr>
<tr>
<td><strong>Who Manages It</strong></td><td>Docker Engine / CLI</td><td>VS Code (or GitHub Codespaces) orchestrates it using Docker</td></tr>
<tr>
<td><strong>Configuration Files</strong></td><td><code>Dockerfile</code>, <code>docker-compose.yml</code></td><td><code>.devcontainer/devcontainer.json</code> + optional <code>Dockerfile</code></td></tr>
<tr>
<td><strong>Focus Area</strong></td><td>Runtime consistency</td><td>Development consistency</td></tr>
<tr>
<td><strong>What It Contains</strong></td><td>App runtime, dependencies, minimal OS</td><td>Toolchains, debuggers, VS Code extensions, environment variables, scripts, plus everything Docker has</td></tr>
<tr>
<td><strong>Lifecycle</strong></td><td>Build → Run → Deploy</td><td>Open project → VS Code builds container → Develop inside it</td></tr>
<tr>
<td><strong>Typical Use Case</strong></td><td>Microservices, production workloads, CI/CD</td><td>Onboarding, reproducible dev setups, isolated toolchains</td></tr>
<tr>
<td><strong>User Experience</strong></td><td>You run containers manually</td><td>VS Code auto‑builds and attaches your editor to the container</td></tr>
<tr>
<td><strong>Environment Scope</strong></td><td>Only the app environment</td><td>Full developer workstation (inside a container)</td></tr>
<tr>
<td><strong>Portability</strong></td><td>Portable runtime</td><td>Portable development workflow</td></tr>
<tr>
<td><strong>Isolation Level</strong></td><td>Isolates the app from the host</td><td>Isolates the host from the app’s dev dependencies</td></tr>
<tr>
<td><strong>Tooling Support</strong></td><td>CLI‑driven</td><td>Editor‑driven (VS Code UI + commands)</td></tr>
<tr>
<td><strong>Debugging</strong></td><td>Requires manual setup</td><td>Preconfigured in <code>devcontainer.json</code></td></tr>
<tr>
<td><strong>Team Collaboration</strong></td><td>Ensures app runs the same everywhere</td><td>Ensures developers code the same everywhere</td></tr>
<tr>
<td><strong>Learning Curve</strong></td><td>Docker concepts (images, containers, volumes, networks)</td><td>Docker concepts + VS Code Dev Container features</td></tr>
<tr>
<td><strong>Philosophy</strong></td><td>“Package the app.”</td><td>“Package the developer environment.”</td></tr>
</tbody>
</table>
</div><p>When looking at a table you can see that the DevContainer gives us a capabilities to reproduce the developer environment very easily.</p>
<p>Honestly, not much — except that once you get used to Dev Containers, you start wondering why you ever installed toolchains directly on your OS. Your machine becomes lighter. Cleaner. Less fragile.</p>
<p>And your projects become more portable, more reproducible, and easier to maintain.</p>
<h2 id="heading-final-thought"><strong>Final thought</strong></h2>
<p>Docker gave us consistent application environments. Dev Containers give us consistent developer environments. If Docker is the engine, <strong>the Dev Container is the entire workshop built around it.</strong></p>
<p>Let’s see how we create a DevContainer environment in action in future article, if you can’t wait until that article, just ask from your favorite LLM 😎.</p>
<p>Have a nice day 👋..</p>
]]></content:encoded></item><item><title><![CDATA[[Day 03] - Laptop to Lab -- Lot of Questions]]></title><description><![CDATA[You already know that I’m in the process of converting my old laptop into a server for my experiments. So far, we have installed headless Debian to make the server more lightweight.
Now let’s move on to what we plan to do today, But when tried to log...]]></description><link>https://blog.zasela.site/day-03-laptop-to-lab-lot-of-questions</link><guid isPermaLink="true">https://blog.zasela.site/day-03-laptop-to-lab-lot-of-questions</guid><category><![CDATA[server]]></category><category><![CDATA[Homelab]]></category><dc:creator><![CDATA[Asela Priyadarshana]]></dc:creator><pubDate>Sun, 08 Feb 2026 18:10:06 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1770574152771/6e8524ec-fca2-4129-a360-cae13e7046a4.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>You already know that I’m in the process of converting my old laptop into a server for my experiments. So far, we have installed headless Debian to make the server more lightweight.</p>
<p>Now let’s move on to what we plan to do today, But when tried to log in to the server for the first time today, I got this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1770567376867/0ab8fe2c-af12-44ce-8b1f-9b5b1d383b02.png" alt class="image--center mx-auto" /></p>
<p>I was a bit confused by this error at first because I had already logged in to the server via SSH on day 2. After doing some searching, I realized that when I was using Linux Mint before installing the new OS, I had also connected to the old laptop through SSH on my local network. At that time, the laptop’s local IP was <strong>192.168.8.132</strong>, but on day 2 I used the <strong>x.x.x.133</strong> IP instead</p>
<p>Since my computer had saved the SSH details for the laptop when it was using the <strong>.132</strong> IP, it detected something was wrong. From the computer’s perspective, I was actually the imposter.</p>
<p>The reason is simple: the server’s <strong>fingerprint</strong> changed. SSH blocks the connection to protect you from a man‑in‑the‑middle attack, where someone might pretend to be your server and intercept your data. In this case, I’m the “imposter” because I replaced the old system with a new one.</p>
<p>To fix this, I told my machine to forget the previous fingerprint</p>
<pre><code class="lang-bash">ssh-keygen -R 192.168.8.132
</code></pre>
<p>After I try to login to server again and now I’m able to login without any problem.</p>
<h3 id="heading-more-problems">More Problems</h3>
<p>Now I can log in to the account, but I still have another problem. When I close the lid of my laptop, the laptop turns off, which causes the server to shut down. To fix this, I edited the <code>logind.conf</code> file</p>
<pre><code class="lang-bash">sudo nano /etc/systemd/logind.conf
</code></pre>
<p>I change the <code>HandleLidSwitch=ignore</code> to prevent my laptop shut down when the lid close, Once I restart the logind server, Now I’m able to close the lid, But still my server up and running.</p>
<p>Then I ran into another issue: when I tried to use the <code>sudo</code> command, I got an error saying that <code>sudo</code> was not found. I was a bit confused because I assumed every Linux system included the <code>sudo</code> command — but later I discovered that this isn’t always the case.</p>
<p>When I looked into the issue, I learned that…</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">In the Debian world, if you provide a root password during installation, the installer assumes you want to manage administrative tasks by logging directly into the <code>root</code> account, so it doesn't install the <code>sudo</code> package by default.</div>
</div>


<p>But I prefer to use the <code>sudo</code> command with my personal account (I’m still not entirely sure whether this is recommended, but let’s see). So I decided to install the <code>sudo</code> package.</p>
<pre><code class="lang-bash">apt update &amp;&amp; apt install sudo
</code></pre>
<p>After I added my personal account to the <code>sudo</code> group, I was able to use the <code>sudo</code> command from my personal account as well.</p>
<h3 id="heading-install-ollama">Install Ollama</h3>
<p>Now let’s do some experiments with Ollama. First, we’ll install Ollama and try an open‑source model. Later, we can try some cool things with Docker as well.</p>
<pre><code class="lang-bash">curl -fsSL https://ollama.com/install.sh | sh
</code></pre>
<p>But before run this command, I also wanna install curl to my linux system.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1770568608992/4e46d422-26c4-4485-b59d-cedafc2fc741.png" alt class="image--center mx-auto" /></p>
<p>The I install <code>llama3.2</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1770572615309/08c0b496-c7a1-4000-b730-32f70a43a7bf.png" alt class="image--center mx-auto" /></p>
<p>It’s working! Now the <code>llama3.2:latest (3B)</code> model is running on my server locally without any cost.</p>
<p>What’s next? Next, I plan to install a web UI so my other devices can access it through a browser. Let’s check that out in action on Day 4 😎</p>
<p>Until then, see you guys!</p>
]]></content:encoded></item><item><title><![CDATA[I setup VPC using Terraform]]></title><description><![CDATA[These days I’m following the terraform learning path from the KodeKloud to learn about the Terraform for my research, so I decided to write about the task that I have done today.
If you don’t know about the Terraform, It’s a Infrastructure as Code (I...]]></description><link>https://blog.zasela.site/i-setup-vpc-using-terraform</link><guid isPermaLink="true">https://blog.zasela.site/i-setup-vpc-using-terraform</guid><category><![CDATA[Terraform]]></category><dc:creator><![CDATA[Asela Priyadarshana]]></dc:creator><pubDate>Sat, 07 Feb 2026 13:07:01 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1770469557116/fdc9e42f-2cb2-43bd-ac18-e18331faecd0.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>These days I’m following the terraform learning path from the KodeKloud to learn about the Terraform for my research, so I decided to write about the task that I have done today.</p>
<p>If you don’t know about the Terraform, It’s a <strong>Infrastructure as Code (IaC)</strong> tool created by <strong>HashiCorp</strong> that lets us define, provision, and manage cloud and on‑prem infrastructure. Basically we able to version control and automate infrastructure setup.</p>
<p>Today my task is to setup Virtual Private Cloud (VPC),</p>
<p>If you don’t know about the VPC — Its a <strong>virtual network</strong> dedicated to your AWS account. It is logically isolated from other virtual networks in the AWS Cloud. It gives you full control over your networking environment.</p>
<p>Don’t confuse with the virtual machine concept, I also confuse in first time… !</p>
<p>Think of an AWS VPC as the <strong>building</strong> or the <strong>private property</strong>, while a Virtual Machine (called an EC2 instance in AWS) is the <strong>computer</strong> you place inside one of the rooms.</p>
<p>It gives full control over,</p>
<ul>
<li><p><strong>IP Address Ranges:</strong> Choosing your own private IP space.</p>
</li>
<li><p><strong>Subnets:</strong> Dividing your network into smaller sections (e.g., a "Public" section for web servers and a "Private" section for databases).</p>
</li>
<li><p><strong>Routing:</strong> Deciding which traffic can go to the internet and which stays internal.</p>
</li>
<li><p><strong>Security:</strong> Using Firewalls (Network ACLs and Security Groups) to lock down access.</p>
</li>
</ul>
<p>Here is a side by side comparison ,</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Feature</strong></td><td><strong>VPC (Virtual Private Cloud)</strong></td><td><strong>EC2 (Elastic Compute Cloud)</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>Category</strong></td><td>Networking</td><td>Compute</td></tr>
<tr>
<td><strong>Analogy</strong></td><td>The private land/fenced yard</td><td>The house or equipment on the land</td></tr>
<tr>
<td><strong>Purpose</strong></td><td>To define where and how data travels</td><td>To run code, apps, and OS</td></tr>
<tr>
<td><strong>Identity</strong></td><td>Defined by CIDR blocks (IP ranges)</td><td>Defined by CPU, RAM, and Storage</td></tr>
<tr>
<td><strong>Is it a VM?</strong></td><td><strong>No</strong>, it's the network infrastructure</td><td><strong>Yes</strong>, it is a Virtual Machine</td></tr>
</tbody>
</table>
</div><h2 id="heading-move-to-the-question">Move to the Question</h2>
<p>This question was very easy one and my task is to Create a VPC named <code>xfusion-vpc</code> in <code>us-east-1</code> region with <code>192.168.0.0/24</code> IPv4 CIDR using terraform.</p>
<p>Here is the code example.</p>
<pre><code class="lang-plaintext">resource "aws_vpc" "xfusion-vpc" {
    cidr_block = "192.168.0.0/24"

    tags = {
        Name = "xfusion-vpc"
    }
}
</code></pre>
<p>If you don’t have any idea about the terraform code, let me example the code,</p>
<p>Here we define the resource called “aws_vpc”, that names as “datacenter_vpc”, this name like a variable name that we can refer the created VPC in our infrastructure.</p>
<p><code>cidr_block = "192.168.0.0/24"</code>: This defines the IP address range for your network. The <code>/24</code> means you have a range of 256 IP addresses (from <code>192.168.0.0</code> to <code>192.168.0.255</code>).</p>
<p><code>tags</code>: This is a map of labels. Setting the <code>Name</code> tag to <code>datacenter-vpc</code> is what actually makes that name show up in the "Name" column of AWS Management Console.</p>
<p>That’s pretty much everthing that I want to do for complete this task, but make sure that in order to run this code, we needed to setup the provider, In this case aws. I’m not set the provider here because KodeKloud do it for me.</p>
]]></content:encoded></item><item><title><![CDATA[How I Learned to "See" Math: My Journey into Matrices and Python]]></title><description><![CDATA[I’ve always heard people talk about Linear Algebra as this scary, and I must admit because, I feel the same way. When I first studied the matrices as the university subject, that was really boring for me.
I was always asked my self why I did learn th...]]></description><link>https://blog.zasela.site/how-i-learned-to-see-math-my-journey-into-matrices-and-python</link><guid isPermaLink="true">https://blog.zasela.site/how-i-learned-to-see-math-my-journey-into-matrices-and-python</guid><category><![CDATA[Learning Journey]]></category><category><![CDATA[Maths]]></category><dc:creator><![CDATA[Asela Priyadarshana]]></dc:creator><pubDate>Fri, 06 Feb 2026 18:39:08 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1770403094073/b389c634-ac74-4d53-ac54-2065106fe7fb.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I’ve always heard people talk about Linear Algebra as this scary, and I must admit because, I feel the same way. When I first studied the matrices as the university subject, that was really boring for me.</p>
<p>I was always asked my self why I did learn this, but I didn’t ask that question from LLM, because at the time LLM are not much popular. Today I did it because those days I try to improve my Maths knowledge.</p>
<p>So I started to learn about matrix, but not as the boring theory, instead with some examples in python. I sat down with an AI tutor ( Gemini) , and instead of memorizing boring formulas, I learned how to actually <em>play</em> with the numbers.</p>
<p>Here’s a recap of what I learned, from the basics of grids to editing images with pure math.</p>
<h2 id="heading-1-the-matrix-its-just-a-spreadsheet">1. The Matrix: It’s Just a Spreadsheet</h2>
<p>The biggest "Aha!" moment came right at the start. A matrix isn’t magic; it’s just a grid. It’s a way to organize data into <strong>Rows</strong> (horizontal) and <strong>Columns</strong> (vertical).</p>
<p>If you have a list of numbers, that’s a vector. If you stack them up, that’s a matrix.</p>
<p>We describe them by their size (Dimensions). A <code>2 × 3</code> matrix has 2 rows and 3 columns. Simple, right?</p>
<h2 id="heading-2-the-rules-of-engagement">2. The Rules of Engagement</h2>
<p>I learned that you can’t just smash two matrices together. There are rules:</p>
<ul>
<li><p><strong>Addition / Subtract :</strong> We can only add or sub matrices if they are the exact same size. It’s like stacking egg cartons—the cups have to line up.</p>
</li>
<li><p><strong>Multiplication (The Boss Level):</strong> This was tricky! To multiply Matrix A and Matrix B, the <em>columns</em> of the first one must match the <em>rows</em> of the second. And you don’t just multiply numbers; you do a "Row by Column" swipe (the Dot Product).</p>
</li>
</ul>
<h2 id="heading-3-the-magic-of-identity">3. The Magic of Identity</h2>
<p>I discovered the <strong>Identity Matrix (I)</strong>. It’s a square grid filled with 0s, but with a diagonal line of 1s down the middle. It acts like the number <strong>1</strong>.</p>
<p>If we multiply any matrix by the Identity Matrix, nothing changes. It’s the "neutral" gear of Linear Algebra.</p>
<h2 id="heading-4-coding-it-in-python">4. Coding It in Python</h2>
<p>Theory is nice, but code is better. I fired up Python and used a library called <strong>NumPy</strong>, here is the notebook that I have tried, feel free to play with it.</p>
<p><a target="_blank" href="https://gist.github.com/zaselalk/19d292a73f93b9f432b0277dd16b2934">https://gist.github.com/zaselalk/19d292a73f93b9f432b0277dd16b2934</a></p>
<div class="gist-block embed-wrapper" data-gist-show-loading="false" data-id="19d292a73f93b9f432b0277dd16b2934"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a href="https://gist.github.com/zaselalk/19d292a73f93b9f432b0277dd16b2934" class="embed-card">https://gist.github.com/zaselalk/19d292a73f93b9f432b0277dd16b2934</a></div><p> </p>
<h2 id="heading-5-the-grand-finale-images-are-matrices">5. The Grand Finale: Images ARE Matrices!</h2>
<p>This was the coolest part. I learned that every digital photo is just a giant matrix of numbers representing brightness.</p>
<p>I wrote a few lines of Python to generate a <code>100 x 100</code> matrix, and when I visualized it, it wasn't just numbers—it was a picture! That was soo cool 😎</p>
<h3 id="heading-my-takeaway">My Takeaway</h3>
<p>Math isn't just about solving for <code>x</code>. It's the engine behind the images we see, the games we play, and the data we analyze. Today, I stopped looking at matrices as homework and started seeing them as tools.</p>
]]></content:encoded></item><item><title><![CDATA[[Day 02] - My Journey from Laptop to Lab -- Server setup successfully..]]></title><description><![CDATA[This is the second day of my Journey make my laptop server, If you are not read the first version yet kindly read that article first [Day 01] - My Journey from Laptop to Lab: Building a Headless Debian Server for DevOps & AI
Alright now it’s time for...]]></description><link>https://blog.zasela.site/day-02-my-journey-from-laptop-to-lab-server-setup-successfully</link><guid isPermaLink="true">https://blog.zasela.site/day-02-my-journey-from-laptop-to-lab-server-setup-successfully</guid><category><![CDATA[serversetup]]></category><category><![CDATA[learning]]></category><category><![CDATA[Learning Journey]]></category><category><![CDATA[#learning-in-public]]></category><category><![CDATA[server]]></category><dc:creator><![CDATA[Asela Priyadarshana]]></dc:creator><pubDate>Fri, 06 Feb 2026 00:30:39 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1770300708938/466aa98b-e77d-4d90-84ef-57e58cd8cf2e.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This is the second day of my Journey make my laptop server, If you are not read the first version yet kindly read that article first <a target="_blank" href="https://blog.zasela.site/day-01-my-journey-from-laptop-to-lab-building-a-headless-debian-server-for-devops-and-ai">[Day 01] - My Journey from Laptop to Lab: Building a Headless Debian Server for DevOps &amp; AI</a></p>
<p>Alright now it’s time for try the new OS, In day 01 you might remember that I downloaded and update the bootable device with Debian 13, then let’s see what to do today.</p>
<p>I start the install <code>debian-13.3.0-amd64-netinst</code> and when I go through the process, I got steps like setup domain, setup admin password (<code>/root</code>) and setup user account by giving the full name, username, password.</p>
<p>Then I came the process to setup the disk, At that process the Linux installation ask me to whether follow the guided setups or manual steps to install the system. I selected the manual method, because wanna fresh installation.</p>
<p>Then I got the following screen,</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1770296761344/887b9456-422a-494a-ab0b-3fa8532b7c95.jpeg" alt="The current disk status" class="image--center mx-auto" /></p>
<p>I have the deleted all the partitions in both SSD (<code>sda</code>) and the HDD (<code>sdb</code>), and I created two manual partitions for the server to run,</p>
<ul>
<li><p>536MB - EFI System partition</p>
</li>
<li><p>127.5GB - ext4 partition for server</p>
</li>
</ul>
<p>The <strong>EFI System Partition (ESP)</strong> is a critical, OS-independent partition that serves as the storage location for bootloaders, kernel images, and drivers used by the system firmware during startup.</p>
<p>As I found about the ESP, this act like a bridge between the firmware and the operating system. instead of a "boot sector," the ESP holds the actual <code>.efi</code> binary files (like <code>grubx64.efi</code>) that the motherboard loads to start OS.</p>
<p>This is also a platform independent and I found that a single ESP can hold bootloaders for multiple operating systems (like Windows and Linux) if needed.</p>
<p>Refer the image how that looks after the server install successfully. (This is after server setup - you are time travelling).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1770298659856/831dd41b-3528-4a90-9310-889a4fd449e1.png" alt class="image--center mx-auto" /></p>
<p>But there is a something notable, that I haven’t setup the swap for my installation, When I did little search about the swap, I discovered that I can either setup the swap when I install the OS or after setup the OS.</p>
<p>So, I decided to find what are the difference between these two approaches and what will be the suitable for me.</p>
<p>Here what I did found,</p>
<ol>
<li><h3 id="heading-setting-up-swap-in-installation-partition-method">Setting Up Swap in Installation (Partition Method)</h3>
</li>
</ol>
<p>During the installer, we would create a dedicated "Swap Partition" on SSD, that method associated with following advantages and disadvantages.</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Advantages</strong></td><td><strong>Disadvantages</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>Performance</strong>: A dedicated partition can be slightly faster than a file because the data is stored in contiguous blocks on the disk.</td><td><strong>Inflexible</strong>: Once create a 2GB partition, it is difficult to resize it later without unmounting drives and using tools like GParted.</td></tr>
<tr>
<td><strong>Reliability</strong>: It is "set and forget." The system will always have that emergency memory available from the first boot.</td><td><strong>Wasted Space</strong>: If we never use swap, that 2GB–4GB of fast 120GB SSD is permanently "locked" and can't be used for AI models or files.</td></tr>
</tbody>
</table>
</div><ol start="2">
<li><h3 id="heading-setting-up-swap-later-swap-file-method">Setting Up Swap Later (Swap File Method)</h3>
<p> Once Debian is installed, we able to create a "Swap File" (a large file sitting on root partition that acts like RAM). This method associated with following advantages and disadvantages,</p>
</li>
</ol>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Advantages</strong></td><td><strong>Disadvantages</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>Dynamic Flexibility</strong>: This is the modern "DevOps" way. We can create a 1GB swap file today, and if we find Llama-3.2 needs more, we can delete it and create an 8GB file in seconds without rebooting.</td><td><strong>Slight Overhead</strong>: Theoretically, a file has a tiny bit more overhead than a raw partition, though on modern Linux kernels and SSDs, this difference is practically zero.</td></tr>
<tr>
<td><strong>No Disk Fragmentation</strong>: We can put the swap file on your SSD for speed or move it to your 1TB HDD if we want to save SSD space.</td><td><strong>Manual Setup</strong>: We have to run 4-5 terminal commands after the installation is finished.</td></tr>
</tbody>
</table>
</div><p>If we compare the overall process in both approach it looks like this,</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Feature</strong></td><td><strong>Setting Up Now (Partition)</strong></td><td><strong>Setting Up Later (File)</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>Ease of Setup</strong></td><td>Automatic (via Installer)</td><td>Manual (via Terminal)</td></tr>
<tr>
<td><strong>Flexibility</strong></td><td>Low (Hard to resize)</td><td><strong>High (Easy to resize/move)</strong></td></tr>
<tr>
<td><strong>Disk Usage</strong></td><td>Fixed "slice" of the disk</td><td>Just another file on the system</td></tr>
<tr>
<td><strong>Performance</strong></td><td>Slightly better</td><td>Practically identical on SSDs</td></tr>
</tbody>
</table>
</div><p>To came to the conclusion, I got selected the Swap file method, since my Dell has 8GB of RAM, I likely won't even need swap for a minimal Debian server and small AI models like Llama-3.2 1B. There for I skipping it now.</p>
<p>Then If I hit a "Memory Out" error later while running a models or working I plan to create a swap file later.</p>
<p>Before getting a decision I also consider about the performance difference in the both approaches, Here what I got through Gemini,</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Metric</strong></td><td><strong>Swap Partition (Set up now)</strong></td><td><strong>Swap File (Set up later)</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>I/O Speed</strong></td><td>Maximum (Direct access)</td><td>Near-Maximum (Minimal overhead)</td></tr>
<tr>
<td><strong>Access Latency</strong></td><td>Consistent</td><td>Negligible difference on SSD</td></tr>
<tr>
<td><strong>System Boot Time</strong></td><td>No impact</td><td>No impact</td></tr>
<tr>
<td><strong>CPU Overhead</strong></td><td>Zero</td><td>Extremely low</td></tr>
</tbody>
</table>
</div><p>For me “<strong>Swap File”</strong> method seems its flexibility for future DevOps projects as well, because I can adjust the swap storage as needed in future.</p>
<p>Then I continue and I follow the few more steps like select the mirror server and other minor settings.</p>
<p>Finally I got to select the software that want to install to the OS, In that screen I only selected the <strong>SSH Server</strong> And <strong>Standard Utility</strong> to keep the my server more lightweight but make sure essential software are installed.</p>
<p>SSH server is essential for managing server from remotely and standard system utility included the essential command line tools like following,</p>
<h3 id="heading-key-categories-of-included-tools">Key Categories of Included Tools</h3>
<ul>
<li><p><strong>Text Editors</strong>: Basic terminal-based editors like <code>nano</code> or <code>vim-tiny</code> for editing configuration files.</p>
</li>
<li><p><strong>Networking Tools</strong>: Utilities for managing connections and troubleshooting, such as <code>iputils-ping</code>, <code>curl</code>, and <code>wget</code>.</p>
</li>
<li><p><strong>File Management</strong>: Tools for handling archives and file systems, including <code>tar</code>, <code>gzip</code>, <code>bzip2</code>, and <code>parted</code>.</p>
</li>
<li><p><strong>Process Management</strong>: Basic monitors like <code>top</code> to view system resource usage and manage running tasks.</p>
</li>
<li><p><strong>System Documentation</strong>: Access to manual pages through the <code>man-db</code> system to look up command usage offline.</p>
</li>
<li><p><strong>Hardware Detection</strong>: Small utilities that help the kernel identify and interact with your specific laptop components.</p>
</li>
</ul>
<p>That’s all after few minutes I got my brand new (yet laptop is old) server, with lot of memory to play for me. In simple term, now I have bigger ground to play, look at my resource usage now 👇</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1770298224592/3e9de141-8262-490b-b524-8ff651d398d1.png" alt class="image--center mx-auto" /></p>
<p>What do you think ? It’s glad to hear yours opinion on the comment section 👇</p>
<p>Alright that’s it for today, let’s meet in day 3 with more exciting story, most probably my next goal is to setup llama, let’s see what happen next. see you all in the day 03.</p>
<p>Thank you for reading… ! 😎</p>
]]></content:encoded></item><item><title><![CDATA[[Day 01] - My Journey from Laptop to Lab: Building a Headless Debian Server for DevOps & AI]]></title><description><![CDATA[Hey everyone! As an undergraduate always looking to get my hands dirty, I decided it was time to level up my old Dell Inspiron 15-3567. Instead of letting it gather dust running a resource-heavy desktop OS, I embarked on a mission: transform it into ...]]></description><link>https://blog.zasela.site/day-01-my-journey-from-laptop-to-lab-building-a-headless-debian-server-for-devops-and-ai</link><guid isPermaLink="true">https://blog.zasela.site/day-01-my-journey-from-laptop-to-lab-building-a-headless-debian-server-for-devops-and-ai</guid><category><![CDATA[serversetup]]></category><category><![CDATA[learning]]></category><category><![CDATA[Learning Journey]]></category><dc:creator><![CDATA[Asela Priyadarshana]]></dc:creator><pubDate>Thu, 05 Feb 2026 12:05:16 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1770050285446/8c8dfb9b-09f4-4ab9-b35c-f5d07e221a2c.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey everyone! As an undergraduate always looking to get my hands dirty, I decided it was time to level up my old Dell Inspiron 15-3567. Instead of letting it gather dust running a resource-heavy desktop OS, I embarked on a mission: transform it into a lean, mean, headless Debian server specifically for my DevOps and Agentic AI experiments.</p>
<p>This isn't just about getting a machine running; it's about deeply understanding the underlying tech. I hope to learn lot of fundamental concepts throughout the process and hope to share my experience with you.</p>
<p>Also appreciate your supportive comments and ideas, because I’m not an expert at all and I learn things by searching and asking by AI.</p>
<p>Here’s a breakdown of what I’ve been up to, and more importantly, what I’ve learned (sometimes the hard way!).</p>
<h3 id="heading-the-before-my-trusty-but-thirsty-linux-mint-laptop">The "Before": My Trusty (but Thirsty) Linux Mint Laptop</h3>
<p>My Dell Inspiron, sporting an <strong>Intel Core i3-7100U</strong> and <strong>8GB of RAM</strong>, was running Linux Mint 21. While Mint is fantastic for daily use, my <code>inxi -Fxxxrz</code> output revealed its Achilles' heel for my new ambitions: <strong>80% RAM usage just at idle!</strong> That's not going to cut it when I want to run large language models (LLMs) and Docker containers.</p>
<p>The goal became clear: strip down the OS to the absolute essentials to free up as much RAM as possible.</p>
<h3 id="heading-i-chose-debian-because-gemini-tell-me-to-try-that">I chose Debian, because Gemini tell me to try that..</h3>
<p>When I search thought what will be the best OS to try for me that can learn things and setup my AI and DevOps environment while learning, Gemini suggest me to try the Debian 12, but when I search on the Bing I discovered that Debian 13 is also available.</p>
<p>Then Why I try some old, staff, So I decided to learn something new and ignore the Gemini suggested <strong>Debian 12 "Bookworm"</strong> and download the <strong>Debian 13 "trixie",</strong> Because I don’t trust AI always.</p>
<p>As Gemini mentioned here are the feature that I can achieve through the Debian</p>
<ol>
<li><p><strong>Minimalism &amp; Performance:</strong> A headless Debian server (no fancy graphical desktop environment) can idle at an incredible <strong>150-200MB of RAM</strong>. This means nearly 7.5GB of my 8GB RAM is available for actual AI tasks!</p>
</li>
<li><p><strong>Industry Standard:</strong> Debian is the bedrock for many enterprise servers and forms the base for Ubuntu, making it invaluable for real-world DevOps skills.</p>
</li>
<li><p><strong>Stability:</strong> For a dedicated lab, I need something that won't randomly break, letting me focus on my projects, not OS debugging.</p>
</li>
</ol>
<p>The Gemini also suggest me to try “Arch Linux” as “As an undergraduate, nothing teaches you how Linux actually works better than an Arch installation”. But right now I think It’s better to try the “Debian way" fist and then move to the Arch later.</p>
<p>The actual reason is that always I use the Debian based OS for my servers and then I wanna study how to build the Debian base server from ground up.</p>
<h3 id="heading-navigating-the-iso-minefield-free-vs-non-free-firmware">Navigating the ISO Minefield: "Free" vs. "Non-Free" Firmware</h3>
<p>This was my first major learning curve! First I login into to the my laptop using <code>SSH</code> though the local network. That was the first time I log to my laptop using the <code>ssh</code> , Most time I used the Anydesk for that.</p>
<p>Then I downloaded the <code>mini.iso</code> , using the <code>wget</code> command and I also explore the current available block devices using the <code>lsblk</code> command which is stands for <strong>List Block Devices</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1770292841524/eabd799c-88a7-4967-b4fb-c0c3cb4c43ff.png" alt class="image--center mx-auto" /></p>
<p>Once I got onedrive block, I decided to flashed downloaded os into it, I used the <code>dd</code> commands for that. (a powerful tool that overwrites everything, so <strong>always double-check your target drive, folks!</strong>).</p>
<p>I thought I was golden, but then the installer hit me with this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1770291693222/4e11820e-4100-4e1e-a267-d5aad1e64a10.jpeg" alt class="image--center mx-auto" /></p>
<p><strong>The Revelation: My Wi-Fi and Ethernet need "Non-Free" Firmware!</strong></p>
<p>The messages <code>ath10k/QCA9377</code> and then later <code>rtl_nic</code> weren't just random errors. They were the installer politely (but firmly!) telling me that my <strong>Qualcomm Atheros Wi-Fi</strong> and <strong>Realtek Ethernet</strong> chips needed proprietary binary files to function.</p>
<p>These are "non-free" not because you have to pay for them, but because their source code isn't openly available, which conflicts with Debian's strict "free software" philosophy in its default installers.</p>
<p><strong>The Solution:</strong> I had to scrap that <code>mini.iso</code> and download the official <strong>Debian 13 Netinst ISO that <em>includes</em> non-free firmware</strong>. This version is a godsend for modern laptops as it bundles those closed-source blobs, allowing the hardware to actually turn on.</p>
<p>Then I started to make bootable device using newly download ios, use the same <code>dd</code> commands, let’s see what happened next in day 02 blog.</p>
<p>I'm excited to get this server online and start diving into Docker, Ollama, and building my first Agentic AI prototypes. Stay tuned for Part 2!</p>
]]></content:encoded></item><item><title><![CDATA[Understanding Object-Oriented Analysis and Design (OOAD)]]></title><description><![CDATA[Object-oriented analysis and design (OOAD) is a foundational approach to software development that has revolutionized the way systems are conceptualized, designed, and implemented.
In this article, we explore the core principles, methodologies, and b...]]></description><link>https://blog.zasela.site/understanding-object-oriented-analysis-and-design-ooad</link><guid isPermaLink="true">https://blog.zasela.site/understanding-object-oriented-analysis-and-design-ooad</guid><category><![CDATA[oop]]></category><dc:creator><![CDATA[Asela Priyadarshana]]></dc:creator><pubDate>Sun, 10 Aug 2025 09:47:58 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1754819173139/b93e9d33-0206-4e04-8bbe-11ee01812635.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Object-oriented analysis and design (OOAD) is a foundational approach to software development that has revolutionized the way systems are conceptualized, designed, and implemented.</p>
<p>In this article, we explore the core principles, methodologies, and both advantages and disadvantages of object orientation.</p>
<h3 id="heading-object-orientation-a-paradigm-shift-in-software-development"><strong>Object Orientation: A Paradigm Shift in Software Development</strong></h3>
<p>At its core, object orientation is a paradigm that views systems as collections of interacting and interrelated objects. Each object encapsulates both data (attributes) and behavior (methods), mirroring real-world entities and their interactions.</p>
<p>Object-oriented systems development emphasizes building modular, self-contained modules that facilitate reusability, modifiability, and scalability.</p>
<p><strong>GIF</strong></p>
<p><img src="https://media2.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxbhvbeu7365knnr26sdo.gif" alt="Why Object Oriented Approach ? " /></p>
<h3 id="heading-why-object-oriented-approach"><strong>Why Object Oriented Approach ?</strong></h3>
<p>Object orientation offers numerous benefits compared to traditional procedural approaches to software development:</p>
<ul>
<li><p><strong>Reusability:</strong> Objects and classes can be reused across different projects, reducing development time and effort.</p>
</li>
<li><p><strong>Increased Quality:</strong> The modular design of object-oriented systems promotes better code organization and reduces the likelihood of errors.</p>
</li>
<li><p><strong>Faster Development:</strong> Reusable components and modular design lead to faster development cycles and improved time-to-market.</p>
</li>
<li><p><strong>Maintainability:</strong> Changes to one part of the system can be localized, minimizing the impact on other components, thus enhancing maintainability.</p>
</li>
<li><p><strong>Scalability:</strong> Object-oriented systems can easily accommodate changes in requirements and scale to meet evolving needs.</p>
</li>
<li><p><strong>Modularity:</strong> The modular structure of object-oriented systems promotes better code organization, making it easier to manage and extend.</p>
</li>
</ul>
<h3 id="heading-what-are-the-disadvantages"><strong>What are the Disadvantages ?</strong></h3>
<p>While object-oriented analysis and design (OOAD) offers numerous advantages, it's important to acknowledge its limitations and potential drawbacks.</p>
<p>Here are some disadvantages associated with the object-oriented approach:</p>
<ul>
<li><p><strong>Complexity:</strong> Object-oriented systems can become complex, especially as the number of classes and their interactions increase. Managing the complexity of large-scale object-oriented projects requires careful design and planning.</p>
</li>
<li><p><strong>Learning Curve:</strong> Transitioning from procedural programming to object-oriented programming may pose a steep learning curve for developers, particularly those unfamiliar with the concepts of classes, objects, inheritance, and polymorphism.</p>
</li>
<li><p><strong>Performance Overhead:</strong> Object-oriented systems may incur performance overhead compared to procedural counterparts. The overhead arises from features such as dynamic dispatch, inheritance, and polymorphism, which can introduce runtime inefficiencies.</p>
</li>
<li><p><strong>Inheritance Issues:</strong> While inheritance promotes code reuse, it can also lead to issues such as tight coupling between classes, the fragile base class problem, and difficulty in understanding class hierarchies. Inappropriate use of inheritance can result in rigid, inflexible designs.</p>
</li>
</ul>
<p>You know more from your experience or not agree with me, feel free to comment your ideas.</p>
<p>Now Let's move to the process In Object oriented development process we called "Object-Oriented Development Lifecycle", there are three main steps.</p>
<h4 id="heading-the-object-oriented-development-lifecycle"><strong>The Object-Oriented Development Lifecycle</strong></h4>
<ol>
<li><p><strong>Object-Oriented Analysis (OOA):</strong> This phase focuses on identifying and describing objects or concepts within the problem domain.</p>
</li>
<li><p><strong>Object-Oriented Design (OOD):</strong> In OOD, structures are developed to define software objects and their interactions. It involves defining classes, specifying attributes, and determining how objects collaborate to fulfill system requirements.</p>
</li>
<li><p><strong>Object-Oriented Programming (OOP):</strong> OOP involves implementing the designed objects in a programming language. It translates the abstract design into executable code, where classes are instantiated as objects, and methods are invoked to perform specific tasks.<br /> This is the step that we get a help of Object oriented programming language like JAVA.</p>
</li>
</ol>
<p>There is a another important thing that you should now that is,</p>
<h3 id="heading-core-principles-of-object-orientation"><strong>Core Principles of Object Orientation</strong></h3>
<ol>
<li><p><strong>Abstraction:</strong> Abstraction involves representing only the essential aspects of a system while hiding irrelevant details.</p>
</li>
<li><p><strong>Encapsulation:</strong> Encapsulation involves bundling data and methods into a single unit (class) and restricting access to the internal state of objects. It promotes information hiding, data integrity, and modular design.</p>
</li>
<li><p><strong>Inheritance:</strong> Inheritance allows classes to inherit attributes and behaviors from parent classes, enabling code reuse and promoting hierarchy and specialization.</p>
</li>
<li><p><strong>Polymorphism:</strong> Polymorphism enables objects to exhibit different behaviors based on their context or inputs. It allows for flexibility and extensibility by enabling the same method to behave differently in different contexts.</p>
</li>
</ol>
<h3 id="heading-conclusion"><strong>Conclusion</strong></h3>
<p>Object-oriented analysis and design represent a paradigm shift in software development, offering a more intuitive, modular, and maintainable approach to building complex systems.</p>
<p>Event though it have some disadvantages overall It provide well define approach to building complex systems. Then choose wisely according to your requirement.</p>
]]></content:encoded></item><item><title><![CDATA[How To Create Chess Pattern With HTML, CSS And a Little bit of JS]]></title><description><![CDATA[This article was originally posted on dev.to
Hello everyone, Today I'll tell you how to create a simple 8 X 8 chess pattern using HTML, CSS and a little JS.
Complete Source Code: https://github.com/zaselalk/Chess-Pattern-CSS-JS
First things first, He...]]></description><link>https://blog.zasela.site/how-to-create-chess-pattern-with-html-css-and-a-little-bit-of-js</link><guid isPermaLink="true">https://blog.zasela.site/how-to-create-chess-pattern-with-html-css-and-a-little-bit-of-js</guid><category><![CDATA[CSS]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[HTML5]]></category><dc:creator><![CDATA[Asela Priyadarshana]]></dc:creator><pubDate>Fri, 07 Jun 2024 02:30:56 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/G1yhU1Ej-9A/upload/436e90982fca68d7cf428de84f81788d.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This article was originally posted on <a target="_blank" href="https://dev.to/zaselalk/how-to-create-chess-pattern-with-html-and-css-little-bit-of-js-1gpa">dev.to</a></p>
<p>Hello everyone, Today I'll tell you how to create a simple 8 X 8 chess pattern using HTML, CSS and a little JS.</p>
<p>Complete Source Code: <a target="_blank" href="https://github.com/zaselalk/Chess-Pattern-CSS-JS">https://github.com/zaselalk/Chess-Pattern-CSS-JS</a></p>
<p>First things first, Here's my little piece of HTML code.</p>
<p><code>index.html</code></p>
<pre><code class="lang-bash">&lt;!DOCTYPE html&gt;
&lt;html lang=<span class="hljs-string">"en"</span>&gt;
&lt;head&gt;
    &lt;meta charset=<span class="hljs-string">"UTF-8"</span>&gt;
    &lt;meta http-equiv=<span class="hljs-string">"X-UA-Compatible"</span> content=<span class="hljs-string">"IE=edge"</span>&gt;
    &lt;meta name=<span class="hljs-string">"viewport"</span> content=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;
    &lt;title&gt;Chess-Pattern-CSS-JS &lt;/title&gt;
    &lt;link rel=<span class="hljs-string">"stylesheet"</span> href=<span class="hljs-string">"style.css"</span>&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;div id=<span class="hljs-string">"board"</span>&gt;
    &lt;/div&gt;   
    &lt;script src=<span class="hljs-string">"script.js"</span>&gt;&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p><strong>What Next?</strong></p>
<p>Now Let's add some styles for our chessboard pattern,</p>
<p><code>style.css</code>.</p>
<pre><code class="lang-bash"><span class="hljs-comment">#board{</span>
    display: flex;
    flex-wrap: wrap;
    width: 640px;
    height: 640px;
    border:1px solid black;
    background-color: <span class="hljs-comment">#fff;</span>

  }
</code></pre>
<p><strong>Explain</strong></p>
<ul>
<li><p>Use <code>#board</code> Element as a Flex-Container and Add <code>display:flex</code> property to it.</p>
</li>
<li><p>Add <code>flex-warp</code> property to make sure that your square warp to lines.</p>
</li>
<li><p>Define our chess board <code>width</code> and <code>height</code>.</p>
</li>
<li><p>use 1px <code>border</code> and white as `background-color' to make sure your chess board more decent.</p>
</li>
</ul>
<p>Next, We're going to Style small square on a chessboard, in this Code there're Two types of squares,<br />Which are,<br />*<code>.esquare</code> - Square that in even line<br />*<code>.osquare</code> - Sqaure in odd line</p>
<p><strong>Two Types? But Why?</strong></p>
<p>That's because chessboard have 64 squares and there're 8 squares in one line. There're 8 lines on board. But these lines are not in the same pattern.</p>
<p>As an example, If we select black squares and numbered them.Look you can see they are changing as odd and even pattern.</p>
<p>Now let's Back to our code.</p>
<p><code>style.css</code> .</p>
<p>`</p>
<pre><code class="lang-bash">

.esquare, .osquare{
    width: 80px;
    height: 80px;
    border:1px solid black;
    box-sizing:border-box;
  }
</code></pre>
<p>Nice! We Finished most of CSS Codes and finally we have to style our Black Squares like chess pattern. Let's achieve this.</p>
<p>more code for <code>style.css</code></p>
<pre><code class="lang-bash"> .esquare:nth-of-type(2n){
    background-color: <span class="hljs-comment">#000;</span>
  }
  .osquare:nth-of-type(2n+1){
    background-color: <span class="hljs-comment">#000;</span>
  }
</code></pre>
<p><strong>Explain</strong></p>
<p>As I said this is the final part of our CSS code. Within this part , We're going to design pattern of black squares in our chessboard.</p>
<p>As I mention before, We group squares as <code>esqaures</code> and <code>osqaures</code> to style our chessboard.</p>
<p>Now you are end of line and final one is our js file.</p>
<p><strong>But Why JS?</strong></p>
<p>The truth is normally JS isn't use for the simple codes like this, But to have a more clean code I added little JS code to multiply <code>.square</code> elements.</p>
<p>Here is My Js Code<br /><code>script.js</code></p>
<pre><code class="lang-bash">const board = document.getElementById(<span class="hljs-string">'board'</span>);
<span class="hljs-built_in">let</span> patterneven = <span class="hljs-string">" &lt;div class='esquare'&gt;&lt;/div&gt;"</span> ;
<span class="hljs-built_in">let</span> patternodd = <span class="hljs-string">" &lt;div class='osquare'&gt;&lt;/div&gt;"</span> ;

<span class="hljs-keyword">for</span>(i=0;i&lt;4;i++){
    board.innerHTML += patterneven.repeat(8);
    board.innerHTML += patternodd.repeat(8);
}
</code></pre>
<p>Using JS to create a loop so that we could easily make our code more clear and Easy to enhanced.</p>
<p>Mission complete !, Now you have Chess Pattern 😎</p>
<p>Would you like to try Live demo ? Then click the link below.</p>
<p>Live Demo: <a target="_blank" href="http://gestyy.com/epXRuq">http://gestyy.com/epXRuq</a></p>
<p>Do you know this is my first post for dev.to and feel free to add comments about this post.</p>
]]></content:encoded></item><item><title><![CDATA[A Simple way to Import Excel to Mongo Atlas]]></title><description><![CDATA[This article was originally posted on LinkedIn.
A few days ago, I was working on developing a library system for my school using a MERN stack.
During this project, I had to import around 12,000 excel records into my Mongo Atlas database because libra...]]></description><link>https://blog.zasela.site/a-simple-way-to-import-excel-to-mongo-atlas</link><guid isPermaLink="true">https://blog.zasela.site/a-simple-way-to-import-excel-to-mongo-atlas</guid><category><![CDATA[MongoDB]]></category><category><![CDATA[excel]]></category><dc:creator><![CDATA[Asela Priyadarshana]]></dc:creator><pubDate>Wed, 05 Jun 2024 02:30:07 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1717488858025/bb5c615b-5b3d-468f-9bd3-1e1c33472c13.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This article was originally posted on <a target="_blank" href="https://www.linkedin.com/pulse/simple-way-import-excel-mongo-atlas-asela-priyadarshana/?trackingId=UTT6rxPFSTq8hClDAnPtyQ%3D%3D">LinkedIn</a>.</p>
<p>A few days ago, I was working on developing a library system for my school using a MERN stack.</p>
<p>During this project, I had to import around 12,000 excel records into my Mongo Atlas database because library staff already maintained their book and student information in excel sheets.</p>
<p>When looking for a way to import this data into a Mongo Atlas cluster, I found a tool called "mongoimport."</p>
<p>Mongoimport is a MongoDB database tool that was released as a standalone tool after MongoDB 4.4. If you are using a higher version than Mongo 4.4, you have to install it.</p>
<p>Hense installation is different for each operating system please <a target="_blank" href="https://www.mongodb.com/docs/database-tools/mongoimport/?_ga=2.269047921.1435217070.1650519887-1908806812.1640359772">follow the official guide for installation</a>.</p>
<p>With this tool, I was able to import data into my database by following the steps described below.</p>
<p>First, I deleted all unnecessary columns and titles in the excel sheet. Mongoimport commands allow you to give column titles with the appropriate types.</p>
<p>After that, I saved my file as a CSV file; I used LibreOffice, but you could also use Google Sheets if you prefer.</p>
<p>Now we are ready to import our file to the mongo database.</p>
<p>Please keep in mind that if you use unique key validation in the collection and haven't created a collection yet, I recommend that you should <strong>manually add at least one document</strong> to your collection. Otherwise, validations will not work properly while importing a CSV file.</p>
<p>In the below example, I used two-column "Name, Barcode." with their types, More types in Mongo can be found in <a target="_blank" href="https://www.mongodb.com/docs/database-tools/mongoimport/#std-option-mongoimport.--columnsHaveTypes">mongoimport documentation</a>.</p>
<p>Also don't forget to update <strong>&lt;connecttionString&gt;</strong>,<strong>&lt;collectionName&gt;</strong>, <strong>&lt;CSVpath&gt;</strong> with your own values.</p>
<pre><code class="lang-bash">mongoimport --uri &lt;connecttionString&gt; --collection &lt;collectionName&gt; --<span class="hljs-built_in">type</span> csv --file &lt;CSVpath&gt; -f <span class="hljs-string">"Name.string(),Barcode.string()"</span> --columnsHaveTypes
</code></pre>
<p>Enclosing fields in double quotes will prevent shell errors.</p>
<p><img src="https://media.licdn.com/dms/image/C5612AQElYf6_KUlJaw/article-inline_image-shrink_1500_2232/0/1650699736314?e=1723075200&amp;v=beta&amp;t=QZRY4MOXVfKR_3U1eQviPXWmeLn3Kq4UARVlHnEUfZU" alt="No alt text provided for this image" /></p>
<p>Done! Isn't it simple? You can use this technique to import Excel into MongoDB starting today.</p>
]]></content:encoded></item><item><title><![CDATA[Understanding the Difference Between || (OR) and ?? (nullish coalescing) Operators in JavaScript]]></title><description><![CDATA[Both || (OR operator) ?? (nullish coalescing operator) are the way of assigning default value in Javascript when dealing with undefined or other falsy values. However, they behave different in certain situations.
The main difference between the two o...]]></description><link>https://blog.zasela.site/understanding-the-difference-between-or-and-nullish-coalescing-operators-in-javascript</link><guid isPermaLink="true">https://blog.zasela.site/understanding-the-difference-between-or-and-nullish-coalescing-operators-in-javascript</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[short-story]]></category><category><![CDATA[Developer]]></category><dc:creator><![CDATA[Asela Priyadarshana]]></dc:creator><pubDate>Tue, 25 Apr 2023 06:10:42 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1682143142509/cf9aec44-7450-482f-9727-a7b7fbd0156a.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Both <code>||</code> (OR operator) <code>??</code> (nullish coalescing operator) are the way of assigning default value in Javascript when dealing with <code>undefined</code> or other falsy values. However, they behave different in certain situations.</p>
<p>The main difference between the two operators is how they handle falsy values for example consider following code.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> value = <span class="hljs-literal">false</span>;
<span class="hljs-built_in">console</span>.log(value || <span class="hljs-number">500</span>); <span class="hljs-comment">// Output: 500</span>
<span class="hljs-built_in">console</span>.log(value ?? <span class="hljs-number">500</span>); <span class="hljs-comment">// Output: false</span>
</code></pre>
<p>In this scenario, the output is different in each operator.</p>
<h3 id="heading-but-why">But Why ?</h3>
<p>The reason is <code>??</code> operator return default value only if left side value is <code>null</code> or <code>undefined</code> while <code>||</code> operator consider following scenarios,</p>
<ol>
<li><p><code>false</code>: The boolean false value.</p>
</li>
<li><p><code>0</code>: The number zero (integer).</p>
</li>
<li><p><code>-0</code>: The negative zero (integer).</p>
</li>
<li><p><code>0n</code>: The BigInt zero.</p>
</li>
<li><p><code>NaN</code>: Not-a-Number, a special value that represents the result of an undefined or unrepresentable mathematical operation.</p>
</li>
<li><p><code>null</code>: A null value, representing the absence of any value or object.</p>
</li>
<li><p><code>undefined</code>: A value that is automatically assigned to variables that have just been declared or to object properties that do not exist.</p>
</li>
<li><p><code>""</code>: An empty string.</p>
</li>
</ol>
<p>Here is an example code</p>
<pre><code class="lang-jsx"><span class="hljs-built_in">console</span>.log(<span class="hljs-literal">false</span> || <span class="hljs-string">'default'</span>); <span class="hljs-comment">// Output: 'default'</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-number">0</span> || <span class="hljs-number">42</span>);            <span class="hljs-comment">// Output: 42</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-literal">NaN</span> || <span class="hljs-number">100</span>);         <span class="hljs-comment">// Output: 100</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-literal">null</span> || <span class="hljs-string">'Hello'</span>);    <span class="hljs-comment">// Output: 'Hello'</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-literal">undefined</span> || <span class="hljs-number">123</span>);   <span class="hljs-comment">// Output: 123</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">''</span> || <span class="hljs-string">'Fallback'</span>);   <span class="hljs-comment">// Output: 'Fallback'</span>
</code></pre>
<p>Now let’s compare this code with <code>??</code> operator</p>
<pre><code class="lang-jsx"><span class="hljs-built_in">console</span>.log(<span class="hljs-literal">false</span> ?? <span class="hljs-string">'default'</span>); <span class="hljs-comment">// Output: false</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-number">0</span> ?? <span class="hljs-number">42</span>);            <span class="hljs-comment">// Output: 0</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-literal">NaN</span> ?? <span class="hljs-number">100</span>);         <span class="hljs-comment">// Output: NaN</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-literal">null</span> ?? <span class="hljs-string">'Hello'</span>);    <span class="hljs-comment">// Output: 'Hello'</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-literal">undefined</span> ?? <span class="hljs-number">123</span>);   <span class="hljs-comment">// Output: 123</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">''</span> ?? <span class="hljs-string">'Fallback'</span>);   <span class="hljs-comment">// Output: ''</span>
</code></pre>
<p>As you see the <code>??</code> operator only return it’s right-side value if left-side value is <code>null</code> or <code>undefined</code>.</p>
<p>In conclusion, understanding the differences between the **<code>||</code>**and <code>??</code> operators in JavaScript is essential for assigning default values correctly, depending on whether you want to consider all falsy values or only **<code>null</code>**and <code>undefined</code> .</p>
]]></content:encoded></item><item><title><![CDATA[Why I planned to move medium to hashnode]]></title><description><![CDATA[I'm looking for one source to publish all my personal blog articles related to the programming and then, I asked chatgpt to compare the difference between medium and hashnode and it says me like below,
Both Hashnode and Medium are popular blogging pl...]]></description><link>https://blog.zasela.site/why-i-planned-to-move-medium-to-hashnode</link><guid isPermaLink="true">https://blog.zasela.site/why-i-planned-to-move-medium-to-hashnode</guid><category><![CDATA[Hashnode]]></category><category><![CDATA[Developer]]></category><dc:creator><![CDATA[Asela Priyadarshana]]></dc:creator><pubDate>Sun, 23 Apr 2023 02:30:42 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1682142623220/37220780-5671-44e4-b306-3c22cdba869e.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I'm looking for one source to publish all my personal blog articles related to the programming and then, I asked chatgpt to compare the difference between medium and hashnode and it says me like below,</p>
<p>Both Hashnode and Medium are popular blogging platforms, each with its own set of features and advantages. Here's a comparison between the two to help you make an informed decision:</p>
<p>Hashnode:</p>
<p>Pros:</p>
<ol>
<li><p>Free: Hashnode offers a free plan with no restrictions on custom domains, content ownership, or monetization options.</p>
</li>
<li><p>Custom Domain: You can easily set up a custom domain to enhance your personal brand.</p>
</li>
<li><p>Content Ownership: You retain full ownership of your content, which can be important for long-term credibility and SEO.</p>
</li>
<li><p>Developer-Focused: The platform is tailored towards developers, with a built-in audience interested in technical content.</p>
</li>
<li><p>Markdown Support: You can write and format your articles using Markdown, which is a popular and easy-to-learn markup language.</p>
</li>
<li><p>Community Engagement: Hashnode has a supportive and interactive community, where you can get feedback and engage with other writers.</p>
</li>
</ol>
<p>Cons:</p>
<ol>
<li><p>Smaller Audience: Hashnode has a smaller overall audience compared to Medium, which may result in fewer views for non-technical content.</p>
</li>
<li><p>Limited Exposure: The platform's focus on the developer community may limit the exposure of non-technical content.</p>
</li>
<li><p>Fewer Design Options: The customization options for the look and feel of your blog are limited.</p>
</li>
</ol>
<p>Medium:</p>
<p>Pros:</p>
<ol>
<li><p>Large Audience: Medium has a vast user base, providing you with more potential readers and increased exposure for your content.</p>
</li>
<li><p>Curated Content: Medium's curation team selects and promotes high-quality articles, which can lead to increased visibility.</p>
</li>
<li><p>Elegant Design: The platform offers a clean and minimalist design, allowing your content to shine without distractions.</p>
</li>
<li><p>Simple to Use: Medium's editor is user-friendly and easy to learn, even for beginners.</p>
</li>
<li><p>Diverse Topics: Medium caters to a wide range of topics, making it suitable for writers in various niches.</p>
</li>
<li><p>Monetization: Medium offers the Partner Program, allowing you to earn money from your content based on engagement.</p>
</li>
</ol>
<p>Cons:</p>
<ol>
<li><p>Paywall: Medium's paywall may deter some readers from accessing your content, potentially limiting your reach.</p>
</li>
<li><p>Content Ownership: Medium has more control over your content and can remove it if it violates their terms.</p>
</li>
<li><p>Limited Customization: The platform offers limited customization options, making it harder to establish a unique brand identity.</p>
</li>
<li><p>No Custom Domain: Medium does not offer custom domains, which may not be ideal for personal branding.</p>
</li>
<li><p>Monetization Restrictions: The Partner Program is not available in all countries, and your earnings may be impacted by Medium's curation and promotion policies.</p>
</li>
</ol>
<p>By comparing my needs I decided to start publishing content with hasnode.</p>
<p>In conclusion, if you are a developer or prefer a platform with custom domains, content ownership, and a strong community, Hashnode may be the better choice for you. On the other hand, if you want a platform with a larger audience, more diverse topics, and the potential to earn money from your content, Medium could be the right fit.</p>
]]></content:encoded></item><item><title><![CDATA[How to setup Tailwind in vite react project]]></title><description><![CDATA[Tailwind CSS is a utility-first CSS framework for rapidly building custom user interfaces. It is designed to be highly customizable and allows you to create unique designs without having to write your own CSS styles from scratch.
Tailwind provides a ...]]></description><link>https://blog.zasela.site/how-to-setup-tailwind-in-vite-react-project</link><guid isPermaLink="true">https://blog.zasela.site/how-to-setup-tailwind-in-vite-react-project</guid><category><![CDATA[Tailwind CSS]]></category><category><![CDATA[React]]></category><category><![CDATA[Tailwind CSS Tutorial]]></category><dc:creator><![CDATA[Asela Priyadarshana]]></dc:creator><pubDate>Tue, 20 Dec 2022 08:07:42 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1671090846253/TcXL7jP0w.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Tailwind CSS is a utility-first CSS framework for rapidly building custom user interfaces. It is designed to be highly customizable and allows you to create unique designs without having to write your own CSS styles from scratch.</p>
<p>Tailwind provides a large number of utility classes that you can use to style your elements. For example, you can use classes like <code>text-blue-500</code> or <code>bg-green-100</code> to apply color to text or backgrounds. It also provides a number of responsive utility classes, so you can easily create responsive layouts that look good on all screen sizes.</p>
<p>To set up Tailwind in a Vite React project, you will need to do the following:</p>
<ol>
<li>Install the Tailwind CSS package from npm by running the following command:</li>
</ol>
<pre><code class="lang-javascript">npm install tailwindcss
</code></pre>
<ol start="2">
<li>Next, you will need to create a Tailwind configuration file. To do this, run the following command:</li>
</ol>
<pre><code class="lang-javascript">npx tailwind init
</code></pre>
<ol start="3">
<li><p>This will create a <code>tailwind.config.js</code> file in the root of your project. You can modify this file to customize the Tailwind configuration as needed.</p>
</li>
<li><p>Next, you will need to add the Tailwind CSS styles to your project. There are a few different ways to do this, but one option is to create a <code>tailwind.css</code> file in the <code>src</code> directory of your project and import the Tailwind styles like this:</p>
</li>
</ol>
<pre><code class="lang-javascript">@tailwind base;
@tailwind components;
@tailwind utilities;
</code></pre>
<ol start="5">
<li>Then, in your React components, you can use the Tailwind classes to style your elements. For example:</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"bg-blue-500 text-white p-4"</span>&gt;</span>
      This is a blue container with white text and padding.
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<ol start="6">
<li>Finally, you will need to add the <code>tailwind.css</code> file to your project's build process. If you are using Vite, you can do this by adding the following lines to your <code>vite.config.js</code> file:</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { vitePresetReact } <span class="hljs-keyword">from</span> <span class="hljs-string">'vite-preset-react'</span>;
<span class="hljs-keyword">import</span> tailwind <span class="hljs-keyword">from</span> <span class="hljs-string">'tailwindcss'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
  ...vitePresetReact,
  <span class="hljs-attr">plugins</span>: [tailwind()],
};
</code></pre>
<p>This will configure Vite to process the <code>tailwind.css</code> file using the Tailwind plugin, and include the resulting styles in your project.</p>
<p>After completing these steps, you should be able to use Tailwind CSS in your Vite React project.</p>
]]></content:encoded></item><item><title><![CDATA[How to Setup PWA(Progressive Web App) in vite react  app]]></title><description><![CDATA[A PWA (Progressive Web App) is a web app that uses modern web technologies to deliver a user experience similar to that of a native app. PWAs are designed to be fast, reliable, and engaging, and can be installed on the user's device like a native app...]]></description><link>https://blog.zasela.site/how-to-setup-pwaprogressive-web-app-in-vite-react-app</link><guid isPermaLink="true">https://blog.zasela.site/how-to-setup-pwaprogressive-web-app-in-vite-react-app</guid><category><![CDATA[React]]></category><category><![CDATA[PWA]]></category><category><![CDATA[progressive web apps]]></category><dc:creator><![CDATA[Asela Priyadarshana]]></dc:creator><pubDate>Sat, 17 Dec 2022 07:56:44 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1671090244109/fOPXWYg89.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A PWA (Progressive Web App) is a web app that uses modern web technologies to deliver a user experience similar to that of a native app. PWAs are designed to be fast, reliable, and engaging, and can be installed on the user's device like a native app.</p>
<p>To set up a PWA (Progressive Web App) in a Vite React app, you will need to follow these steps:</p>
<ol>
<li>Install the <code>vite-plugin-pwa</code> package by running the following command:</li>
</ol>
<pre><code class="lang-javascript">npm install vite-plugin-pwa
</code></pre>
<ol start="2">
<li>Create a <code>pwa.config.js</code> file in the root of your project, and add the following code to it:</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">name</span>: <span class="hljs-string">'My App'</span>, <span class="hljs-comment">// The name of your app</span>
  <span class="hljs-attr">short_name</span>: <span class="hljs-string">'MyApp'</span>, <span class="hljs-comment">// The short name of your app</span>
  <span class="hljs-attr">theme_color</span>: <span class="hljs-string">'#fff'</span>, <span class="hljs-comment">// The theme color of your app</span>
  <span class="hljs-attr">background_color</span>: <span class="hljs-string">'#fff'</span>, <span class="hljs-comment">// The background color of your app</span>
  <span class="hljs-attr">display</span>: <span class="hljs-string">'standalone'</span>, <span class="hljs-comment">// The display mode of your app</span>
  <span class="hljs-attr">scope</span>: <span class="hljs-string">'/'</span>, <span class="hljs-comment">// The scope of your app</span>
  <span class="hljs-attr">start_url</span>: <span class="hljs-string">'/'</span>, <span class="hljs-comment">// The start URL of your app</span>
  <span class="hljs-attr">icons</span>: [
    {
      <span class="hljs-attr">src</span>: <span class="hljs-string">'./icon.png'</span>, <span class="hljs-comment">// The path to your app icon</span>
      <span class="hljs-attr">sizes</span>: [<span class="hljs-number">96</span>, <span class="hljs-number">128</span>, <span class="hljs-number">192</span>, <span class="hljs-number">256</span>, <span class="hljs-number">384</span>, <span class="hljs-number">512</span>], <span class="hljs-comment">// The sizes of your app icon</span>
    },
  ],
}
</code></pre>
<ol start="3">
<li>Import the <code>createPWA</code> function from the <code>vite-plugin-pwa</code> package, and use it to create a PWA plugin for your Vite app. Add the following code to your <code>src/vite.config.js</code> file:</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { createPWA } <span class="hljs-keyword">from</span> <span class="hljs-string">'vite-plugin-pwa'</span>

<span class="hljs-keyword">const</span> pwaPlugin = createPWA({
  <span class="hljs-attr">config</span>: <span class="hljs-built_in">require</span>(<span class="hljs-string">'./pwa.config.js'</span>),
})

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
  <span class="hljs-comment">// Your other Vite config options...</span>
  <span class="hljs-attr">plugins</span>: [pwaPlugin],
}
</code></pre>
<ol start="4">
<li><p>Build your Vite app using the <code>vite build</code> command. This will generate the necessary files for your PWA, including the <code>manifest.json</code> file and the icon files.</p>
</li>
<li><p>Serve your Vite app using a web server, such as <code>serve</code>. This will allow you to test your PWA and see if it works as expected.</p>
</li>
</ol>
<p>After completing these steps, your Vite React app should be set up as a PWA. You can test it by visiting your app in a web browser and checking if it meets the criteria for a PWA, such as being installable, offline-capable, and responsive.</p>
<p><a target="_blank" href="https://vite-pwa-org.netlify.app/">For more information refer official documentation</a></p>
]]></content:encoded></item><item><title><![CDATA[Beautiful SVG Icon Collection for React - Free and Open Source]]></title><description><![CDATA[If you're looking for a simple and attractive SVG icon collection for your react applications, HeroIcons is the library for you.
HeroIcons have Beautiful hand-crafted SVG icons, by the makers of Tailwind CSS. Which can be easily used with react proje...]]></description><link>https://blog.zasela.site/beautiful-svg-icon-collection-for-react-free-and-open-source</link><guid isPermaLink="true">https://blog.zasela.site/beautiful-svg-icon-collection-for-react-free-and-open-source</guid><category><![CDATA[React]]></category><category><![CDATA[SVG]]></category><category><![CDATA[Icons]]></category><dc:creator><![CDATA[Asela Priyadarshana]]></dc:creator><pubDate>Thu, 15 Dec 2022 07:34:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1671089594589/Kjxk88R36.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you're looking for a simple and attractive SVG icon collection for your react applications, HeroIcons is the library for you.</p>
<p><a target="_blank" href="https://heroicons.com/">HeroIcons</a> have Beautiful hand-crafted SVG icons, by the makers of Tailwind CSS. Which can be easily used with react projects.</p>
<p><strong>How to Use In Your Project</strong></p>
<p><img src="https://reactprocoder.vercel.app/_next/image?url=https%3A%2F%2Fimages.unsplash.com%2Fphoto-1545065695-64b67d551e68%3Fcrop%3Dentropy%26cs%3Dtinysrgb%26fit%3Dmax%26fm%3Djpg%26ixid%3DMnwxMTc3M3wwfDF8c2VhcmNofDJ8fGljb25zfGVufDB8fHx8MTY2MTYyOTU5NA%26ixlib%3Drb-1.2.1%26q%3D80%26w%3D2000&amp;w=3120&amp;q=75" alt /></p>
<p>Photo by <a target="_blank" href="https://unsplash.com/@balazsketyi?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit">Balázs Kétyi</a> / <a target="_blank" href="https://unsplash.com/?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit">Unsplash</a></p>
<p>There are a few ways you can use HeroIcon with your projects.</p>
<p>The quickest method for using these icons is just to copy the source code from <a target="_blank" href="http://heroicons.com">heroicons.com</a> and paste it into your JSX code.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">svg</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"h-6 w-6 text-gray-500"</span> <span class="hljs-attr">fill</span>=<span class="hljs-string">"none"</span> <span class="hljs-attr">viewBox</span>=<span class="hljs-string">"0 0 24 24"</span> <span class="hljs-attr">stroke</span>=<span class="hljs-string">"currentColor"</span> <span class="hljs-attr">stroke-width</span>=<span class="hljs-string">"2"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">path</span>
    <span class="hljs-attr">stroke-linecap</span>=<span class="hljs-string">"round"</span>
    <span class="hljs-attr">stroke-linejoin</span>=<span class="hljs-string">"round"</span>
    <span class="hljs-attr">d</span>=<span class="hljs-string">"M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"</span>
  /&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">svg</span>&gt;</span>
</code></pre>
<p>SVG code</p>
<p>The example below is show How we can create a reusable Icon component with SVG which can be easily customised and can use in many places in your application.</p>
<p>Using this kind of component you are able to add custom class names, width and height. also, you may add more props as you wish.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">DarftIcon</span>(<span class="hljs-params">{ className, width, height }</span>) </span>{
  <span class="hljs-keyword">let</span> classNames = <span class="hljs-string">""</span>;
  width ? (classNames += <span class="hljs-string">`w-<span class="hljs-subst">${width}</span> `</span>) : (classNames += <span class="hljs-string">`w-6 `</span>);
  height ? (classNames += <span class="hljs-string">`h-<span class="hljs-subst">${height}</span> `</span>) : (classNames += <span class="hljs-string">`h-6 `</span>);
  className &amp;&amp; (classNames += <span class="hljs-string">`<span class="hljs-subst">${className}</span> `</span>);

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">svg</span>
      <span class="hljs-attr">xmlns</span>=<span class="hljs-string">"http://www.w3.org/2000/svg"</span>
      <span class="hljs-attr">className</span>=<span class="hljs-string">{classNames}</span>
      <span class="hljs-attr">fill</span>=<span class="hljs-string">"none"</span>
      <span class="hljs-attr">viewBox</span>=<span class="hljs-string">"0 0 24 24"</span>
      <span class="hljs-attr">stroke</span>=<span class="hljs-string">"currentColor"</span>
      <span class="hljs-attr">strokeWidth</span>=<span class="hljs-string">{2}</span>
    &gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">path</span>
        <span class="hljs-attr">strokeLinecap</span>=<span class="hljs-string">"round"</span>
        <span class="hljs-attr">strokeLinejoin</span>=<span class="hljs-string">"round"</span>
        <span class="hljs-attr">d</span>=<span class="hljs-string">"M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"</span>
      /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">svg</span>&gt;</span></span>
  );
}
</code></pre>
<hr />
<p>HeroIcon also provides <a target="_blank" href="https://www.npmjs.com/package/@heroicons/react">Library for React</a> to use their icon easily and like reusable components as we did earlier.</p>
<p>To use this library First, you need to install <code>@heroicons/react</code> it on npm by running the following command.</p>
<pre><code class="lang-javascript">npm install @heroicons/react
</code></pre>
<p>Now each icon can be imported individually as a React component:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { BeakerIcon } <span class="hljs-keyword">from</span> <span class="hljs-string">'@heroicons/react/24/solid'</span>

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyComponent</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">BeakerIcon</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"h-6 w-6 text-blue-500"</span>/&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  )
}
</code></pre>
<p>If you need 24x24 outline icons you can be imported them from <code>@heroicons/react/24/outline</code>.</p>
<p>20x20 size can also be used in this library by import like this.</p>
<ul>
<li><p><code>@heroicons/react/24/outline</code> for 20x20 outline Icons</p>
</li>
<li><p><code>@heroicons/react/24/solid</code> for 20x20 solid  Icons</p>
</li>
</ul>
<p>To See more guides and all icons provided by HeroIcons you can visit <a target="_blank" href="https://heroicons.com/">their site</a>.</p>
]]></content:encoded></item><item><title><![CDATA[How to use bootstrap with create-react-app]]></title><description><![CDATA[To use Bootstrap with React, you will need to install the React-Bootstrap package. This package provides React components that use Bootstrap styles, so you can use the components and styles from the Bootstrap library in your React app.
Here is an exa...]]></description><link>https://blog.zasela.site/how-to-use-bootstrap-with-create-react-app</link><guid isPermaLink="true">https://blog.zasela.site/how-to-use-bootstrap-with-create-react-app</guid><category><![CDATA[React]]></category><dc:creator><![CDATA[Asela Priyadarshana]]></dc:creator><pubDate>Thu, 15 Dec 2022 07:03:32 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1671087744263/LL-YNdv_K.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>To use Bootstrap with React, you will need to install the React-Bootstrap package. This package provides React components that use Bootstrap styles, so you can use the components and styles from the Bootstrap library in your React app.</p>
<p>Here is an example of how to use the React-Bootstrap package to add a button to your React app:</p>
<ol>
<li>First, install the React-Bootstrap package by running the following command:</li>
</ol>
<pre><code class="lang-javascript">npm install react-bootstrap bootstrap
</code></pre>
<ol start="2">
<li>Import the React-Bootstrap components that you want to use in your app. For example, to use the Button component from React-Bootstrap, you would add the following import statement to your JavaScript file:</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { Button } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-bootstrap'</span>;
</code></pre>
<ol start="3">
<li>Use the imported React-Bootstrap components in your app. For example, to add a button to your app, you would use the <code>&lt;Button&gt;</code> component like this:</li>
</ol>
<pre><code class="lang-javascript">&lt;Button variant=<span class="hljs-string">"primary"</span>&gt;Click me!&lt;/Button&gt;
</code></pre>
<p>That's it! You can now use the React-Bootstrap components in your app and style them with the styles from the Bootstrap library.</p>
]]></content:encoded></item><item><title><![CDATA[useState hook in react - Complete Guide]]></title><description><![CDATA[In React, the useState hook allows you to add a state to functional components. It is a way to manage and manipulate the state in your components without using a class.
To use the useState hook, you need to import it at the top of your component file...]]></description><link>https://blog.zasela.site/usestate-hook-in-react-complete-guide</link><guid isPermaLink="true">https://blog.zasela.site/usestate-hook-in-react-complete-guide</guid><category><![CDATA[React]]></category><dc:creator><![CDATA[Asela Priyadarshana]]></dc:creator><pubDate>Tue, 06 Dec 2022 06:44:21 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1671086797489/dxF2v6W6sj.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In React, the <code>useState</code> hook allows you to add a state to functional components. It is a way to manage and manipulate the state in your components without using a class.</p>
<p>To use the <code>useState</code> hook, you need to import it at the top of your component file:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
</code></pre>
<p>After importing <code>useState</code>, you can use it in your functional component by calling it inside the component. The <code>useState</code> hook takes an initial state as an argument and returns an array with two elements: the current state value and a function that updates the state.</p>
<p>For example, if you want to create a <code>count</code> state variable that is initially set to 0, you can use <code>useState</code> like this:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyComponent</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-number">0</span>);

  <span class="hljs-comment">// other component code here...</span>
}
</code></pre>
<p>This code sets the <code>count</code> variable to 0 and assigns the <code>setCount</code> function to update the value of <code>count</code>.</p>
<p>To update the value of <code>count</code>, you can call the <code>setCount</code> function and pass the new value as an argument. For example:</p>
<pre><code class="lang-javascript">setCount(<span class="hljs-number">1</span>); <span class="hljs-comment">// sets count to 1</span>
setCount(count + <span class="hljs-number">1</span>); <span class="hljs-comment">// increments count by 1</span>
</code></pre>
<p>You can use the <code>useState</code> hook multiple times in a single component to create multiple state variables.</p>
<p>Here is an example of a functional component that uses <code>useState</code> to keep track of a count and a value:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyComponent</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-number">0</span>);
  <span class="hljs-keyword">const</span> [value, setValue] = useState(<span class="hljs-string">''</span>);

  <span class="hljs-comment">// other component code here...</span>
}
</code></pre>
<p>In this example, the component has two state variables: <code>count</code> and <code>value</code>. The <code>count</code> the variable is initially set to 0, and the <code>value</code> the variable is initially set to an empty string. The component has two functions, <code>setCount</code> and <code>setValue</code>, to update the values of these state variables.</p>
<p>The <code>useState</code> a hook is a powerful tool that enables you to add state to functional components in React. The state is an essential part of any app that has dynamic data, and the <code>useState</code> the hook makes it easy to manage the state in your functional components.</p>
<p>The <code>useState</code> hook takes an initial state value as an argument and returns an array with two elements: the current state value and a function that updates the state. You can use the returned function to update the state value, and the state value will be updated in the component automatically.</p>
<p>You can use the <code>useState</code> hook multiple times in a single component to create multiple state variables. This is useful when you need to manage different pieces of state in your component.</p>
<p>Here is an example of how you might use <code>useState</code> to manage a form input in a functional component:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyForm</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [inputValue, setInputValue] = useState(<span class="hljs-string">''</span>);

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleChange</span>(<span class="hljs-params">event</span>) </span>{
    setInputValue(event.target.value);
  }

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">form</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{inputValue}</span> <span class="hljs-attr">onChange</span>=<span class="hljs-string">{handleChange}</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span></span>
  );
}
</code></pre>
<p>In this example, the <code>MyForm</code> the component has a state variable called <code>inputValue</code> that is initially set to an empty string. The <code>handleChange</code> the function is called whenever the user types something into the form input, and it updates the <code>inputValue</code> state variable with the current value of the input. This ensures that the input value is always up-to-date and in sync with the state.</p>
<p>The <code>useState</code> a hook is a versatile tool that can help you manage the state of your React apps. It is easy to use and can make your code more concise and maintainable.</p>
<p><a target="_blank" href="https://reactjs.org/docs/hooks-state.html">Read more about useState hook in react documentation</a></p>
]]></content:encoded></item><item><title><![CDATA[How to use react usecallback hook in ReactJs]]></title><description><![CDATA[The useCallback hook is a React hook that lets you optimize the performance of your function components by caching the functions that don't change between renders. This is especially useful for functions that are passed as props to child components, ...]]></description><link>https://blog.zasela.site/how-to-use-react-usecallback-hook-in-reactjs</link><guid isPermaLink="true">https://blog.zasela.site/how-to-use-react-usecallback-hook-in-reactjs</guid><category><![CDATA[React]]></category><dc:creator><![CDATA[Asela Priyadarshana]]></dc:creator><pubDate>Tue, 15 Nov 2022 07:17:58 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1671088607010/EKok5FJz6.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The <code>useCallback</code> hook is a React hook that lets you optimize the performance of your function components by caching the functions that don't change between renders. This is especially useful for functions that are passed as props to child components, because it prevents the child components from re-rendering every time unless its props have changed.</p>
<p>Here is an example of how to use the <code>useCallback</code> hook:</p>
<pre><code class="lang-javascript">Copy codeimport React, { useState, useCallback } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Example</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-comment">// Declare a state variable and a function to update the state</span>
  <span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-number">0</span>);

  <span class="hljs-comment">// Declare a function that will be passed as a prop to a child component</span>
  <span class="hljs-keyword">const</span> handleClick = useCallback(<span class="hljs-function">() =&gt;</span> {
    setCount(count + <span class="hljs-number">1</span>);
  }, [count]);

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>You clicked {count} times<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">ChildComponent</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{handleClick}</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ChildComponent</span>(<span class="hljs-params">props</span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{props.onClick}</span>&gt;</span>
      Click me
    <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
  );
}
</code></pre>
<p>In this example, the <code>handleClick</code> the function is wrapped with <code>useCallback</code>, and the <code>count</code> variable is passed as the second argument to <code>useCallback</code>. This means that the <code>handleClick</code> function will only be re-created if the <code>count</code> variable changes. This prevents the child component from re-rendering every time the parent component re-renders, and improves the performance of the app.</p>
<p><a target="_blank" href="https://reactjs.org/docs/hooks-reference.html#usecallback">React documentation about useCallback</a></p>
]]></content:encoded></item></channel></rss>