<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" 
     xmlns:content="http://purl.org/rss/1.0/modules/content/"
     xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Devarshi Shimpi's Blog</title>
    <description>Insights, tutorials, and thoughts on web development, cloud computing, and modern technology by Devarshi Shimpi</description>
    <link>https://devarshi.dev</link>
    <language>en-us</language>
    <lastBuildDate>Wed, 29 Jul 2026 16:16:58 GMT</lastBuildDate>
    <ttl>60</ttl>
    <atom:link href="https://devarshi.dev/rss.xml" rel="self" type="application/rss+xml"/>
    <image>
      <url>https://static.devarshi.dev/devarshi-logo.jpeg</url>
      <title>Devarshi Shimpi's Blog</title>
      <link>https://devarshi.dev</link>
      <width>144</width>
      <height>144</height>
    </image>
    <managingEditor>devarshishimpi@gmail.com (Devarshi Shimpi)</managingEditor>
    <webMaster>devarshishimpi@gmail.com (Devarshi Shimpi)</webMaster>
    <category>Technology</category>
    <category>Programming</category>
    <category>Web Development</category>
    <category>Cloud Computing</category>
    <item>
      <title><![CDATA[How the Bitcoin Network Actually Works]]></title>
      <description><![CDATA[A layered walkthrough of Bitcoin: hashes, keys, UTXOs, blocks, proof of work and fees, with interactive demos you can run right in the browser.]]></description>
      <content:encoded><![CDATA[<h2>How to read this</h2><p>Bitcoin gets called a lot of things: digital gold, internet money, a scam, a revolution. This guide skips all of that. It is not about what Bitcoin is _for_. It is about what Bitcoin _is_: the parts, how they fit, and why they work.</p><p>We are going to build the idea up in layers, because that is genuinely how Bitcoin is put together. Each layer sits on top of the one below it. If you skip a layer, the ones above look like magic. If you take them in order, the magic turns into something more satisfying: plain engineering.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-HowTheBitcoinNetworkActuallyWorks/btc-diagram-foundation-infra.png">btc-diagram-foundation-infra</a></p><p><strong>A quick note on numbers.</strong> The _rules_ in this guide (how often blocks appear, the coin limit, how a block is structured) are fixed by the software and do not change. The _live figures_ (how much computing power is on the network, how busy it is, the price) change all the time. Where I mention one of those, treat it as "roughly true in mid-2026" and check a live site for today's value.</p><h2>What we are actually looking at</h2><p>Here is the one-sentence version of the whole thing:</p><p>> Bitcoin is a way for a huge group of strangers, who do not trust each other and have no boss, to agree on a single shared list of who owns what.</p><p>That is harder than it sounds. Normally, when a group needs to agree on something, someone is in charge. A bank keeps the official record of your balance. A referee makes the call. Bitcoin has no one in charge, and some of the people taking part may be actively trying to cheat. Somehow it still ends up with one agreed answer.</p><p>By the end of this guide you should be able to explain, in your own words, why a coin cannot be spent twice, why sending Bitcoin costs a fee, why the mining difficulty keeps adjusting up and down, why "running a node" and "mining" are two completely different jobs, and what actually happens in the roughly ten minutes between tapping <strong>send</strong> and the payment becoming permanent.</p><h2>The one problem Bitcoin was built to solve</h2><p>Everything starts here, so it is worth slowing down.</p><p>The problem is called <strong>double spending</strong>, and it only exists for digital money.</p><p>Think about a physical $20 bill. When you hand it to a shop, you no longer have it. The object moved from your hand to theirs. You physically cannot be in two shops spending the same bill at the same time.</p><p>Now think about anything digital: a photo, a song, a file. Copying it is free and perfect. You can send the exact same photo to a thousand people at once, and each copy is flawless. That is great for photos. It is a disaster for money. If a "coin" were just a file, you could send the same coin to a thousand different people, and each one would see a perfectly real coin. Only later would everyone realise they were all paid with the same money.</p><p>The usual fix is to put someone in charge. A bank keeps one official list. When you pay, the bank subtracts from your row and adds to someone else's row. Because there is only one list, controlled by one company, the same dollar cannot be in two places. This works, and most of the world runs on it. But it comes with a cost. You have to trust that company. It can freeze you, reverse payments, get hacked, go under, or simply charge you for the service.</p><p>So the question that led to Bitcoin was very specific:</p><p>> Can you keep one official list of who owns what, <strong>without anyone being in charge of the list?</strong></p><h2>Two pieces of math hold up everything else</h2><p>Almost every surprising thing about Bitcoin comes from one of two tools. Neither was invented for Bitcoin. Both are decades old and used all over the internet.</p><h3>Tool 1: the fingerprint machine (a hash)</h3><p>A <strong>hash function</strong> is like a machine that takes anything you feed it (a word, a file, an entire book) and spits out a short jumble of characters. Bitcoin uses one called <strong>SHA-256</strong>, whose output is always 64 characters long. Feed in a single letter or the complete works of Shakespeare, and you still get exactly 64 characters back. People often call this output a <strong>fingerprint</strong>, and that is the word I will use.</p><p>Three things make it special, and the whole security of Bitcoin leans on them:</p><p>1. <strong>Same input, same fingerprint, every time.</strong> Anyone, anywhere, feeding in the same thing gets the same result. No coordination needed.<br/>2. <strong>Change the input a tiny bit, and the fingerprint changes completely.</strong> There is no "close." Change one letter and about half the output flips, with no pattern connecting the two.<br/>3. <strong>You cannot run it backwards.</strong> Given a fingerprint, there is no way to figure out what was fed in, other than guessing. And there are so many possible fingerprints that guessing is hopeless. (For scale: the number of possible outputs is far larger than the number of atoms on Earth.)</p><p>Point 2 is the one people underestimate, so here it is made concrete. Type a word below, and the second row will show the same word with a single letter changed. The characters that differ are highlighted:</p><p><AvalancheEffect /><p>This matters a lot later. Because there is no "getting warmer," you cannot be clever and steer a fingerprint toward a shape you want. Your only option is to try, check, and try again. Remember that.</p><p>A good way to build intuition is to feel it yourself. Use the playground below, type something, and change one letter at a time:</p><p><HashPlayground /><p>One more detail for the curious: Bitcoin usually runs this machine _twice_ in a row, taking the fingerprint of the fingerprint. You do not need to remember why. Just know that when you hear "the block's ID" or "the transaction ID," that is one of these fingerprints.</p><h3>Tool 2: a lock only you can close, that anyone can check</h3><p>The second tool answers a different question: how do you prove you are allowed to spend a coin, without giving away a secret that would let anyone else spend it too?</p><p>The answer is a matched pair of keys:</p><p>- A <strong>private key</strong>, which is basically a giant secret random number that only you know.<br/>- A <strong>public key</strong>, which is calculated from the private key and which you can share freely.</p><p>Like the fingerprint machine, this only runs one way. It is easy to make the public key from the private key, and effectively impossible to go backwards.</p><p>With this pair you can do two things:</p><p>- <strong>Sign.</strong> Using your private key, you can stamp a specific message (a payment) with a unique signature. The signature only works for that key and that exact message.<br/>- <strong>Verify.</strong> Anyone with your public key can check that the signature is real, which proves _you_ made it, without ever seeing your private key.</p><p>A helpful picture: think of a special wax seal that only your ring can press, but that anyone in the world can recognise on sight. You never hand over the ring. You just stamp things, and everyone can confirm the stamp is yours.</p><p>This is the entire idea of owning Bitcoin. A coin is not sitting "inside" a wallet like a file in a folder. To own Bitcoin simply means you know a private key that can produce a valid signature to move that coin. Lose the key and the coins are stuck forever. There is no support line and no reset button. That is what people mean by the phrase "not your keys, not your coins."</p><h2>From a secret number to an address</h2><p>You have probably seen a Bitcoin address, one of those long strings starting with <code>bc1</code>. Here is where it comes from, and it is just the two tools from the previous section (the fingerprint machine and the key pair) chained together.</p><p>The path runs in one direction only: <strong>private key</strong> to <strong>public key</strong> to <strong>address</strong>.</p><p>Each step is easy to walk forwards and practically impossible to walk backwards. You make the public key from the private key using the key math. Then you make the address by taking the fingerprint of the public key.</p><p>Because of that one-way street, two everyday facts fall out:</p><p>- <strong>Sharing your address is safe.</strong> It is downstream of everything secret, so it gives nothing away. People can send you money, and that is all.<br/>- <strong>Sharing your private key is a catastrophe.</strong> It is the thing at the very start of the chain. Anyone who has it can sign, which means they can spend everything.</p><p>You may notice addresses start with different prefixes. A quick key:</p><p>- <code>1...</code> is <strong>P2PKH (legacy)</strong>, the original address style.<br/>- <code>3...</code> is <strong>P2SH</strong>, often used for shared or multi-key setups.<br/>- <code>bc1q...</code> is <strong>native SegWit v0 (Bech32)</strong>, cheaper and more efficient, from the 2017 SegWit upgrade.<br/>- <code>bc1p...</code> is <strong>Taproot / SegWit v1 (Bech32m)</strong>, the newest style, from the 2021 Taproot upgrade.</p><p>They all do the same basic job: they are a safe-to-share destination for money. As a quick rule of thumb, Taproot addresses commonly start with <code>bc1p</code>, and the older native SegWit addresses start with <code>bc1q</code>.</p><h2>Blocks, and why they form a chain</h2><p>Now we can build the record itself.</p><p>A <strong>block</strong> is simply a batch of transactions bundled together, plus a small label on top called the <strong>header</strong>. Think of a block as one page in a shared notebook. The page has a body (the list of payments) and a heading (the summary info). New pages are added roughly every ten minutes, and each page can hold a few thousand payments.</p><p>The header is small but it is where the clever part lives. Tap any field below to see what it does:</p><p><BlockHeader /><p>The single most important field is the <strong>previous block's fingerprint</strong>. Every block's header contains the fingerprint of the block right before it. That one detail is what turns a pile of separate pages into a connected <strong>chain</strong>.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-HowTheBitcoinNetworkActuallyWorks/btc-diagram-fingerprint-blocks.png">btc-diagram-fingerprint-blocks</a></p><p>Here is why that chain is so powerful. Imagine a cheater wants to secretly change a payment in an old block. The moment they change anything in that old block, its fingerprint changes (that is the fingerprint machine from earlier). But the _next_ block was carrying the _old_ fingerprint. So now the next block does not match, and its own fingerprint would need to change too, which breaks the block after that, and so on all the way to the present.</p><p>In other words, you cannot quietly edit page 400 of the notebook. Editing it visibly wrecks every page after it. To make the change stick, the cheater would have to redo every single page from 400 to now, faster than the rest of the world is adding new pages. The section on proof of work explains why that is effectively impossible.</p><h2>Merkle trees: summing up thousands of payments with one fingerprint</h2><p>You may have spotted a field in the header called the <strong>Merkle root</strong>. It sounds fancy. The idea is simple and genuinely elegant.</p><p>A block might hold thousands of transactions. The header does not want to store all of them, but it does want a way to lock them in so none can be swapped out later. The trick is to squash all of them down into a single fingerprint, built like a knockout tournament.</p><p>Pair up the transactions and take a fingerprint of each pair. Then pair up _those_ fingerprints and hash them. Keep going until only one fingerprint is left standing. That final winner is the <strong>Merkle root</strong>, and it goes in the header.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-HowTheBitcoinNetworkActuallyWorks/btc-diagram-merkle-root.png">btc-diagram-merkle-root</a></p><p>Two nice things come out of this:</p><p>- <strong>Nothing can be swapped.</strong> Change any single payment and its fingerprint changes, which changes its pair, which changes the root, which changes the whole block. The root locks everything in.<br/>- <strong>You can prove one payment is in a block without downloading the whole block.</strong> This is how a phone wallet can confirm your payment landed without storing the entire history of Bitcoin. It only needs a short trail of fingerprints up the tree, not the thousands of other payments.</p><h2>Coins are not a balance, they are more like cash</h2><p>This is the part that trips up almost everyone, because it works differently from a bank.</p><p>Your bank account has a single number: your balance. When you spend, the number goes down. Bitcoin does not work that way. Bitcoin is more like a wallet full of actual bills and coins of odd sizes.</p><p>In Bitcoin, when you receive money, you receive it as a distinct chunk, like being handed a specific bill. The proper name for one of these unspent chunks is an <strong>unspent transaction output</strong>, usually shortened to <strong>UTXO</strong>. You do not need the jargon. Just picture bills of random sizes sitting in your wallet.</p><p>Now, here is the cash-like rule: <strong>you cannot spend part of a bill.</strong> Pick which coins to spend below and drag the payment amount around to see what comes back as change:</p><p><UtxoFlow /><p>The tiny bit that does not come back as change is the <strong>fee</strong>, which the miner who includes your payment gets to keep. There is more on fees in the section on the waiting room below.</p><p>Two everyday consequences of this design:</p><p>- <strong>Your "balance" is not stored anywhere.</strong> Your wallet app just scans the record, finds every chunk that belongs to your keys, and adds them up to show you a number. Nobody wrote that number down.<br/>- <strong>Privacy is fiddly.</strong> Because change comes back as a new chunk, following the trail of chunks is how blockchain analysts try to trace activity.</p><h2>Two different jobs: nodes and miners</h2><p>People mix these up constantly. They are separate roles, and most participants only do one of them.</p><p><strong>Nodes are the referees.</strong> A node is a computer running the Bitcoin software that keeps a full copy of the record and checks every single rule. Is this signature valid? Does this person actually own the coins they are trying to spend? Is this block properly formed? If anything breaks a rule, the node rejects it and refuses to pass it on. There are tens of thousands of these referees around the world, and crucially, _anyone can run one on ordinary hardware._ This is the real backbone of Bitcoin. The rules are enforced by thousands of independent copies, not by any authority.</p><p><strong>Miners are the record keepers who compete for the right to add the next page.</strong> Their job is to bundle waiting transactions into a new block and win the right to add it. This takes serious specialised equipment and a lot of electricity. The next section is all about what they are actually doing.</p><p>The key thing to take away: <strong>miners propose, nodes decide.</strong> A miner can build any block it likes, but if that block breaks the rules, every honest node simply throws it away and the miner wasted its effort for nothing. Power in Bitcoin is split on purpose.</p><h2>Proof of work: the guessing game you cannot cheat</h2><p>This is the heart of Bitcoin, and thanks to the two tools from earlier it is now easy to explain.</p><p>To add the next block, a miner has to win a guessing game. Remember the header has a field called the <strong>nonce</strong>, which is just a number the miner is free to change. The game is this: find a nonce so that when you take the fingerprint of the whole header, the result is small enough.</p><p>To be precise: a fingerprint is really just a very large number written in hex. The header also carries a <strong>target</strong> value (packed into a small field called <code>nBits</code>). A block only counts as valid if its fingerprint, read as a number, comes out <strong>below that target</strong>. The lower the target, the fewer fingerprints qualify, and the harder the puzzle. The easy way to picture "below the target" is "the fingerprint has to start with a certain number of zeros," and that is the mental model I will use, but keep in mind the real rule is the numeric comparison against the target.</p><p>That is it. Because of the fingerprint machine's "no getting warmer" rule from earlier, there is no smart way to find such a nonce. You cannot calculate it. You cannot nudge the number in the right direction. You can only try a nonce, take the fingerprint, check if it has enough leading zeros, and if not, add one and try again. Over and over, billions of times per second.</p><p>You can feel exactly how this works with the demo below. Type a message, choose how many leading zeros you want, and hit start. Your browser will do the same dumb loop a real miner does, just far slower. Add one more required zero and watch the work roughly multiply:</p><p><HashGrinder /><p>Now, why is this pointless-looking effort actually useful? Because of a beautiful lopsidedness:</p><p>- <strong>Very hard to do, instant to check.</strong> Finding a winning nonce takes the entire network huge effort. But _checking_ someone else's winning block takes any referee a split second: take the fingerprint once, count the zeros, done. Making the proof is expensive. Verifying the proof is free.<br/>- <strong>Lying costs real money.</strong> A winning block represents real electricity that got burned. To rewrite an old block, a cheater would have to burn all that electricity again, plus redo every block since, plus keep outrunning the entire rest of the world adding new blocks in real time, forever. It is not that cheating is banned. It is that cheating is wildly more expensive than playing fair.</p><p>That last point is the whole security model in one line: <strong>behaving honestly pays better than attacking.</strong></p><h3>Why almost nobody mines alone</h3><p>Winning a block is a lottery. If you mine by yourself, you might go months or years without ever winning, then win once, then nothing again. That wild unpredictability is unbearable for most operators trying to pay an electricity bill.</p><p>So miners team up into <strong>pools</strong>. A pool has thousands of miners all working on the same block and splitting any reward in proportion to how much work each one did. This turns a wild lottery into a steady, paycheck-like income. The downside is that it concentrates a lot of decision-making into a handful of large pools, which is one of the genuine worries about Bitcoin today.</p><h2>Keeping blocks ten minutes apart, forever</h2><p>Bitcoin aims for a new block roughly every ten minutes. But the amount of computing power aimed at the network is always changing. More miners join, better machines arrive, prices swing and some switch off. So how does the gap stay near ten minutes?</p><p>The network <strong>retunes the difficulty</strong> automatically. Every 2,016 blocks (which at ten minutes each works out to about two weeks), every node does the same simple check: did the last stretch of blocks arrive faster or slower than the ten-minute target? The difficulty then adjusts up or down accordingly. If the last period was mined too fast, the puzzle gets harder (the target drops, so more leading zeros are needed). If it was too slow, the puzzle gets easier. It can and regularly does move in both directions.</p><p>A good mental image is a treadmill that speeds up as more runners jump on, so that a runner still crosses the line about every ten minutes no matter how many are racing. This is why you cannot make Bitcoin produce coins faster by throwing more machines at it. Add more power and the puzzle simply gets harder to match.</p><p>Every node calculates this adjustment independently and arrives at the same answer, because they all follow the same rule on the same shared record. No committee, no announcement. Just math everyone runs.</p><h2>New coins, the halving, and the 21 million limit</h2><p>So where do new coins come from, and who gets them?</p><p>Whoever wins a block gets to include one special payment at the top that creates brand new coins out of nothing and pays them to the winner. This is the <strong>reward</strong>, and it is the incentive that makes people spend money on mining in the first place. The winner also collects all the fees from the transactions in that block.</p><p>Here is the famous twist. That reward <strong>cuts in half every four years</strong> (more precisely, every 210,000 blocks). It started at 50 coins per block in 2009. It dropped to 25, then 12.5, then 6.25, and in 2024 to 3.125. This is called <strong>the halving</strong>.</p><p>Because the reward keeps halving, the total number of coins that can ever exist adds up to a fixed ceiling: <strong>21 million</strong>, and not one more. New coins trickle out more and more slowly until, sometime around the year 2140, the reward rounds down to zero and no new coins are ever made again.</p><p><SupplyCurve /><p>This fixed limit is a large part of why supporters compare Bitcoin to gold. There is a hard cap, and no one can vote to print more. As of mid-2026, roughly 20.06 million of the 21 million already exist. (That figure keeps ticking up slowly, so treat it as a snapshot and check a live source for today's exact number. The 21 million cap itself never moves.)</p><p>There is an obvious question hiding here: if the reward eventually falls to zero, why would anyone keep mining? The intended answer is fees. As the new-coin reward shrinks, transaction fees are meant to become the main thing miners earn. Whether fees alone will be enough to keep the network secure that far out is a real and openly debated question. Nobody knows for certain.</p><h2>The waiting room and why fees exist</h2><p>When you send Bitcoin, it does not go straight into a block. First it waits in the <strong>mempool</strong> as an unconfirmed transaction until a miner picks it up. It is tempting to picture one single worldwide queue, but that is not quite how it works. Each node keeps its _own_ local pool of the valid, unconfirmed transactions it has heard about. These local pools overlap heavily, so they look similar, but there is no one official global waiting room. Think of it as many nearly-identical waiting rooms rather than a single one.</p><p>Here is the catch: a block only has room for so many transactions. When more people want in than there is space, miners have to choose. And they choose the way you would expect anyone paid by tips to choose: <strong>they prefer the payments offering the highest fee for the space they take up.</strong></p><p>Think of a miner as a taxi with limited room and a line of passengers, each waving a different tip. The driver naturally picks whoever pays the most per seat. If you attach a generous fee, you get into the next block. If you attach a stingy fee during a busy period, you wait, sometimes a long time.</p><p>One important detail: the fee is not based on how much money you are sending. It is based on how much _space_ your transaction takes up in a block. That space is measured in <strong>virtual bytes</strong> (also called weight), a size measure introduced by the 2017 SegWit upgrade. What miners actually rank by is the <strong>fee rate</strong>: the fee divided by that virtual size. So a payment moving a fortune can be cheap if it is small and simple, and a payment moving pocket change can be expensive if it is large and complicated. You are paying for room on the page, not for the value being moved.</p><p>Two features exist to help when you guess the fee wrong:</p><p>- <strong>Bumping the fee</strong> lets you resend a stuck transaction with a higher fee to jump the line.<br/>- <strong>Child pays for parent</strong> lets a follow-up transaction attach a big fee to drag a stuck earlier one along with it, since a miner has to include the earlier one to collect the juicy later fee.</p><h2>What happens when two miners win at once</h2><p>Sometimes two miners find a valid block at nearly the same moment, in different parts of the world. For a short while, the network disagrees. Part of it heard about block A, part of it heard about block B. This is called a <strong>fork</strong>, and it is normal and expected, not a crisis.</p><p>The tie does not last. Miners keep working, and soon someone builds the _next_ block on top of one of the two. Say the next block lands on top of A. Now the "A" side of the record is longer, and the rule everyone follows is simple: <strong>the version with the most work built on it wins.</strong> Everyone switches to the longer branch. Block B, the loser, is abandoned, and its transactions (which are almost always also in A) go back into the waiting room to be included normally.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-HowTheBitcoinNetworkActuallyWorks/btc-diagram-blocks.png">btc-diagram-blocks</a></p><p>This is exactly why people say to wait for a few <strong>confirmations</strong> on a big payment. One confirmation means your payment made it into a block. Each additional block stacked on top makes it exponentially harder to ever reverse, because a cheater would have to redo that block and all the ones after it faster than the whole network. For large amounts, waiting for about six blocks (roughly an hour) is the traditional comfort zone.</p><h3>The "51 percent attack," in plain terms</h3><p>You may have heard that if someone controlled a majority of the network's mining power, they could attack Bitcoin. That is true, but it is worth being precise about what they could and could not do.</p><p><strong>Could</strong> do: with the majority of power, an attacker could out-build the honest network and rewrite _recent_ history, which would let them undo one of their own recent payments and effectively spend the same coins twice.</p><p><strong>Could not</strong> do, even with all that power: steal coins from an address they do not have the key for (they still cannot forge a signature), create coins out of thin air beyond the rules, or change the rules everyone else's nodes enforce. The referees would simply reject anything invalid.</p><p>So even the scariest attack is limited, expensive, and easy to notice. It cannot quietly drain your wallet.</p><h2>Upgrading a system with no boss</h2><p>If nobody is in charge, how does Bitcoin ever get updated? Carefully, and with the agreement of the people running nodes. There are two flavours of change:</p><p>- A <strong>soft fork</strong> tightens the rules in a way that older software still accepts. It is backwards compatible, so it can roll out smoothly. The 2017 upgrade known as <strong>SegWit</strong> and the 2021 upgrade known as <strong>Taproot</strong> were both soft forks. They made transactions more efficient and more private without forcing everyone to upgrade on the same day.<br/>- A <strong>hard fork</strong> changes the rules in a way older software will _reject_. If some people upgrade and some do not, the network can split permanently into two separate coins. This is a much bigger deal and much rarer, because it needs near-universal agreement to avoid a messy divorce.</p><p>The short version: Bitcoin can improve, but only by broad agreement, and it strongly prefers changes that do not break anyone who has not upgraded yet.</p><h2>Going faster: layers on top</h2><p>Every payment we have described so far gets written into the shared record, checked by every referee on Earth. That is wonderfully secure, but it is not built for buying a coffee. It is a bit like asking the whole world to witness and file paperwork for a $3 purchase.</p><p>The common solution is to add a faster layer on top, the best known being the <strong>Lightning Network</strong>. The idea in plain terms: two people (or a chain of people) open a private tab between them, make as many instant, nearly free payments back and forth as they like, and only write to the main record twice, once to open the tab and once to close it and settle the final total.</p><p>It is the same instinct as running a bar tab instead of paying the bank for every single sip. The slow, heavily witnessed main chain becomes the final settlement layer, and the fast layer on top handles the everyday small stuff.</p><h2>The machines and the electricity question</h2><p>Early on, people mined Bitcoin on ordinary computers. That did not last. Because mining is just the same fingerprint calculation repeated as fast as possible, hardware makers built chips that do _only_ that one calculation and nothing else, insanely fast. These are called <strong>ASICs</strong>, and today serious mining happens in warehouses full of them.</p><p>This is where the well-known energy debate comes from, and it is worth stating both sides fairly rather than picking one:</p><p>- <strong>The concern:</strong> all that guessing burns a genuinely large amount of electricity for a task that, from the outside, produces no physical product. Critics argue that is wasteful and adds to carbon emissions.<br/>- <strong>The response:</strong> supporters argue the electricity is the _point_, since that real cost is exactly what makes cheating too expensive. They also point out that miners chase the cheapest power, which is often surplus, stranded, or renewable energy that would otherwise go unused, and that plenty of other industries use comparable amounts of energy with less scrutiny.</p><p>Both sides have real arguments. Where you land tends to depend on how much value you think a boss-free, tamper-resistant global record actually provides. This guide is not going to settle that for you, and honest people disagree.</p><h2>A few myths worth clearing up</h2><p>- <strong>"Bitcoin is anonymous."</strong> Not really. Every payment is public and permanent. Names are not attached directly, but the trail of coins can often be followed and linked to real identities. It is more like writing in a public ledger under a pen name than being invisible.<br/>- <strong>"A bitcoin is a coin sitting in a file somewhere."</strong> No. There is no coin object. There is only the record of which keys control which chunks of value. Owning Bitcoin means holding a key that can sign.<br/>- <strong>"You have to buy a whole bitcoin."</strong> No. Each coin divides into 100 million tiny units, so you can own and send a very small slice.<br/>- <strong>"Miners approve or reject your payment based on who you are."</strong> No. Miners mostly just take the highest fees. The rules are enforced by the referee nodes, not decided by miners' opinions of you.<br/>- <strong>"If the price crashes, the coins vanish."</strong> No. Price is what people will pay. The record of who owns what does not care about the price and keeps working exactly the same either way.</p><h2>The whole life of a payment, start to finish</h2><p>Let us tie every layer together by following one payment from the moment you tap send to the moment it is permanent.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-HowTheBitcoinNetworkActuallyWorks/btc-diagram-pay-cycle.png">btc-diagram-pay-cycle</a></p><p>Look back at what each step used:</p><p>- Step 1 is the <strong>UTXO</strong> model (coins as cash): whole coins in, payment and change out.<br/>- Step 2 is a <strong>digital signature</strong>: the wax seal only you can press.<br/>- Steps 3 and 4 are the <strong>nodes</strong> doing their referee job.<br/>- Step 5 is the <strong>mempool and fees</strong>: the waiting room and the tip.<br/>- Steps 6 and 7 are <strong>proof of work</strong>: the guessing game.<br/>- Step 8 is the <strong>chain and confirmations</strong>: each new block locks the ones below it.</p><p>That is the entire machine. Fingerprints at the bottom. Signatures for ownership. Transactions built from signatures. Blocks built from transactions. A chain built from blocks. Agreement built from work. And an economy built on top of all of it.</p><p>None of it needs a boss. It needs only a rule that everyone can check for themselves, and a game that makes honesty the cheapest option. That is the quiet, stubborn idea at the centre of Bitcoin.</p><h2>Next in this series</h2><p>We have covered _why_ mining works and _what_ the guessing game is. In the next post we will get our hands dirty and actually watch proof of work happen on a real machine, using a mining program called XMRig to make the loop visible and tangible.</p><p>Small but important heads-up for later: XMRig cannot mine Bitcoin. Bitcoin mining today needs those special ASIC chips from the hardware section above, not a regular computer's processor. XMRig mines a different, processor-friendly coin. We are using it purely as a clear, hands-on window into the same guess-and-check idea you met here. See you there.</p><p>_Reference figures (network size, coins mined) reflect roughly mid-2026 and drift over time. The protocol rules (ten-minute target, the halving schedule, the 21 million cap, the block layout) are fixed by the software. When in doubt about a live number, check a public block explorer._<br/>]]></content:encoded>
      <link>https://devarshi.dev/blog/how-the-bitcoin-network-actually-works</link>
      <guid isPermaLink="true">https://devarshi.dev/blog/how-the-bitcoin-network-actually-works</guid>
      <pubDate>Sat, 25 Jul 2026 00:00:00 GMT</pubDate>
      <author>devarshishimpi@gmail.com (Devarshi Shimpi)</author>
      <enclosure url="https://static.devarshi.dev/blog/1600/HowTheBitcoinNetworkActuallyWorks1600.png" type="image/png"/>
      <category>Technology</category>
      <category>Programming</category>
      <category>Development</category>
    </item>
    <item>
      <title><![CDATA[5 Kyverno Policies to Secure Your Kubernetes Cluster]]></title>
      <description><![CDATA[Five practical Kyverno ClusterPolicy examples with demos: resource limits, image tags, required labels, privileged containers, and image signing.]]></description>
      <content:encoded><![CDATA[<h2>Introduction</h2><p>If you run workloads on Kubernetes, you already know how easy it is for small mistakes to slip into production. A missing resource limit here, a container running as root there, and suddenly your cluster has problems nobody planned for. This is exactly the kind of thing policy as code was built to fix, and <strong><a href="https://kyverno.io/">Kyverno</a></strong> is one of the easiest tools to start with.</p><p>Kyverno is a policy engine built specifically for Kubernetes. Instead of learning a new language to write rules, you write policies in plain YAML, the same format you already use for your deployments and services. That alone makes it a great starting point if you are new to Kubernetes security. Kyverno is also a CNCF Graduated project, which means it has passed a high bar for stability and community trust, and it is already used in production by companies like Spotify, LinkedIn, and Adidas.</p><p>In this post, we will walk through five Kyverno policies. We will start simple and end with something a bit more advanced, verifying container image signatures. Each one comes with a small demo so you can see exactly what happens when a policy blocks something. By the end, you will have a solid feel for how Kyverno works and a few policies you can actually use.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-5KyvernoPoliciesToSecureYourKubernetesCluster/how-kyverno-works-diagram.png">how-kyverno-works-diagram</a></p><p>Before we get into the policies, here is a quick picture of how Kyverno fits into the request flow. Every time you or your CI pipeline sends something to Kubernetes, Kyverno gets a chance to check it first.</p><p>A quick note before we start. Kyverno recently introduced a newer, CEL based way of writing policies, and the classic format used below (<code>ClusterPolicy</code>) is now marked as deprecated in the official docs, though it is still fully supported and works today. It is still the easiest format to learn as a beginner, and this guide points you to the migration path at the end, once you are ready for it.</p><h2>1. Require Resource Limits</h2><p>One of the most common problems in a shared cluster is a single pod using up all the CPU or memory on a node. This is often called the "noisy neighbor" problem, and it can slow down or crash other workloads running nearby.</p><p>This policy makes sure every pod defines both requests and limits for CPU and memory before it is allowed to run. You can see the full syntax for this kind of rule in the <a href="https://kyverno.io/docs/policy-types/cluster-policy/validate/">Kyverno validate rules docs</a>.</p><pre><code class="language-yaml">apiVersion: kyverno.io/v1<br/>kind: ClusterPolicy<br/>metadata:<br/>  name: require-requests-limits<br/>spec:<br/>  background: true<br/>  rules:<br/>    - name: validate-resources<br/>      match:<br/>        any:<br/>          - resources:<br/>              kinds:<br/>                - Pod<br/>      validate:<br/>        failureAction: Enforce<br/>        message: "CPU and memory resource requests and limits are required."<br/>        pattern:<br/>          spec:<br/>            containers:<br/>              - resources:<br/>                  requests:<br/>                    memory: "?*"<br/>                    cpu: "?*"<br/>                  limits:<br/>                    memory: "?*"<br/>                    cpu: "?*"<br/></code></pre><p>Once this is applied, any pod that does not set these values will simply be rejected. It is a small rule, but it prevents a lot of headaches later.</p><h3>Demo: what happens if you skip resource limits</h3><p>Say you try to apply this pod, which has no requests or limits set.</p><pre><code class="language-yaml">apiVersion: v1<br/>kind: Pod<br/>metadata:<br/>  name: no-limits-pod<br/>spec:<br/>  containers:<br/>    - name: app<br/>      image: nginx:1.27<br/></code></pre><pre><code class="language-sh">kubectl apply -f no-limits-pod.yaml<br/></code></pre><pre><code class="language-sh">Error from server: error when creating "no-limits-pod.yaml": admission webhook "validate.kyverno.svc-fail" denied the request:</p><p>resource Pod/default/no-limits-pod was blocked due to the following policies</p><p>require-requests-limits:<br/>  validate-resources: 'CPU and memory resource requests and limits are required.<br/>    Validation rule validate-resources failed at path /spec/containers/0/resources/'<br/></code></pre><p>Now add the missing fields and try again.</p><pre><code class="language-yaml">apiVersion: v1<br/>kind: Pod<br/>metadata:<br/>  name: with-limits-pod<br/>spec:<br/>  containers:<br/>    - name: app<br/>      image: nginx:1.27<br/>      resources:<br/>        requests:<br/>          memory: "128Mi"<br/>          cpu: "100m"<br/>        limits:<br/>          memory: "256Mi"<br/>          cpu: "250m"<br/></code></pre><pre><code class="language-sh">kubectl apply -f with-limits-pod.yaml<br/><h1>pod/with-limits-pod created</h1><br/></code></pre><p>That's it. The pod goes through as soon as it meets the policy.</p><h2>2. Block the "latest" Image Tag</h2><p>It is tempting to just use <code>image: myapp:latest</code> when you are getting started. The problem is that "latest" can point to a different image every time it is rebuilt. This makes deployments unpredictable and makes it very hard to know exactly what version of your app is actually running.</p><p>This policy blocks any pod that uses the "latest" tag, or no tag at all.</p><pre><code class="language-yaml">apiVersion: kyverno.io/v1<br/>kind: ClusterPolicy<br/>metadata:<br/>  name: disallow-latest-tag<br/>spec:<br/>  background: true<br/>  rules:<br/>    - name: require-image-tag<br/>      match:<br/>        any:<br/>          - resources:<br/>              kinds:<br/>                - Pod<br/>      validate:<br/>        failureAction: Enforce<br/>        message: "An image tag is required."<br/>        pattern:<br/>          spec:<br/>            containers:<br/>              - image: "<em>:</em>"<br/>    - name: validate-image-tag<br/>      match:<br/>        any:<br/>          - resources:<br/>              kinds:<br/>                - Pod<br/>      validate:<br/>        failureAction: Enforce<br/>        message: "Using a mutable image tag like 'latest' is not allowed."<br/>        pattern:<br/>          spec:<br/>            containers:<br/>              - image: "!*:latest"<br/></code></pre><p>This forces every team to use a proper version tag, which makes rollbacks and debugging much easier down the road. This exact example is adapted from the sample policy library that ships with the Kyverno project.</p><h3>Demo: what happens if you use "latest"</h3><pre><code class="language-yaml">apiVersion: v1<br/>kind: Pod<br/>metadata:<br/>  name: latest-tag-pod<br/>spec:<br/>  containers:<br/>    - name: app<br/>      image: myapp:latest<br/></code></pre><pre><code class="language-sh">kubectl apply -f latest-tag-pod.yaml<br/></code></pre><pre><code class="language-sh">Error from server: error when creating "latest-tag-pod.yaml": admission webhook "validate.kyverno.svc-fail" denied the request:</p><p>resource Pod/default/latest-tag-pod was blocked due to the following policies</p><p>disallow-latest-tag:<br/>  validate-image-tag: 'Using a mutable image tag like ''latest'' is not allowed.<br/>    Validation rule validate-image-tag failed at path /spec/containers/0/image/'<br/></code></pre><p>Swap in a real version and the pod goes through without any trouble.</p><pre><code class="language-yaml">apiVersion: v1<br/>kind: Pod<br/>metadata:<br/>  name: versioned-pod<br/>spec:<br/>  containers:<br/>    - name: app<br/>      image: myapp:1.4.2<br/></code></pre><pre><code class="language-sh">kubectl apply -f versioned-pod.yaml<br/><h1>pod/versioned-pod created</h1><br/></code></pre><h2>3. Require Labels</h2><p>Labels are how Kubernetes keeps things organized. They help you filter resources, connect them to monitoring tools, and figure out who owns what. Without labels, a growing cluster turns into a pile of unlabeled boxes nobody can identify.</p><p>This policy requires every pod to have a specific label before it can be created. If you want a refresher on what labels are for, the Kubernetes labels documentation is a good place to start.</p><pre><code class="language-yaml">apiVersion: kyverno.io/v1<br/>kind: ClusterPolicy<br/>metadata:<br/>  name: require-labels<br/>spec:<br/>  rules:<br/>    - name: check-for-labels<br/>      match:<br/>        any:<br/>          - resources:<br/>              kinds:<br/>                - Pod<br/>      validate:<br/>        failureAction: Enforce<br/>        message: "The label 'app.kubernetes.io/name' is required."<br/>        pattern:<br/>          metadata:<br/>            labels:<br/>              app.kubernetes.io/name: "?*"<br/></code></pre><p>You can add more required labels over time, like team name or environment, once this basic rule feels comfortable.</p><h3>Demo: what happens if a label is missing</h3><pre><code class="language-yaml">apiVersion: v1<br/>kind: Pod<br/>metadata:<br/>  name: unlabeled-pod<br/>spec:<br/>  containers:<br/>    - name: app<br/>      image: myapp:1.4.2<br/></code></pre><pre><code class="language-sh">kubectl apply -f unlabeled-pod.yaml<br/></code></pre><pre><code class="language-sh">Error from server: error when creating "unlabeled-pod.yaml": admission webhook "validate.kyverno.svc-fail" denied the request:</p><p>resource Pod/default/unlabeled-pod was blocked due to the following policies</p><p>require-labels:<br/>  check-for-labels: 'The label ''app.kubernetes.io/name'' is required.<br/>    Validation rule check-for-labels failed at path /metadata/labels/'<br/></code></pre><p>Add the label and the same pod is accepted right away.</p><pre><code class="language-yaml">apiVersion: v1<br/>kind: Pod<br/>metadata:<br/>  name: labeled-pod<br/>  labels:<br/>    app.kubernetes.io/name: myapp<br/>spec:<br/>  containers:<br/>    - name: app<br/>      image: myapp:1.4.2<br/></code></pre><pre><code class="language-sh">kubectl apply -f labeled-pod.yaml<br/><h1>pod/labeled-pod created</h1><br/></code></pre><h2>4. Restrict Privileged Containers</h2><p>A privileged container can do almost anything the host machine can do, including accessing other containers and system resources it should never touch. This is one of the biggest security risks in Kubernetes, and it is usually not something you want to allow unless there is a very specific reason for it.</p><p>This policy blocks any pod from running in privileged mode. It is also one of the checks covered by the <a href="https://kubernetes.io/docs/concepts/security/pod-security-standards/">Kubernetes Pod Security Standards</a>, which Kyverno has its own dedicated guide for if you want to enforce the whole standard at once instead of writing individual rules.</p><pre><code class="language-yaml">apiVersion: kyverno.io/v1<br/>kind: ClusterPolicy<br/>metadata:<br/>  name: disallow-privileged-containers<br/>spec:<br/>  background: true<br/>  rules:<br/>    - name: privileged-containers<br/>      match:<br/>        any:<br/>          - resources:<br/>              kinds:<br/>                - Pod<br/>      validate:<br/>        failureAction: Enforce<br/>        message: "Privileged mode is not allowed."<br/>        pattern:<br/>          spec:<br/>            containers:<br/>              - =(securityContext):<br/>                  =(privileged): "false"<br/></code></pre><p>This is one of the simplest changes you can make that meaningfully reduces your attack surface.</p><h3>Demo: what happens if a pod asks for privileged mode</h3><pre><code class="language-yaml">apiVersion: v1<br/>kind: Pod<br/>metadata:<br/>  name: privileged-pod<br/>spec:<br/>  containers:<br/>    - name: app<br/>      image: myapp:1.4.2<br/>      securityContext:<br/>        privileged: true<br/></code></pre><pre><code class="language-sh">kubectl apply -f privileged-pod.yaml<br/></code></pre><pre><code class="language-sh">Error from server: error when creating "privileged-pod.yaml": admission webhook "validate.kyverno.svc-fail" denied the request:</p><p>resource Pod/default/privileged-pod was blocked due to the following policies</p><p>disallow-privileged-containers:<br/>  privileged-containers: 'Privileged mode is not allowed.<br/>    Validation rule privileged-containers failed at path /spec/containers/0/securityContext/privileged/'<br/></code></pre><p>Remove the privileged flag, and the pod is created normally.</p><pre><code class="language-yaml">apiVersion: v1<br/>kind: Pod<br/>metadata:<br/>  name: safe-pod<br/>spec:<br/>  containers:<br/>    - name: app<br/>      image: myapp:1.4.2<br/></code></pre><pre><code class="language-sh">kubectl apply -f safe-pod.yaml<br/><h1>pod/safe-pod created</h1><br/></code></pre><h2>5. Verify Container Image Signatures</h2><p>This last one is a step up in complexity, but it is worth learning because it solves a real problem, how do you know the image running in your cluster is actually the one your team built, and not something tampered with along the way?</p><p>This is where image signing comes in. Tools like <a href="https://github.com/sigstore/cosign">Cosign</a>, part of the Sigstore project, let you cryptographically sign container images when you build them. Kyverno can then check that signature before allowing the image to run, and reject anything that is not signed or does not match. The full details of this feature are in the <a href="https://kyverno.io/docs/policy-types/cluster-policy/verify-images/sigstore/">Kyverno Sigstore verification docs</a>.</p><pre><code class="language-yaml">apiVersion: kyverno.io/v1<br/>kind: ClusterPolicy<br/>metadata:<br/>  name: check-image-signature<br/>spec:<br/>  background: false<br/>  rules:<br/>    - name: check-signature<br/>      match:<br/>        any:<br/>          - resources:<br/>              kinds:<br/>                - Pod<br/>      verifyImages:<br/>        - imageReferences:<br/>            - "ghcr.io/yourorg/*"<br/>          failureAction: Enforce<br/>          attestors:<br/>            - entries:<br/>                - keys:<br/>                    publicKeys: |-<br/>                      -----BEGIN PUBLIC KEY-----<br/>                      <your public key here><br/>                      -----END PUBLIC KEY-----<br/></code></pre><p>This is the same idea behind supply chain security, which has become a major topic in the industry after several high profile attacks where malicious code got smuggled into trusted software. Signing and verifying images is one of the clearest ways to close that gap, and it is a great skill to have even if you are still early in your Kubernetes journey.</p><h3>Demo: what happens with an unsigned image</h3><p>First, you would sign your image once, when you build it.</p><pre><code class="language-sh">cosign sign --key cosign.key ghcr.io/yourorg/myapp:1.4.2<br/></code></pre><p>Now if someone tries to deploy an image that was never signed, Kyverno stops it. Note that image verification is handled through Kyverno's mutating webhook, so the error will mention "mutate" rather than "validate" even though the outcome is a rejection.</p><pre><code class="language-yaml">apiVersion: v1<br/>kind: Pod<br/>metadata:<br/>  name: unsigned-image-pod<br/>spec:<br/>  containers:<br/>    - name: app<br/>      image: ghcr.io/yourorg/myapp:1.0.0<br/></code></pre><pre><code class="language-sh">kubectl apply -f unsigned-image-pod.yaml<br/></code></pre><pre><code class="language-sh">Error from server: admission webhook "mutate.kyverno.svc" denied the request:</p><p>resource Pod/default/unsigned-image-pod was blocked due to the following policies</p><p>check-image-signature:<br/>  check-signature: 'image verification failed for ghcr.io/yourorg/myapp:1.0.0:<br/>    signature not found'<br/></code></pre><p>Deploy the signed version instead, and it goes through.</p><pre><code class="language-yaml">apiVersion: v1<br/>kind: Pod<br/>metadata:<br/>  name: signed-image-pod<br/>spec:<br/>  containers:<br/>    - name: app<br/>      image: ghcr.io/yourorg/myapp:1.4.2<br/></code></pre><pre><code class="language-sh">kubectl apply -f signed-image-pod.yaml<br/><h1>pod/signed-image-pod created</h1><br/></code></pre><h2>Conclusion</h2><p>None of these policies are complicated on their own, but together they cover a lot of ground: resource limits, image tagging, labeling, privilege restrictions, and image signing. If you are new to Kyverno, a good approach is to start with the first two policies, get comfortable applying them with <code>kubectl apply -f policy.yaml</code>, watch how Kyverno reports violations, and then work your way down the list. You can try all of this without a real cluster using the Kyverno Playground.</p><p>Kyverno is actively evolving too. As of version 1.18, the <code>ClusterPolicy</code> style shown in this guide is marked deprecated in the docs in favor of newer CEL based policy types like <code>ValidatingPolicy</code>. It still works fully today and remains the easiest format for a beginner to learn, but once you are comfortable, it is worth reading the <a href="https://kyverno.io/docs/guides/migration-to-cel/">guide to migrating to CEL policies</a> to see where the project is headed.</p><p>If you want to go further, the official Kyverno documentation has a large library of sample policies you can copy and adapt for your own cluster, and the <a href="https://github.com/kyverno/kyverno">Kyverno GitHub repository</a> is where the project itself lives if you want to see what is being worked on next.</p><p>Thank you for reading! If you found this blog post helpful, please consider sharing it with others who might benefit. Feel free to check out my other blog posts and visit my socials!</p><p>- <a href="https://devarshi.dev">Profile</a><br/>- <a href="https://linkedin.com/in/devarshi-shimpi">Linkedin</a><br/>- <a href="https://twitter.com/devarshishimpi">Twitter</a><br/>- <a href="https://youtube.com/@devarshishimpi">Youtube</a></p><h3>Read more</h3><p>- <a href="https://devarshi.dev/blog/react-rsc-exploits-are-real-and-its-hurting-engineering-teams">React (RSC) Exploits Are Real and It's Hurting Engineering Teams</a><br/>- <a href="https://devarshi.dev/blog/managing-dependencies-and-security-with-npm">Managing Dependencies and Security in JavaScript with NPM</a><br/>- <a href="https://devarshi.dev/blog/deploy-minio-on-amazon-eks-self-host-s3-storage">Deploy MinIO on Amazon EKS: Self-Host S3 Storage</a><br/>]]></content:encoded>
      <link>https://devarshi.dev/blog/five-kyverno-policies-to-secure-kubernetes-cluster</link>
      <guid isPermaLink="true">https://devarshi.dev/blog/five-kyverno-policies-to-secure-kubernetes-cluster</guid>
      <pubDate>Tue, 07 Jul 2026 00:00:00 GMT</pubDate>
      <author>devarshishimpi@gmail.com (Devarshi Shimpi)</author>
      <enclosure url="https://static.devarshi.dev/blog/1600/5KyvernoPoliciesToSecureYourKubernetesCluster1600.png" type="image/png"/>
      <category>Technology</category>
      <category>Programming</category>
      <category>Development</category>
    </item>
    <item>
      <title><![CDATA[I Wanted AI Code Review I Could Actually Own. So I Built Codra.]]></title>
      <description><![CDATA[Codra is a private, free and open-source AI code review engine with bring-your-own models, infrastructure and limits.]]></description>
      <content:encoded><![CDATA[<p>I wanted AI code review I could actually own.</p><p>Not access through a subscription or a black-box service with its own limits. The deployment, credentials, providers, and usage under my control.</p><p>I kept hitting usage limits mid-week during deep building sessions. The models were capable. The workflow was useful. But access still depended on somebody else's weekly allowance, and centralized platforms can change whenever the company behind them decides to. Pricing, quotas, models, plan boundaries.</p><p>A workflow that fits this month may sit behind another subscription next month. I could not find a reliable open-source option that gave me the ownership model I wanted. So I built one.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-CodraSelfHostedAICodeReviewToolForDevelopers/codra-ai-code-review-dashboard.png">codra-ai-code-review-dashboard</a></p><p>That became <strong><a href="https://github.com/devarshishimpi/codra">Codra</a></strong>: A self-hosted AI review engine built around bring-your-own models, your own data boundary, and no Codra-imposed usage ceiling.</p><h2>What Codra Is</h2><p><strong><a href="https://github.com/devarshishimpi/codra">Codra</a></strong> is an open-source, self-hosted AI code review engine for GitHub pull requests.</p><p>It listens to pull request events, reviews changed files, posts inline findings, and provides a dashboard for jobs, repositories, model routing, history, usage, and failures.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-CodraSelfHostedAICodeReviewToolForDevelopers/codra-github-inline-pr-comment.png">codra-github-inline-pr-comment</a></p><p>It runs on Cloudflare Workers and uses:</p><p>- Cloudflare Queues for review jobs<br/>- PostgreSQL through Hyperdrive for storage<br/>- KV for sessions and cache<br/>- A React dashboard for operations</p><p>The GitHub App, model credentials, database, and review history are yours. Provider keys are encrypted with AES-GCM using your deployment secret.</p><h3>Bring Your Own Model, Bring Your Own Limits</h3><p>Changing providers does not require replacing your review history, configuration, or workflow.</p><p>You configure the provider and model. Supported:</p><p>- OpenAI-compatible APIs<br/>- OpenRouter<br/>- Anthropic<br/>- Google / Gemini<br/>- Cloudflare Workers AI</p><h3>Why Self-Hosted Matters Here</h3><p>A large frontend repo and a tiny backend repo should not need the same review strategy.</p><p>Each repository gets its own review settings. You tune triggers, skip generated files, ignore drafts, use mention-triggered reviews, configure labels, set file limits, and define custom rules.</p><h2>What Codra Actually Does</h2><p><strong><a href="https://codra.run">Codra</a></strong> is not just a prompt wrapped around a diff.</p><p>It includes the pieces needed to operate AI review as a system:</p><p>- Automatic and mention-triggered reviews<br/>- Inline comments, summaries, and check runs<br/>- Per-repository rules and skipped paths<br/>- Provider fallbacks and size-based model routing<br/>- Queue-backed, chunked processing with retries<br/>- Dead letter queue recovery<br/>- Job history, usage, repository, and model dashboards</p><p>The boring pieces are the point.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-CodraSelfHostedAICodeReviewToolForDevelopers/codra-dashboard-job-issues.png">codra-dashboard-job-issues</a></p><p>Production software is mostly unhappy paths: provider outages, malformed output, large diffs, stale jobs, superseded reviews, and failed queue runs.</p><p>Codra exists because those details matter.</p><h2>Open Source Is Part of the Product</h2><p>Codra is AGPL-licensed because "own your AI review loop" only means something when the system is inspectable.</p><p>Developers can inspect how jobs, diffs, prompts, fallbacks, comments, failures, and repository settings work. AI code review is still early, and those questions are better answered in the open:</p><p>AI code review is still early. There are open questions everywhere:</p><p>- Which models work best for different kinds of PRs?<br/>- How strict should automated review be?<br/>- How should local models and repository context fit in?<br/>- How do we reduce noise without missing real bugs?</p><p>Those questions are better answered in the open.</p><p>Codra should improve through real codebases and community contributions to prompts, providers, docs, tests, and defaults.</p><h2>What Comes Next</h2><p>Still in beta, but the foundation is there. The next phase has three tracks.</p><p>The next phase has three main tracks.</p><h3>Deployment Targets</h3><p>Cloudflare Workers stays the primary target. These paths are for teams and<br/>individuals who want to run Codra on infrastructure they already control.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-CodraSelfHostedAICodeReviewToolForDevelopers/discord-other-hosting-support-cloudflare-issue.png">discord-other-hosting-support-cloudflare-issue</a></p><p>- Vercel Functions adapter and other serverless runtime support<br/>- Conventional server deployment via Node.js and PM2 for EC2 or any VM<br/>- A Docker-first deployment path for platforms like Hetzner, DigitalOcean, and Coolify</p><h3>Stability and Developer Experience</h3><p>The review pipeline works. The focus now is making it hold up under real-world load<br/>and easier to get running without friction.</p><p>- A more robust pipeline that handles large PRs reliably<br/>- Cleaner installation, configuration, and debugging flows for first-time deployers<br/>- Community-driven defaults and real-world review config examples</p><h3>Provider and Model Support</h3><p>Inference should not be locked to hosted APIs. Local and self-hosted models will<br/>become a first-class option alongside the existing provider list.</p><p>- Improved support across existing providers<br/>- Routes for local and self-hosted models, Ollama, LM Studio, and similar<br/>- More language-aware review behavior per file type</p><h2>Own the Review Loop</h2><p>Providers, pricing, and quotas will keep changing. Your review engine should not have to change with them.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-CodraSelfHostedAICodeReviewToolForDevelopers/codra-cta-banner.png">codra-cta-banner</a></p><p><strong><a href="https://github.com/devarshishimpi/codra">Codra is open source on GitHub</a></strong>. Try it, star it, break it, file issues, and help shape where it goes next.</p><p><strong>Docs:</strong> <a href="https://codra.run/docs">https://codra.run/docs</a></p><h3>Read more</h3><p>- <a href="https://devarshi.dev/blog/codra-self-hosted-ai-code-review">I Wanted AI Code Review I Could Actually Own. So I Built Codra.</a><br/>- <a href="https://devarshi.dev/blog/self-hosting-your-own-cloud-storage-on-aws-using-nextcloud">Self-Hosting Your Own Cloud Storage on AWS using NextCloud</a><br/>- <a href="https://devarshi.dev/blog/how-to-create-a-new-nextjs-project-with-cf-workers-and-pages">How to create a new Next.js project with Cloudflare Pages and Workers</a><br/>]]></content:encoded>
      <link>https://devarshi.dev/blog/codra-self-hosted-ai-code-review</link>
      <guid isPermaLink="true">https://devarshi.dev/blog/codra-self-hosted-ai-code-review</guid>
      <pubDate>Wed, 24 Jun 2026 00:00:00 GMT</pubDate>
      <author>devarshishimpi@gmail.com (Devarshi Shimpi)</author>
      <enclosure url="https://static.devarshi.dev/blog/1600/CodraSelfHostedAICodeReviewToolForDevelopers1600.png" type="image/png"/>
      <category>Technology</category>
      <category>Programming</category>
      <category>Development</category>
    </item>
    <item>
      <title><![CDATA[Voice Search in Chrome Extensions Is Harder Than It Looks]]></title>
      <description><![CDATA[From Hono WebSocket bugs to broken AudioWorklet in MV3, here's everything that went wrong building voice search for my Chrome extension.]]></description>
      <content:encoded><![CDATA[<p>I thought this was just an hour of work. It wasn't. Here's everything that went wrong and what actually worked in the end.</p><h2>Starting with the obvious choice</h2><p><code>window.SpeechRecognition</code> is built into Chrome. No API keys, no server, completely free. It felt like the perfect starting point for adding voice search to my extension.<br/>After a day of testing, I dropped it.<br/>The mic permission popup was all over the place. Sometimes it would show up randomly mid-session. Sometimes it would just stop listening with no error, no warning, nothing. Results were different depending on the machine and OS. For a new tab extension that's meant to feel polished, that just wasn't good enough.<br/>I switched to <strong>Deepgram's Nova-3</strong> model. It's fast, accurate, and sends results back in real time over WebSocket, so you don't have to wait for a full sentence before seeing any output.<br/>But now I needed a server, which kicked off a whole chain of problems.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-VoiceSearchInChromeExtensionsIsHarderThanItLooks/old-flow-browser-rec.png">old-flow-browser-rec</a></p><h2>Why you can't call Deepgram directly from the extension</h2><p>Chrome extensions are easy to unpack and read. Any secret you put in the code is basically public. So keeping a Deepgram API key in the client was never going to work.<br/>I needed a server in the middle. My first thought was Railway. I've used it before and getting a Node server running there takes maybe five minutes. But I second guessed that pretty quickly. A server on Railway means it has to start up cold sometimes, it costs money every month, and the speed depends on where the server is located. Cloudflare Workers runs closer to the user since it runs at the edge, and the free plan is generous enough that a voice search API would run for free forever. Easy choice.<br/>The setup I had in mind: the extension sends raw audio to the Worker, the Worker passes it to Deepgram, and the text comes back the same way.</p><p>Simple enough on paper. Actually building it was another story.</p><h3>Hono looked like the right tool. It wasn't.</h3><p>I use Hono for pretty much everything on Cloudflare Workers. Clean, fast, easy routing. So I reached for it without thinking twice.<br/>Set up a <code>/transcribe</code> route, handled the WebSocket upgrade, deployed it. The Worker just froze. No error from my code, just Cloudflare eventually killing the request with a 500 and a message saying the Worker "would never generate a response."<br/>Took me a while to figure out what was going on. Cloudflare needs a special <code>webSocket</code> property on the <code>Response</code> object to finish a WebSocket connection. That's how it knows which socket to hand back to the client.<br/>Hono wraps the built-in <code>Response</code> to add its own features. Somewhere in that process, the <code>webSocket</code> property gets lost. Cloudflare gets a response with no socket, doesn't know what to do, and kills the request.<br/>The fix was to skip Hono for this route and just write it raw:</p><pre><code class="language-typescript">export default {<br/>  async fetch(request, env) {<br/>    if (url.pathname === "/transcribe") {<br/>      const pair = new WebSocketPair();<br/>      const [client, server] = pair;<br/>      server.accept();<br/>      return new Response(null, { status: 101, webSocket: client });<br/>    }<br/>  },<br/>};<br/></code></pre><p>101 Switching Protocols. Finally.</p><h3>The timing bug I should've seen coming</h3><p>Audio was flowing but the Worker kept logging <code>Deepgram not ready</code>. Pretty obvious in hindsight.<br/>The moment the client gets a 101 back, it starts sending audio right away. But the Worker had only just started its own connection to Deepgram. That connection wasn't open yet. So audio was showing up before Deepgram was ready to take it.<br/>My first fix was to wait for the Deepgram connection to open before sending the 101 back:</p><pre><code class="language-typescript">await new Promise((resolve) => {<br/>  deepgramSocket.onopen = resolve;<br/>});<br/>return new Response(null, { status: 101, webSocket: client });<br/></code></pre><p>This worked. But it quietly created a new problem I didn't notice until later.</p><h3>Cloudflare's 10ms CPU limit is real</h3><p>The free plan on Cloudflare Workers gives you 10ms of CPU time per request. Not total time, just active processing time. Waiting on a network call doesn't count, so in theory waiting for Deepgram to connect should be fine.<br/>In practice, keeping the request open through the whole connection process added enough overhead that CPU usage was sitting at 40 to 90ms. Cloudflare was going to start dropping requests.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-VoiceSearchInChromeExtensionsIsHarderThanItLooks/cf-workers-cpu-spike.png">cf-workers-cpu-spike</a></p><p>The fix was to stop waiting. Return the 101 right away, let Deepgram connect in the background, and just hold any audio that comes in too early:</p><pre><code class="language-typescript">let deepgramReady = false;<br/>const pendingChunks = [];</p><p>deepgramSocket.addEventListener("open", () => {<br/>  deepgramReady = true;<br/>  for (const chunk of pendingChunks) deepgramSocket.send(chunk);<br/>  pendingChunks.length = 0;<br/>});</p><p>server.addEventListener("message", (event) => {<br/>  if (!deepgramReady) {<br/>    pendingChunks.push(event.data);<br/>  } else {<br/>    deepgramSocket.send(event.data);<br/>  }<br/>});</p><p>return new Response(null, { status: 101, webSocket: client });<br/></code></pre><p>CPU usage dropped to around 2ms. Deepgram still connects, it just doesn't hold everything else up while it does.</p><h3>AudioWorklet and Manifest V3 don't work together</h3><p>This was the most painful part of the whole thing.<br/>MV3 extensions only let you run scripts that are part of your own extension package. No inline scripts, no scripts from other websites, nothing generated at runtime. <code>AudioWorkletNode</code> is the standard modern way to process audio in a background thread, and it needs you to load a separate file using <code>addModule(url)</code>. You can already see where this is going.</p><p><DevtoolsError /><p>First try was using Vite's <code>?url</code> import:</p><pre><code class="language-typescript">import processorUrl from "./processor.js?url";<br/>// Output: data:text/javascript;base64,...<br/></code></pre><p>Blocked. Makes sense, data URIs aren't allowed.<br/>Second try was putting the file in the <code>public/</code> folder and loading it with <code>chrome.runtime.getURL</code>:</p><pre><code class="language-typescript">const url = chrome.runtime.getURL("audio/pcm-processor.js");<br/>await ctx.audioWorklet.addModule(url);<br/></code></pre><p>This really should have worked. A <code>chrome-extension://</code> URL is from your own extension, so the policy should allow it. I was pretty sure this was the answer.<br/>It failed with <code>AbortError: Unable to load worklet module</code>. No extra info, no useful error message.<br/>After going through Chromium bug reports, turns out this is a known broken behaviour in how Chrome handles extension files in Worklet threads. There are open issues, no fix in sight.</p><h3>The old deprecated API that actually works</h3><p>I gave up on <code>AudioWorklet</code> and used <code>ScriptProcessorNode</code> instead. It's been marked as deprecated for years but it runs directly in the page using a callback, so there's no extra file to load and no policy issues. For converting Float32 audio to Int16, the performance hit is basically nothing.</p><pre><code class="language-typescript">const processor = audioCtx.createScriptProcessor(4096, 1, 1);<br/>processor.onaudioprocess = (e) => {<br/>  const input = e.inputBuffer.getChannelData(0);<br/>  const int16 = float32ToInt16(input);<br/>  ws.send(int16);<br/>};<br/></code></pre><p>Works every time without fail. The modern recommended way broke. The old way just works. That's extension development.</p><h2>A few smaller things worth knowing</h2><p>Cleaning up properly is harder than it sounds. Web Audio can leak memory if you don't clean up after yourself. When voice search stops, you need to close the WebSocket, disconnect the <code>ScriptProcessor</code>, stop all microphone tracks (this turns off the mic light in the browser toolbar), and close the <code>AudioContext</code>. Skip any one of these and you'll have audio processes running in the background that you can't see.<br/>Silence detection matters a lot. Without it, the mic just stays on forever. Every time Deepgram sends back a transcript or a <code>speech_started</code> event, reset a 2.5 second timer. When the timer runs out, stop listening. It makes the whole thing feel much less annoying to use.<br/>Add the Worker URL to <code>host_permissions</code> in your manifest. You need to allow <code>wss://your-worker.workers.dev/*</code> or the browser blocks the connection before it even gets to any policy check.</p><h2>What actually changed</h2><p>Before all of this, the extension was using <code>window.SpeechRecognition</code> with around 500ms before it even started listening, results that changed between machines, and random failures. After the rewrite, it connects in around 100ms, the Worker uses 1 to 3ms of CPU per request, and it works the same way every time.<br/>Every single problem in this build came from the same place: the standard tools weren't built for this environment. Hono breaks WebSockets on Cloudflare. <code>AudioWorklet</code> breaks in MV3 extensions. Once you understand why something fails, the fix is usually obvious. The hard part is getting there.</p><h2>Happy Coding!!!</h2><p>Thank you for reading! If you found this blog post helpful, please consider sharing it with others who might benefit. Feel free to check out my other blog posts and visit my socials!</p><p>- <a href="https://devarshi.dev">Profile</a><br/>- <a href="https://linkedin.com/in/devarshi-shimpi">Linkedin</a><br/>- <a href="https://twitter.com/devarshishimpi">Twitter</a><br/>- <a href="https://youtube.com/@devarshishimpi">Youtube</a><br/>- <a href="https://devarshishimpi.hashnode.dev">Hashnode</a><br/>- <a href="https://dev.to/devarshishimpi">DEV</a></p><h3>Read more</h3><p>- <a href="https://devarshi.dev/blog/self-hosting-your-own-cloud-storage-on-aws-using-nextcloud">Self-Hosting Your Own Cloud Storage on AWS using NextCloud</a><br/>- <a href="https://devarshi.dev/blog/creating-your-first-droplet-digitalocean-tutorials">Creating Your First Droplet - DigitalOcean Tutorials</a><br/>- <a href="https://devarshi.dev/blog/complete-markdown-tutorial-for-beginners">Complete Markdown Tutorial for Beginners</a><br/>]]></content:encoded>
      <link>https://devarshi.dev/blog/voice-search-in-chrome-extensions</link>
      <guid isPermaLink="true">https://devarshi.dev/blog/voice-search-in-chrome-extensions</guid>
      <pubDate>Mon, 16 Mar 2026 00:00:00 GMT</pubDate>
      <author>devarshishimpi@gmail.com (Devarshi Shimpi)</author>
      <enclosure url="https://static.devarshi.dev/blog/1600/VoiceSearchInChromeExtensionsIsHarderThanItLooks1600.png" type="image/png"/>
      <category>Technology</category>
      <category>Programming</category>
      <category>Development</category>
    </item>
    <item>
      <title><![CDATA[React (RSC) Exploits Are Real and It's Hurting Engineering Teams]]></title>
      <description><![CDATA[Deep dive into React RCE (CVE-2025-55182) & Next.js risks. Covers RSC Flight exploits, patch fatigue, and securing server actions from DoS & leaks.]]></description>
      <content:encoded><![CDATA[<p>If you work in web engineering, the transition into 2026 hasn’t been defined by new features, but by a single, terrifying realization: <strong>The boundary between your client and server is broken.</strong></p><p>In December, "React2Shell" (<a href="https://react.dev/blog/2025/12/03/critical-security-vulnerability-in-react-server-components">CVE-2025-55182</a>) exposed a critical RCE in React Server Components. Barely after teams patched, two more high-severity exploits emerged in the same subsystem. This is the definitive technical post-mortem.</p><h2>The "React2Shell" RCE (CVE-2025-55182)</h2><p>To understand why this vulnerability (CVSS 10.0) was so devastating, we first have to understand the machinery it destroyed, the <strong>React Flight Protocol</strong>.</p><p>For years, the mental model for React developers was simple: React renders UI in the browser, and an API (REST/GraphQL) fetches data. The server and client were distinct worlds, separated by a clear network boundary.</p><p>React Server Components (RSC) erased that boundary.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-ReactRSCExploitsAreRealAndItsHurtingEngineeringTeams/react-flight-protocol.png">react-flight-protocol</a></p><p>In the RSC world, the server doesn't send HTML to the client. It streams a proprietary serialization format called "Flight." This stream contains descriptions of UI components, serialized data, and crucially <strong>Promises</strong> that resolve to data.</p><h3>How React2Shell Works</h3><p><a href="https://react.dev/blog/2025/12/03/critical-security-vulnerability-in-react-server-components">React2Shell</a> was not standard SQL injection or XSS. It was logic abuse targeting a deserializer. Attackers crafted HTTP POST requests with specific "Flight" payloads. These binary-like streams mimicked valid component trees while hiding a "Thenable" Object, or fake Promise.</p><p>1. <strong>Injection:</strong> Attacker sends serialized object containing malicious <code>__proto__</code> keys.<br/>2. <strong>Deserialization:</strong> Server parses stream and tries resolving fake Promise.<br/>3. <strong>Prototype Pollution:</strong> Lack of sanitization lets <code>__proto__</code> overwrite <code>Object.prototype</code> on running Node.js process.<br/>4. <strong>Gadget Chain:</strong> Modified prototype triggers internal calls targeting <code>Function</code> constructor.</p><p>Accessing <code>Function</code> constructor means game over. Arbitrary strings like <code>require('child_process').exec(...)</code> compile and execute immediately.</p><h3>How Next.js was Affected</h3><p>Because <a href="https://nextjs.org/blog/CVE-2025-66478">Next.js App Router</a> enables RSC by default, <strong>every</strong> Next.js application (versions 15.x, 16.x, and canary builds) was vulnerable out of the box. You didn't need to write a buggy Server Action to be hacked. You didn't even need to use Server Components explicitly. If your application booted up <code>react-server-dom-webpack</code>, it was listening for these Flight payloads.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-ReactRSCExploitsAreRealAndItsHurtingEngineeringTeams/client-server-components.png">client-server-components</a></p><p>_Credits: Next.js for the image_</p><h3>The DevOps Nightmare</h3><p>For DevOps engineers, "React2Shell" was a worst-case scenario.</p><p>- <strong>WAF Blindness:</strong> Standard Web Application Firewalls (WAFs) are trained to look for SQL injection (<code>' OR 1=1</code>) or script tags (<code><script></code>). They were _not_ trained to inspect the proprietary text format of React Flight. The malicious payloads passed right through Cloudflare and AWS WAF rules initially.<br/>- <strong>Supply Chain Hell:</strong> The vulnerability wasn't in user code; it was deep in <code>node_modules</code>. You couldn't just "fix the code." You had to wait for Vercel and the React team to release patched binaries, then rebuild and redeploy every single microservice.</p><h2>The Aftershocks (DoS and Leaks)</h2><p>Just as engineering teams were recovering from the RCE panic, the security community found more cracks in the foundation. On December 11, 2025, the <a href="https://react.dev/blog/2025/12/11/denial-of-service-and-source-code-exposure-in-react-server-components">React team issued a new advisory</a> for <strong>three</strong> additional CVEs.</p><p>While these aren't RCEs, they are operationally devastating and highlight the fragility of the current serialization implementation.</p><h3>1. Denial of Service (CVE-2025-55184)</h3><p><strong>Severity: High (7.5/10)</strong></p><p>This vulnerability allows attackers to "freeze" infrastructure with a single request.</p><p><strong>Mechanism:</strong><br/>Flight protocol allows data chunks to reference other chunks. Researchers discovered they could create <strong>circular dependencies</strong> in payloads.</p><p>- Chunk A references Chunk B.<br/>- Chunk B references Chunk A.</p><p>When the React deserializer attempts to resolve this structure, it enters an <strong>infinite synchronous loop</strong>.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-ReactRSCExploitsAreRealAndItsHurtingEngineeringTeams/nodejs-server-event-loop.png">nodejs-server-event-loop</a></p><p><strong>The Impact on Infrastructure:</strong><br/>Because Node.js is single-threaded, this infinite loop blocks the entire Event Loop.</p><p>1. <strong>CPU Spike:</strong> The CPU immediately jumps to 100%.<br/>2. <strong>Request Drops:</strong> The server stops responding to _all_ other users. Health checks fail.<br/>3. <strong>Cluster Destabilization:</strong> In Kubernetes, the liveness probe might fail, causing the pod to restart. But if the attacker sends a stream of these requests, they can put the entire cluster into a "CrashLoopBackOff" state, effectively taking down the application.</p><p>_Note: The initial fix for this was incomplete, leading to CVE-2025-67779 (the "fix for the fix"), which forced DevOps teams to patch their systems a third time in two weeks._</p><h3>2. Source Code Leak (CVE-2025-55183)</h3><p><strong>Severity: Medium (5.3/10)</strong></p><p>Arguably most embarrassing vulnerability for React ecosystem. It allows attackers to trick servers into sending source code back to clients.</p><p><strong>Mechanism:</strong><br/>Exploit relies on JavaScript string coercion. If Server Action returns object implicitly calling <code>.toString()</code> on a function within server runtime, default V8 behavior returns function <strong>source code</strong>.</p><p><strong>"Secrets" Risk:</strong><br/>Developers often assume code inside <code>use server</code> files is private. They might write:</p><pre><code class="language-javascript">// DO NOT DO THIS<br/>const STRIPE_KEY = "sk_live_12345";<br/>export async function purchase() { ... }</p><p></code></pre><p>Under normal circumstances, <code>STRIPE_KEY</code> stays on the server. But with CVE-2025-55183, an attacker can manipulate the serialization of the return value to dump the scope of the function, potentially revealing hardcoded API keys, internal comments, and database schema details.</p><h3>Immediate Action Plan</h3><p>If you are running <strong>Next.js App Router (v13.3+)</strong> or <strong>React 19</strong>, you must execute the following plan immediately:</p><p>1. <strong>The "Immediate" Update:</strong><br/>   Do not trust semantic versioning ranges. Pin your versions to the releases that explicitly fix _all_ discussed CVEs.</p><pre><code class="language-bash">npm install react@19.0.2 react-dom@19.0.2 next@15.1.3<br/><h1>Verify deeply nested dependencies</h1><br/>npm list react-server-dom-webpack</p><p></code></pre><p>_Ensure <code>react-server-dom-webpack</code> is at least version 19.0.2._</p><p>2. <strong>Implement Rate Limiting:</strong><br/>   The DoS exploit is cheap for attackers. You must implement aggressive rate limiting on all routes, especially <code>POST</code> requests, at the infrastructure level (Nginx, Cloudflare, AWS WAF).</p><p>3. <strong>Audit for Secrets:</strong><br/>   Assume your server code _can_ be leaked. Run a scan of your <code>app/</code> directory. If you find a single API key, hardcoded password, or internal IP address in a <code>.ts</code> or <code>.js</code> file, move it to an environment variable immediately.</p><h2>Conclusion</h2><p>React Server Components are a powerful evolution of the web, but "React2Shell" has proven that this power comes with a terrifying new attack surface. The Flight protocol is complex, and as we have seen, complexity is the enemy of security.</p><p>Thank you for reading! If you found this blog post helpful, please consider sharing it with others who might benefit. Feel free to check out my other blog posts and visit my socials!</p><p>- <a href="https://devarshi.dev">Profile</a><br/>- <a href="https://linkedin.com/in/devarshi-shimpi">Linkedin</a><br/>- <a href="https://twitter.com/devarshishimpi">Twitter</a><br/>- <a href="https://youtube.com/@devarshishimpi">Youtube</a></p><h3>Read more</h3><p>- <a href="https://devarshi.dev/blog/managing-dependencies-and-security-with-npm">Managing Dependencies and Security in JavaScript with NPM</a><br/>- <a href="https://devarshi.dev/blog/google-ends-its-url-shortener-and-breaks-urls">The End of Google URL Shortener and breaks 4.6 BILLION URLs!</a><br/>- <a href="https://devarshi.dev/blog/managing-metadata-in-nextjs-for-seo">Managing Metadata in Next.js for Enhanced SEO and User Experience</a><br/>]]></content:encoded>
      <link>https://devarshi.dev/blog/react-rsc-exploits-are-real-and-its-hurting-engineering-teams</link>
      <guid isPermaLink="true">https://devarshi.dev/blog/react-rsc-exploits-are-real-and-its-hurting-engineering-teams</guid>
      <pubDate>Thu, 08 Jan 2026 00:00:00 GMT</pubDate>
      <author>devarshishimpi@gmail.com (Devarshi Shimpi)</author>
      <enclosure url="https://static.devarshi.dev/blog/1600/ReactRSCExploitsAreRealAndItsHurtingEngineeringTeams1600.png" type="image/png"/>
      <category>Technology</category>
      <category>Programming</category>
      <category>Development</category>
    </item>
    <item>
      <title><![CDATA[Managing Metadata in Next.js for Enhanced SEO and User Experience]]></title>
      <description><![CDATA[In Next.js, there are two primary ways to manage metadata for your application: using a static metadata object or a dynamic generateMetadata function.]]></description>
      <content:encoded><![CDATA[<h2>Introduction</h2><p>In Next.js, there are two primary ways to manage metadata for your application: using a static <code>metadata</code> object or a dynamic <code>generateMetadata</code> function. Below is a detailed guide on how to utilize both options effectively.</p><p>This guide provides an in-depth look at both approaches, helping you understand how to effectively implement metadata in your Next.js application.</p><h2>Next.js Demo with Metadata Output</h2><p>In this live example, we'll create a simple Next.js application showcasing the usage of metadata. Then, we'll view the rendered output in the browser and visualise the metadata in action.</p><p>We start by creating a new Next.js project with <code>create-next-app</code></p><pre><code class="language-bash">npx create-next-app@latest<br/></code></pre><p>Here's the options I chose while creating it.</p><pre><code class="language-bash">✔ What is your project named? … my-next-app<br/>✔ Would you like to use TypeScript? … Yes<br/>✔ Would you like to use ESLint? … Yes<br/>✔ Would you like to use Tailwind CSS? … No<br/>✔ Would you like your code inside a <code>src/</code> directory? … No<br/>✔ Would you like to use App Router? (recommended) … Yes<br/>✔ Would you like to use Turbopack for <code>next dev</code>? … No<br/>✔ Would you like to customize the import alias (@/* by default)? … No<br/></code></pre><p>Add this sample code in the following block and let's preview it in the browser.</p><p><strong>Code:</strong></p><pre><code class="language-typescript">import { Metadata } from "next";</p><p>export const metadata: Metadata = {<br/>  title: "My Next.js App",<br/>  description: "A demo application showcasing Next.js metadata.",<br/>  openGraph: {<br/>    title: "My Next.js App",<br/>    description: "A demo application showcasing Next.js metadata.",<br/>    url: "https://example.com",<br/>    siteName: "My App",<br/>    images: [<br/>      {<br/>        url: "https://example.com/og-image.png",<br/>        width: 1200,<br/>        height: 630,<br/>      },<br/>    ],<br/>    locale: "en_US",<br/>    type: "website",<br/>  },<br/>  twitter: {<br/>    card: "summary_large_image",<br/>    title: "My Next.js App",<br/>    description: "A demo application showcasing Next.js metadata.",<br/>    images: ["https://example.com/og-image.png"],<br/>  },<br/>};</p><p>export default function Page() {<br/>  return <main><h1>Hello, World!</h1></main>;<br/>}<br/></code></pre><p><strong>Output:</strong></p><p>And here's the browser output with get with the tags, keep reading the entire article to see how you could implement in your code.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-ManagingMetadataInNextJsForteenForSEO/nextjs-metadata-output.png">nextjs-metadata-output</a></p><h3>Static Metadata</h3><p>To define static metadata, you export a <code>Metadata</code> object from a <code>layout.ts</code> or <code>page.ts</code> file using the App Router.</p><p>Example:</p><pre><code class="language-typescript">import { Metadata } from "next";</p><p>export const metadata: Metadata = {<br/>  title: "Static Page Title",<br/>  description: "This is a static page description",<br/>};</p><p>export default function Page() {}<br/></code></pre><p>This method is suitable when the metadata does not depend on runtime information.</p><h3>Dynamic Metadata</h3><p>Dynamic metadata allows you to generate metadata based on dynamic data, such as route parameters or fetched data.</p><p>Example:</p><pre><code class="language-typescript">import { Metadata, ResolvingMetadata } from "next";</p><p>type Props = {<br/>  params: { id: string };<br/>  searchParams: { [key: string]: string | string[] | undefined };<br/>};</p><p>export async function generateMetadata(<br/>  { params, searchParams }: Props,<br/>  parent: ResolvingMetadata,<br/>): Promise<Metadata> {<br/>  const id = params.id;<br/>  const product = await fetch(<code>https://api.example.com/products/${id}</code>).then(<br/>    (res) => res.json(),<br/>  );</p><p>  const previousImages = (await parent).openGraph?.images || [];</p><p>  return {<br/>    title: product.name,<br/>    description: product.description,<br/>    openGraph: {<br/>      images: [product.imageUrl, ...previousImages],<br/>    },<br/>  };<br/>}</p><p>export default function Page({ params, searchParams }: Props) {}<br/></code></pre><p>This method is useful when the metadata depends on dynamic data or needs to extend parent metadata.</p><h3>Key Points</h3><p>- <strong>Server Components Only</strong>: Both <code>metadata</code> and <code>generateMetadata</code> are only supported in Server Components.<br/>- <strong>Single Export Rule</strong>: You cannot export both the <code>metadata</code> object and <code>generateMetadata</code> function from the same route segment.</p><h3>Metadata Fields</h3><p>Next.js provides a variety of metadata fields to customize the metadata of your application comprehensively.</p><p>#### Title</p><p>- <strong>String</strong></p><p>  <pre><code class="language-typescript">  export const metadata: Metadata = {<br/>    title: "Next.js Application",<br/>  };<br/>  </code></pre><p>  Output: <code><title>Next.js Application</title></code></p><p>- <strong>Template Object</strong></p><p>  <pre><code class="language-typescript">  export const metadata: Metadata = {<br/>    title: {<br/>      template: "%s | Next.js",<br/>      default: "Next.js",<br/>    },<br/>  };<br/>  </code></pre><p>  Output in child routes: <code><title>About | Next.js</title></code></p><p>- <strong>Absolute</strong><br/>  <pre><code class="language-typescript">  export const metadata: Metadata = {<br/>    title: {<br/>      absolute: "About Us",<br/>    },<br/>  };<br/>  </code></pre><br/>  Output: <code><title>About Us</title></code></p><p>#### Description</p><pre><code class="language-typescript">export const metadata: Metadata = {<br/>  description: "The React Framework for the Web",<br/>};<br/></code></pre><p>Output: <code><meta name="description" content="The React Framework for the Web" /></code></p><p>#### Basic Fields</p><pre><code class="language-typescript">export const metadata: Metadata = {<br/>  generator: "Next.js",<br/>  applicationName: "Next.js App",<br/>  keywords: ["Next.js", "React", "JavaScript"],<br/>  authors: [{ name: "Author Name", url: "https://example.com" }],<br/>};<br/></code></pre><p>Output:</p><pre><code class="language-html"><meta name="generator" content="Next.js" /><br/><meta name="application-name" content="Next.js App" /><br/><meta name="keywords" content="Next.js,React,JavaScript" /><br/><meta name="author" content="Author Name" /><br/><link rel="author" href="https://example.com" /><br/></code></pre><p>#### Open Graph</p><pre><code class="language-typescript">export const metadata: Metadata = {<br/>  openGraph: {<br/>    title: "Next.js",<br/>    description: "The React Framework for the Web",<br/>    url: "https://nextjs.org",<br/>    siteName: "Next.js",<br/>    images: [<br/>      {<br/>        url: "https://nextjs.org/og.png",<br/>        width: 800,<br/>        height: 600,<br/>      },<br/>    ],<br/>    locale: "en_US",<br/>    type: "website",<br/>  },<br/>};<br/></code></pre><p>Output:</p><pre><code class="language-html"><meta property="og:title" content="Next.js" /><br/><meta property="og:description" content="The React Framework for the Web" /><br/><meta property="og:url" content="https://nextjs.org/" /><br/><meta property="og:site_name" content="Next.js" /><br/><meta property="og:locale" content="en_US" /><br/><meta property="og:image" content="https://nextjs.org/og.png" /><br/><meta property="og:image:width" content="800" /><br/><meta property="og:image:height" content="600" /><br/></code></pre><p>#### Twitter</p><pre><code class="language-typescript">export const metadata: Metadata = {<br/>  twitter: {<br/>    card: "summary_large_image",<br/>    title: "Next.js",<br/>    description: "The React Framework for the Web",<br/>    images: ["https://nextjs.org/og.png"],<br/>  },<br/>};<br/></code></pre><p>Output:</p><pre><code class="language-html"><meta name="twitter:card" content="summary_large_image" /><br/><meta name="twitter:title" content="Next.js" /><br/><meta name="twitter:description" content="The React Framework for the Web" /><br/><meta name="twitter:image" content="https://nextjs.org/og.png" /><br/></code></pre><p>#### Robots</p><pre><code class="language-typescript">export const metadata: Metadata = {<br/>  robots: {<br/>    index: false,<br/>    follow: true,<br/>    googleBot: {<br/>      index: true,<br/>      follow: false,<br/>    },<br/>  },<br/>};<br/></code></pre><p>Output:</p><pre><code class="language-html"><meta name="robots" content="noindex, follow" /><br/><meta name="googlebot" content="index, nofollow" /><br/></code></pre><p>#### MetadataBase</p><p><code>metadataBase</code> allows setting a base URL prefix for metadata fields that require a fully qualified URL.</p><p>Example:</p><pre><code class="language-typescript">export const metadata: Metadata = {<br/>  metadataBase: new URL("https://example.com"),<br/>  openGraph: {<br/>    images: "/og-image.png",<br/>  },<br/>};<br/></code></pre><p>Output:</p><pre><code class="language-html"><meta property="og:image" content="https://example.com/og-image.png" /><br/></code></pre><h3>Best Practices</h3><p>- <strong>Use Static Metadata When Possible</strong>: If metadata doesn't depend on runtime information, prefer static metadata for simplicity.<br/>- <strong>Dynamic Metadata for Dynamic Data</strong>: Use <code>generateMetadata</code> for routes where metadata depends on dynamic data or needs to extend parent metadata.</p><p>- <strong>Combine Metadata Fields</strong>: Utilize a combination of different metadata fields to ensure comprehensive metadata coverage for SEO and social media integration.</p><p>- <strong>Utilize <code>metadataBase</code></strong>: Set a <code>metadataBase</code> in your root layout to simplify URL-based metadata field definitions.</p><h2>Conclusion</h2><p>By following these guidelines, you can effectively manage metadata in your Next.js application, enhancing both SEO and user experience.</p><p>Thank you for reading! If you found this blog post helpful, please consider sharing it with others who might benefit. Feel free to check out my other blog posts and visit my socials!</p><p>- <a href="https://devarshi.dev">Profile</a><br/>- <a href="https://linkedin.com/in/devarshi-shimpi">Linkedin</a><br/>- <a href="https://twitter.com/devarshishimpi">Twitter</a><br/>- <a href="https://youtube.com/@devarshishimpi">Youtube</a><br/>- <a href="https://devarshishimpi.hashnode.dev">Hashnode</a><br/>- <a href="https://dev.to/devarshishimpi">DEV</a></p><h3>Read more</h3><p>- <a href="https://devarshi.dev/blog/setting-up-an-ubuntu-ec2-instance-from-scratch-on-aws">Setting Up An Ubuntu EC2 Instance From Scratch on AWS</a><br/>- <a href="https://devarshi.dev/blog/what-are-docker-images-and-how-to-use-them">What Are Docker Images And How To Use Them</a><br/>- <a href="https://devarshi.dev/blog/easiest-way-to-install-wordpress-for-beginners">Easiest Way to Install WordPress Locally for Beginners</a><br/>]]></content:encoded>
      <link>https://devarshi.dev/blog/managing-metadata-in-nextjs-for-seo</link>
      <guid isPermaLink="true">https://devarshi.dev/blog/managing-metadata-in-nextjs-for-seo</guid>
      <pubDate>Wed, 24 Dec 2025 00:00:00 GMT</pubDate>
      <author>devarshishimpi@gmail.com (Devarshi Shimpi)</author>
      <enclosure url="https://static.devarshi.dev/blog/1600/ManagingMetadataInNextJsForteenForSEO1600.png" type="image/png"/>
      <category>Technology</category>
      <category>Programming</category>
      <category>Development</category>
    </item>
    <item>
      <title><![CDATA[Dynamic Styling with calc() in TailwindCSS]]></title>
      <description><![CDATA[Use calc() in TailwindCSS for responsive, dynamic styling. Explore practical examples for layouts, custom designs with its utility-first approach.]]></description>
      <content:encoded><![CDATA[<h2>Introduction</h2><p>TailwindCSS is fantastic, right? It lets us build beautiful, custom designs incredibly fast with its utility-first approach. We grab classes like <code>p-4</code>, <code>flex</code>, <code>w-1/2</code>, and _boom_ – things start taking shape. But sometimes... sometimes you hit a wall. You need a layout element to be _exactly_ 100% wide, _minus_ the fixed width of a sidebar. Or maybe you want padding that dynamically adjusts based on the viewport _plus_ a base value.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-DynamicStylingWithCalcInTailwindcss/tailwindcss-logo.png">tailwindcss-logo</a></p><p>In this deep dive, we'll explore how <code>calc()</code> works, why it's such a powerful partner for Tailwind, and how you can leverage it to build more sophisticated, responsive, and pixel-perfect interfaces without ever leaving your HTML (mostly!).</p><h2>First Things First: What Exactly _is_ <code>calc()</code>?</h2><p>Before we plug it into Tailwind, let's quickly refresh ourselves on what <code>calc()</code> actually does in plain old CSS. At its core, <code>calc()</code> is a native CSS function that lets you perform calculations right inside your property values. Think of it like a mini-calculator for your stylesheets.</p><p>It supports the basic arithmetic operations you'd expect:</p><p>- <strong>Addition (<code>+</code>)</strong>: <code>calc(2rem + 10px)</code><br/>- <strong>Subtraction (<code>-</code>)</strong>: <code>calc(100% - 50px)</code><br/>- <strong>Multiplication (<code><em></code>)</strong>: <code>calc(1.5 </em> 1rem)</code><br/>- <strong>Division (<code>/</code>)</strong>: <code>calc(100vw / 3)</code></p><p>!<a href="https://static.devarshi.dev/blog/HLS-DynamicStylingWithCalcInTailwindcss/width-calc-eg.png">width-calc-eg</a></p><p>This ability to blend relative and absolute units is something static values just can't replicate easily.</p><pre><code class="language-css">/<em> Full width minus a fixed sidebar </em>/<br/>.main-content {<br/>  width: calc(100% - 250px);<br/>}</p><p>/<em> Dynamic padding based on viewport height </em>/<br/>.hero-section {<br/>  padding-top: calc(5vh + 2rem);<br/>}<br/></code></pre><h2>Why Bring <code>calc()</code> into the Tailwind World?</h2><p>"Okay," you might be thinking, "Tailwind has spacing, sizing, fractions... why complicate things?"</p><p>That's a fair question! Tailwind covers a _huge_ range of common styling needs with its utilities. But <code>calc()</code> fills the gaps where:</p><p>1.  <strong>You Need Mixed Units:</strong> Tailwind's <code>w-1/2</code> is 50%, <code>w-64</code> is 16rem. But what about <code>calc(50% - 1rem)</code>? Tailwind doesn't have a pre-built utility for every possible mathematical combination.<br/>2.  <strong>You Need Precise Dynamic Relationships:</strong> Calculating an element's size based on the viewport _minus_ a fixed header/footer height is a prime use case.<br/>3.  <strong>You Want Fluidity Beyond Standard Fractions:</strong> Maybe a three-column layout needs precise gutters subtracted from fractional widths.<br/>4.  <strong>You're Dealing with External Constraints:</strong> Sometimes, an element's size needs to account for something outside its direct parent (like the viewport height).</p><h2>Using Arbitrary Values <code>[]</code> with <code>calc()</code></h2><p>The framework embraced the idea that sometimes, you just need to write a specific CSS value directly. This is done using square brackets <code>[]</code>. And guess what? You can put a <code>calc()</code> expression right inside!</p><p>The syntax looks like this:</p><pre><code class="language-html"><div class="property-[calc(expression)]">...</div><br/></code></pre><p>Let's see it in action:</p><p><strong>Creating a width that's full-width minus some padding:</strong></p><pre><code class="language-html"><div class="w-[calc(100%-2rem)] bg-blue-100 p-4"><br/>  My width adapts, always leaving 1rem of space on each side (total 2rem).<br/></div><br/></code></pre><p><strong>Setting a height relative to the viewport minus a header:</strong></p><pre><code class="language-html"><header class="h-16 bg-gray-800 text-white">...</header><br/><main class="h-[calc(100vh-4rem)] bg-gray-100 overflow-y-auto"><br/>  This content area fills the remaining vertical space perfectly.<br/></main><br/></code></pre><p><strong>Applying dynamic margins or padding:</strong></p><pre><code class="language-html"><div class="mt-[calc(2rem+5vh)] bg-green-100 p-3"><br/>  My top margin grows slightly as the viewport height increases.<br/></div><br/></code></pre><p>It's that straightforward! You use the Tailwind property prefix (<code>w-</code>, <code>h-</code>, <code>mt-</code>, <code>p-</code>, etc.) followed by your <code>calc()</code> expression wrapped in square brackets.</p><h2>Let's Get Practical: Real-World <code>calc()</code> Scenarios in Tailwind</h2><p>Theory is nice, but let's see where <code>calc()</code> truly shines in everyday development with Tailwind.</p><h3>Example 1: The Classic Sidebar + Content Layout</h3><p>This is a bread-and-butter layout. You have a fixed-width sidebar and want the main content area to take up the _rest_ of the available space.</p><pre><code class="language-html"><div class="flex min-h-screen"><br/>  <aside class="w-64 bg-gray-100 p-4 flex-shrink-0">Sidebar Content</aside></p><p>  <main class="w-[calc(100%-16rem)] bg-white p-6 flex-grow"><br/>    Main Application Content Here... It perfectly fills the space next to the<br/>    sidebar.<br/>  </main><br/></div><br/></code></pre><p>Here, <code>w-[calc(100%-16rem)]</code> explicitly tells the main content area to calculate its width based on the full container width minus the sidebar's known width. <code>flex-shrink-0</code> on the sidebar prevents it from shrinking if space gets tight, and <code>flex-grow</code> on main allows it to expand (though the <code>calc()</code> width often makes this redundant, it's good practice in flex layouts).</p><p>!<a href="https://static.devarshi.dev/blog/HLS-DynamicStylingWithCalcInTailwindcss/sidebar-content-layout.gif">sidebar-content-layout</a></p><h3>Example 2: Making Room for Fixed Headers/Footers</h3><p>Sticky headers are common, but they can overlap content or require awkward padding. <code>calc()</code> makes managing the space elegant.</p><pre><code class="language-html"><body class="flex flex-col min-h-screen"><br/>  <header class="h-16 bg-indigo-600 text-white p-4 sticky top-0 z-10"><br/>    Fixed Header<br/>  </header></p><p>  <main<br/>    class="flex-grow p-6 bg-gray-50"<br/>    style="padding-top: calc(4rem + 1.5rem);"<br/>  ><br/>    Content Section<br/>  </main></p><p>  <section class="h-[calc(100vh-4rem)] bg-gray-100 p-6 overflow-y-auto"><br/>    This section takes exactly the remaining viewport height below the header.<br/>  </section></p><p>  <footer class="h-12 bg-gray-700 text-white p-3 mt-auto">Footer</footer><br/></body><br/></code></pre><p>In the <code>section</code> example, <code>h-[calc(100vh-4rem)]</code> ensures that specific part of the page uses precisely the vertical space available below the 4rem header. No guesswork needed.</p><h3>Example 3: Fluid Typography That Breathes</h3><p>Want your text headings to scale smoothly with the viewport width, not just jump between breakpoints? <code>calc()</code> combined with viewport units (<code>vw</code>) is your friend.</p><pre><code class="language-html"><h1 class="text-[calc(1.5rem+2vw)] font-bold text-gray-900 leading-tight"><br/>  This Headline Scales Fluidly<br/></h1><br/><p class="text-[calc(1rem+0.5vw)] text-gray-700"><br/>  Even paragraph text can subtly adapt to the screen size, improving readability<br/>  across devices.<br/><br/></code></pre><p>Here, the font size has a base value (<code>1.5rem</code> or <code>1rem</code>) and adds a small percentage of the viewport width (<code>2vw</code> or <code>0.5vw</code>). This creates a much smoother scaling effect than relying solely on <code>text-lg</code>, <code>text-xl</code>, etc., at different breakpoints.</p><h3>Example 4: Precise Centering and Positioning</h3><p>Sometimes <code>flex</code> or <code>grid</code> centering isn't quite right, especially for absolutely positioned elements or overlays where you need an offset.</p><pre><code class="language-html"><div class="relative h-screen bg-gray-200"><br/>  <div<br/>    class="absolute top-[calc(50%-50px)] left-[50%] -translate-x-1/2 -translate-y-1/2 bg-white p-8 rounded shadow-lg"<br/>  ><br/>    I'm centered horizontally, but slightly offset vertically!<br/>  </div><br/></div><br/></code></pre><p>Here, <code>top-[calc(50%-50px)]</code> positions the element's top edge 50 pixels _above_ the halfway point of the container, while the <code>transform</code> utilities handle the rest of the centering adjustment based on the element's own size.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-DynamicStylingWithCalcInTailwindcss/precise-element-positioning.gif">precise-element-positioning</a></p><h2>Going Beyond Arbitrary Values: Custom <code>calc()</code> Utilities</h2><p>Arbitrary values are fantastic for one-offs. But what if you find yourself repeatedly using the same <code>calc()</code> expression? Like that <code>h-[calc(100vh-4rem)]</code> for content below your standard header? Typing that out every time is tedious and error-prone.</p><p>This is where extending your Tailwind configuration shines. You can define your own custom utilities that encapsulate these common calculations.</p><p><strong>Add this to your <code>tailwind.config.ts</code>:</strong></p><pre><code class="language-typescript">import type { Config } from "tailwindcss";</p><p>const config: Config = {<br/>  theme: {<br/>    extend: {<br/>      // Example: Add custom height calculation<br/>      height: {<br/>        "screen-minus-header": "calc(100vh - 4rem)", // Assuming 4rem header<br/>      },<br/>      // Example: Add custom width calculation<br/>      width: {<br/>        "content-area": "calc(100% - 16rem)", // Assuming 16rem sidebar<br/>      },<br/>      // Example: Add custom spacing<br/>      spacing: {<br/>        "dynamic-gutter": "calc(1rem + 2vw)",<br/>      },<br/>    },<br/>  },<br/>  plugins: [],<br/>  content: [<br/>    // Ensure your content paths are configured here<br/>    "./src/<em></em>/*.{html,js,jsx,ts,tsx,vue}",<br/>  ],<br/>};</p><p>export default config;<br/></code></pre><p>Now, you can use these just like native Tailwind utilities:</p><pre><code class="language-html"><main class="h-screen-minus-header w-content-area p-dynamic-gutter"><br/>  Look Ma, custom calc utilities!<br/></main><br/></code></pre><p>This makes your HTML cleaner, your calculations consistent, and your design system more robust.</p><h2>Conclusion</h2><p>TailwindCSS provides an incredible foundation for rapid UI development. By understanding and integrating the native CSS <code>calc()</code> function through arbitrary values and custom configurations, you unlock a whole new level of dynamic control and precision.</p><p>Thank you for reading! If you found this blog post helpful, please consider sharing it with others who might benefit. Feel free to check out my other blog posts and visit my socials!</p><p>- <a href="https://devarshi.dev">Profile</a><br/>- <a href="https://linkedin.com/in/devarshi-shimpi">Linkedin</a><br/>- <a href="https://twitter.com/devarshishimpi">Twitter</a><br/>- <a href="https://youtube.com/@devarshishimpi">Youtube</a><br/>- <a href="https://devarshishimpi.hashnode.dev">Hashnode</a><br/>- <a href="https://dev.to/devarshishimpi">DEV</a></p><h3>Read more</h3><p>- <a href="https://devarshi.dev/blog/creating-your-first-droplet-digitalocean-tutorials">Creating Your First Droplet - DigitalOcean Tutorials</a><br/>- <a href="https://devarshi.dev/blog/top-ten-vscode-extensions-you-need-in-twentytwentytwo">Top 10 VS CODE Extensions You Need In 2022!</a><br/>- <a href="https://devarshi.dev/blog/setting-up-an-ubuntu-ec2-instance-from-scratch-on-aws">Setting Up An Ubuntu EC2 Instance From Scratch on AWS</a><br/>]]></content:encoded>
      <link>https://devarshi.dev/blog/dynamic-styling-with-calc-in-tailwindcss</link>
      <guid isPermaLink="true">https://devarshi.dev/blog/dynamic-styling-with-calc-in-tailwindcss</guid>
      <pubDate>Wed, 15 Oct 2025 00:00:00 GMT</pubDate>
      <author>devarshishimpi@gmail.com (Devarshi Shimpi)</author>
      <enclosure url="https://static.devarshi.dev/blog/1600/DynamicStylingWithCalcInTailwindcss1600.png" type="image/png"/>
      <category>Technology</category>
      <category>Programming</category>
      <category>Development</category>
    </item>
    <item>
      <title><![CDATA[Introduction to Next.js 15: What's New and the improvements!]]></title>
      <description><![CDATA[Next.js 15 has introduced a range of exciting features and improvements that enhance both performance and developer experience.]]></description>
      <content:encoded><![CDATA[<h2>Introduction</h2><p>Next.js 15 has introduced a range of exciting features and improvements that enhance both performance and developer experience. Here’s a detailed overview of what's new!</p><h2>Seamless Upgrades with <code>@next/codemod CLI</code></h2><p>The enhanced codemod CLI simplifies upgrading to the latest Next.js and React versions. It automates code transformations, ensuring a smooth transition to new APIs and features.</p><pre><code class="language-bash">npx @next/codemod@canary upgrade latest<br/></code></pre><h3>Performance Enhancements</h3><p>Next.js 15 focuses heavily on improving the speed and efficiency of applications:</p><p>!<a href="https://static.devarshi.dev/blog/HLS-WhatsNewAndTheImprovementsInNextjs15/nextjs-15-banner.png">nextjs-15-banner</a></p><p>- <strong>Turbopack Boost:</strong> Next.js 15's integration with Turbopack accelerates development server startup by up to 53%, providing faster feedback loops.</p><p>- <strong>Hybrid Rendering:</strong> Partial prerendering combines static and dynamic content for quicker initial loads and improved user experience.</p><p>- <strong>Enhanced Caching:</strong> Optimized caching strategies reduce network requests, resulting in faster load times and predictable data fetching.</p><h3>Developer Experience (DX) Improvements</h3><p>Next.js 15 prioritizes the developer experience with several new tools and features:</p><p>- <strong>Asynchronous Request-Specific APIs</strong>: APIs for handling cookies, headers, and search parameters have been updated to support asynchronous operations. This change allows for cleaner code and enhances application responsiveness.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-WhatsNewAndTheImprovementsInNextjs15/nextjs-15-hydration-error.png">nextjs-15-hydration-error</a></p><p>- <strong>New Debugging Tools</strong>: Enhanced error messages and stack traces make debugging more efficient, helping developers quickly identify and resolve issues.</p><p>- <strong>New Form Component</strong>: A built-in form component simplifies form handling by eliminating the need for third-party libraries. It supports automatic validation, and progressive enhancement, ensuring that forms work even without JavaScript enabled.</p><pre><code class="language-tsx">import Form from "next/form";</p><p>export default function Page() {<br/>  return (<br/>    <Form action="/search"><br/>      <input name="query" /><br/>      <button type="submit">Submit</button><br/>    </Form><br/>  );<br/>}<br/></code></pre><p>- <strong>Experimental Authorization APIs</strong>: New APIs for handling authorization errors (<code>forbidden</code> and <code>unauthorized</code>) provide granular control over authentication processes.</p><p>- <strong>TypeScript Configuration Support</strong>: Developers can now use TypeScript for their configuration files by renaming <code>next.config.js</code> to <code>next.config.ts</code>. This feature improves type safety and autocompletion, reducing errors during development.</p><pre><code class="language-typescript">import type { NextConfig } from "next";</p><p>const nextConfig: NextConfig = {/<em> config options here </em>/};</p><p>export default nextConfig;<br/></code></pre><h3>Static Route Indicator</h3><p>!<a href="https://static.devarshi.dev/blog/HLS-WhatsNewAndTheImprovementsInNextjs15/nextjs-15-static-indicator.png">nextjs-15-static-indicator</a></p><p>Next.js now displays a Static Route Indicator during development to help you identify which routes are static or dynamic. This visual cue makes it easier to optimize performance by understanding how your pages are rendered.</p><h3>New Middleware Capabilities</h3><p>A standout feature in Next.js 15 is the introduction of middleware, which allows developers to run code before requests are completed. This is particularly useful for tasks such as authentication and logging.</p><h3>Support for React 19 and ESLint 9</h3><p>Next.js 15 officially supports React 19, which introduces several performance optimizations and new features including the new <strong>React Compiler</strong>.</p><p>It also adds support for ESLint 9 while maintaining backward compatibility with ESLint 8. This ensures better code quality through improved linting capabilities tailored for React hooks usage.</p><h2>Conclusion</h2><p>Next.js 15 represents a significant advancement in web development capabilities with its blend of performance enhancements, improved developer tools, and robust support for modern React features.</p><p>Thank you for reading! If you found this blog post helpful, please consider sharing it with others who might benefit. Feel free to check out my other blog posts and visit my socials!</p><p>- <a href="https://devarshi.dev">Profile</a><br/>- <a href="https://linkedin.com/in/devarshi-shimpi">Linkedin</a><br/>- <a href="https://twitter.com/devarshishimpi">Twitter</a><br/>- <a href="https://youtube.com/@devarshishimpi">Youtube</a><br/>- <a href="https://devarshishimpi.hashnode.dev">Hashnode</a><br/>- <a href="https://dev.to/devarshishimpi">DEV</a></p><h3>Read more</h3><p>- <a href="https://devarshi.dev/blog/what-are-docker-images-and-how-to-use-them">What Are Docker Images And How To Use Them</a><br/>- <a href="https://devarshi.dev/blog/creating-your-first-droplet-digitalocean-tutorials">Creating Your First Droplet - DigitalOcean Tutorials</a><br/>- <a href="https://devarshi.dev/blog/setting-up-an-ubuntu-ec2-instance-from-scratch-on-aws">Setting Up An Ubuntu EC2 Instance From Scratch on AWS</a><br/>]]></content:encoded>
      <link>https://devarshi.dev/blog/intro-to-nextjs-fifteen-whats-new-and-improvements</link>
      <guid isPermaLink="true">https://devarshi.dev/blog/intro-to-nextjs-fifteen-whats-new-and-improvements</guid>
      <pubDate>Tue, 17 Dec 2024 00:00:00 GMT</pubDate>
      <author>devarshishimpi@gmail.com (Devarshi Shimpi)</author>
      <enclosure url="https://static.devarshi.dev/blog/1600/WhatsNewAndTheImprovementsInNextjs151600.png" type="image/png"/>
      <category>Technology</category>
      <category>Programming</category>
      <category>Development</category>
    </item>
    <item>
      <title><![CDATA[Managing Dependencies and Security in JavaScript with NPM]]></title>
      <description><![CDATA[The JavaScript ecosystem, particularly with NPM, the security implications, and how modern bundlers mitigate these risks.]]></description>
      <content:encoded><![CDATA[<h2>Introduction</h2><p>The JavaScript ecosystem, particularly with <strong>NPM</strong>, _is both a boon and a bane for developers_. On one hand, it provides an incredibly vast library of modules that can accelerate development. On the other hand, it can feel like a tangled web of dependencies, raising legitimate security concerns. Let's dive deep into the intricacies of NPM, the security implications, and how modern bundlers mitigate these risks.</p><h2>Understanding NPM and Its Ecosystem</h2><p>NPM is the default package manager for Node.js, which is widely used for server-side and full-stack JavaScript development. It allows developers to easily install, share, and manage code modules.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-ManagingSecurityInJSWithNPM/npm-lp.png">npm-lp</a></p><p>The convenience it offers has made it a cornerstone of modern JavaScript development. However, with great convenience comes great responsibility.</p><h3>The Dependency Hell</h3><p>When you set up a basic project with <strong>NPM</strong>, you often find yourself pulling in numerous dependencies. Each dependency can have its own dependencies, creating a cascading effect that can quickly spiral out of control. This phenomenon is often referred to as <strong>dependency hell</strong>.</p><p><strong>Consider this scenario:</strong> You install a popular library like <a href="https://www.npmjs.com/package/tailwindcss">TailwindCSS</a>. TailwindCSS itself has a few dependencies.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-ManagingSecurityInJSWithNPM/tailwind-npm-depend.png">tailwind-npm-depend</a></p><p>Those dependencies, in turn, have their own dependencies, and so on. Before you know it, your project has hundreds of packages installed, many of which you may not be familiar with. This can make your project more vulnerable to security risks, as it’s challenging to vet each package and its updates.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-ManagingSecurityInJSWithNPM/tailwind-depend-graph.png">tailwind-depend-graph</a></p><h2>The Security Concerns</h2><p>One of the primary security concerns with NPM is the potential for malicious code to be introduced into your project through dependencies. This can happen in a few ways:</p><p>1. <strong>Compromised Packages</strong>: A legitimate package you depend on might get compromised. This can happen if a maintainer's account is hacked or if the maintainer themselves goes rogue.</p><p>2. <strong>Typosquatting</strong>: Malicious actors sometimes publish packages with names similar to popular packages, hoping that developers will mistype the name and inadvertently install the malicious package.</p><p>3. <strong>Dependency Chains</strong>: Even if your direct dependencies are secure, they might depend on other packages that are not. This creates a long chain of trust that can be difficult to manage.</p><h3>The Polyfill.io Incident</h3><p>!<a href="https://static.devarshi.dev/blog/HLS-ManagingSecurityInJSWithNPM/polyfill-article-link.png">polyfill-article-link</a></p><p>You can read <a href="https://arcticwolf.com/resources/blog/polyfill-supply-chain-attack-impacts-100k-sites/">Arctic Wolf's write-up on the Polyfill.io supply chain attack</a></p><p>A recent incident involving a service called Polyfill.io highlighted these risks. <strong>Polyfill.io</strong> is a <strong>CDN service</strong> that provides _JavaScript polyfills for older browsers_. It was discovered that this service could potentially serve different versions of the same script based on the browser's user agent. This variability made it impossible to use integrity checks to verify the script, creating a security vulnerability.</p><p>Many websites, including high-profile ones like Hulu, were loading scripts from this service. This incident underscores the dangers of relying on third-party CDNs for critical scripts, as a compromise in the CDN can lead to widespread vulnerabilities.</p><h3>So, Are We Trading Security for Convenience?</h3><p>Yes, managing dependencies in a large software project is inherently complex, and no system is foolproof. However, modern package managers, bundlers, and security best practices provide robust safeguards against most common attack vectors.</p><p>The key takeaway is this: understand how your tools work. Don't blindly trust; verify. Pin your dependency versions, audit your dependencies regularly, and stay informed about potential vulnerabilities. By adopting a proactive security mindset and leveraging the tools at your disposal, you can reap the benefits of a vibrant package ecosystem without compromising the integrity of your code.</p><h2>Modern Bundlers to the Rescue</h2><p>Fortunately, modern JavaScript development has tools to mitigate these risks. Bundlers like Webpack, Vite, and Rollup play a crucial role in ensuring the security and efficiency of web applications.</p><h3>What is a Bundler?</h3><p>A bundler takes the various modules and dependencies in your project and combines them into a single file (or a few files) that can be efficiently loaded by the browser. This process not only improves performance by reducing the _number of HTTP requests_ but also helps in managing dependencies more securely.</p><h3>How Bundlers Improve Security</h3><p>1. <strong>Local Assets</strong>: When you build your project using a bundler, it compiles all your code and dependencies into a single bundle. This means that your application is <strong>serving all its JavaScript</strong> from <strong>your own domain</strong>, <strong>not relying on third-party CDNs</strong>. This significantly reduces the risk of third-party script compromises.</p><p>2. <strong>Lock Files</strong>: NPM generates a <code>package-lock.json</code> file that locks the versions of all installed packages. This ensures that the same versions are used every time someone installs your project, even if newer versions of the dependencies are released. This consistency is crucial for security.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-ManagingSecurityInJSWithNPM/integrity-package-lock.png">integrity-package-lock</a></p><p>3. <strong>Integrity Checks</strong>: Modern build tools can include integrity checks to ensure that the files served to the browser match the expected hashes. This makes it harder for compromised or altered packages to go unnoticed.</p><h3>Example with Vite</h3><p>Let's take Vite, a modern bundler, as an example. When you install dependencies and build your project with Vite, it bundles all the necessary JavaScript files into a single minified file. Here’s a step-by-step of what happens:</p><p>!<a href="https://static.devarshi.dev/blog/HLS-ManagingSecurityInJSWithNPM/vite-lp.png">vite-lp</a></p><p>1. <strong>Install Dependencies</strong>: You install your dependencies using NPM.</p><p>2. <strong>Build the Project</strong>: You run <code>vite build</code>, which compiles your project.</p><p>3. <strong>Serve Local Assets</strong>: When you deploy your project, all the JavaScript files are served from your own domain. No external CDNs are involved.</p><p>This process ensures that the JavaScript running on your site is exactly what you expect, with no surprises from third-party CDNs.</p><h2>Addressing Common Misconceptions</h2><p>There are several misconceptions about NPM and modern JavaScript development that contribute to the fear of security risks. Let’s address some of these:</p><h3>Misconception 1: NPM Directly Serves Files to Users</h3><p>Some believe that when users visit a site, they are directly fetching files from NPM. This is not true. NPM is used to manage and install dependencies during the development process. When you build and deploy your project, all the code is served from your own servers, not from NPM.</p><h3>Misconception 2: Dev Dependencies are Included in Production</h3><p>Another common misconception is that dev dependencies (packages used for development purposes, like testing or linting tools) are included in the final bundle served to users. This is false. Dev dependencies are only used during development and are not included in the production build.</p><h3>Misconception 3: Package Lock Files are Unnecessary</h3><p>Some developers overlook the importance of <code>package-lock.json</code> files. These files ensure that the exact same versions of dependencies are used every time the project is installed, which is crucial for maintaining security and consistency. Without a lock file, there’s a risk of pulling in newer, potentially compromised versions of dependencies.</p><h2>Best Practices for Secure JavaScript Development</h2><p>To further mitigate security risks, follow these best practices:</p><p>1. <strong>Regular Audits</strong>: Regularly audit your dependencies using tools like <code>npm audit</code> to identify and address vulnerabilities.</p><p>2. <strong>Lock File Maintenance</strong>: Always use and maintain your <code>package-lock.json</code> file. Ensure that your CI/CD pipelines respect the lock file to prevent accidental upgrades.</p><p>3. <strong>Dependency Management</strong>: Be mindful of the dependencies you add to your project. Avoid unnecessary dependencies and consider the reputation and activity of the package maintainers.</p><p>4. <strong>Use Trusted Sources</strong>: Prefer well-established libraries and avoid packages with unclear or questionable histories.</p><p>5. <strong>Stay Updated</strong>: Keep your dependencies up to date with the latest security patches. Tools like Dependabot can automate this process for you.</p><p>By taking proactive steps to secure your dependencies and being aware of how your tools work, you can harness the power of NPM and modern JavaScript development while keeping your projects safe and secure.</p><h2>Conclusion</h2><p>The NPM ecosystem, with its vast library of packages, undeniably brings convenience to JavaScript development. However, it also introduces potential security risks that cannot be ignored. Understanding how modern bundlers work, maintaining a strict dependency management strategy, and following best practices can significantly mitigate these risks.</p><p>Thank you for reading! If you found this blog post helpful, please consider sharing it with others who might benefit. Feel free to check out my other blog posts and visit my socials!</p><p>- <a href="https://devarshi.dev">Profile</a><br/>- <a href="https://linkedin.com/in/devarshi-shimpi">Linkedin</a><br/>- <a href="https://twitter.com/devarshishimpi">Twitter</a><br/>- <a href="https://youtube.com/@devarshishimpi">Youtube</a><br/>- <a href="https://devarshishimpi.hashnode.dev">Hashnode</a><br/>- <a href="https://dev.to/devarshishimpi">DEV</a></p><h3>Read more</h3><p>- <a href="https://devarshi.dev/blog/how-to-create-a-new-nextjs-project-with-cf-workers-and-pages">How to create a new Next.js project with Cloudflare Pages and Workers</a><br/>- <a href="https://devarshi.dev/blog/easiest-way-to-install-wordpress-for-beginners">Easiest Way to Install WordPress Locally for Beginners</a><br/>- <a href="https://devarshi.dev/blog/wordpresscom-wordpressorg-the-differences-which-to-choose">WordPress.com vs. WordPress.org The Differences & Which To Choose</a><br/>]]></content:encoded>
      <link>https://devarshi.dev/blog/managing-dependencies-and-security-with-npm</link>
      <guid isPermaLink="true">https://devarshi.dev/blog/managing-dependencies-and-security-with-npm</guid>
      <pubDate>Fri, 09 Aug 2024 00:00:00 GMT</pubDate>
      <author>devarshishimpi@gmail.com (Devarshi Shimpi)</author>
      <enclosure url="https://static.devarshi.dev/blog/1600/ManagingSecurityInJSWithNPM1600.png" type="image/png"/>
      <category>Technology</category>
      <category>Programming</category>
      <category>Development</category>
    </item>
    <item>
      <title><![CDATA[The End of Google URL Shortener and breaks 4.6 BILLION URLs!]]></title>
      <description><![CDATA[The innovations Google has brought to the table are amazing like Chrome, But sometimes, it goes the other way, the end of goo.gl, their URL shortener service.]]></description>
      <content:encoded><![CDATA[<h2>Introduction</h2><p>The innovations Google has brought to the table, from Chrome to the Google ecosystem, have undeniably shaped the internet. But sometimes, their decisions leave us scratching our heads, frustrated and disappointed. One such decision is the end of <code>goo.gl</code>, their URL shortener service, which brings back memories of other products they have shelved over the years—like Google Reader and, more recently, Google Domains.</p><h2>The Rise and Fall of goo.gl</h2><p>!<a href="https://static.devarshi.dev/blog/HLS-TheEndOfGoogleURLShortener/goog-url-shortener-logo.png">goog-url-shortener-logo</a></p><p>When <a href="https://goo.gl">goo.gl</a> was launched, it was a nifty tool that made sharing long, cumbersome URLs a breeze. It offered analytics and QR codes, making it a favorite among both casual users and developers.</p><p>But in 2018, Google announced that it would no longer support the creation of new goo.gl links, nudging users towards alternatives like <a href="https://firebase.google.com/docs/dynamic-links">Firebase Dynamic Links</a></p><p>Fast forward to now, and we've learned that all goo.gl links will completely stop working by August 2025. This isn’t just about not being able to make new links anymore; it means that all existing links will die. Clicking on them after the cutoff date will lead to a 404 error -- a digital dead end.</p><h2>Alternatives to Google URL Shortener</h2><p>Google suggested <a href="https://firebase.google.com/docs/dynamic-links">Firebase Dynamic Links</a> as an alternative, but guess what? That service is also being deprecated on August 25, 2025. It's a frustrating loop, recommending one product as a replacement only to kill it off later. It makes planning and continuity a nightmare for users.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-TheEndOfGoogleURLShortener/dub-co-homepage.png">dub-co-homepage</a></p><p>As goo.gl sunsets, users are left seeking alternatives. Services like Bitly, TinyURL, and <a href="https://dub.co">dub.co</a> offer similar functionalities, each service comes with its own set of features, policies, and levels of reliability.</p><p>I personally prefer <a href="https://dub.co">dub.co</a> and it has been great in my experience till now. Their team was quick enough to even make the migration process as seamless as possible! Especially their quick alternative as <strong>ggl.link</strong></p><p>!<a href="https://static.devarshi.dev/blog/HLS-TheEndOfGoogleURLShortener/dub-co-blog-google.png">dub-co-blog-google</a></p><h2>Conclusion</h2><p>The decision to end goo.gl is a reminder of the impermanence of digital tools. While Google's decision might be based on practical considerations, the impact on users is real and far-reaching. It disrupts current operations, potentially erases valuable information, and once again highlights the precariousness of relying on a single company for critical digital infrastructure.</p><p>Thank you for reading! If you found this blog post helpful, please consider sharing it with others who might benefit. Feel free to check out my other blog posts and visit my socials!</p><p>- <a href="https://devarshi.dev">Profile</a><br/>- <a href="https://linkedin.com/in/devarshi-shimpi">Linkedin</a><br/>- <a href="https://twitter.com/devarshishimpi">Twitter</a><br/>- <a href="https://youtube.com/@devarshishimpi">Youtube</a><br/>- <a href="https://devarshishimpi.hashnode.dev">Hashnode</a><br/>- <a href="https://dev.to/devarshishimpi">DEV</a></p><h3>Read more</h3><p>- <a href="https://devarshi.dev/blog/what-are-docker-images-and-how-to-use-them">What Are Docker Images And How To Use Them</a><br/>- <a href="https://devarshi.dev/blog/creating-your-first-droplet-digitalocean-tutorials">Creating Your First Droplet - DigitalOcean Tutorials</a><br/>- <a href="https://devarshi.dev/blog/setting-up-an-ubuntu-ec2-instance-from-scratch-on-aws">Setting Up An Ubuntu EC2 Instance From Scratch on AWS</a><br/>]]></content:encoded>
      <link>https://devarshi.dev/blog/google-ends-its-url-shortener-and-breaks-urls</link>
      <guid isPermaLink="true">https://devarshi.dev/blog/google-ends-its-url-shortener-and-breaks-urls</guid>
      <pubDate>Thu, 01 Aug 2024 00:00:00 GMT</pubDate>
      <author>devarshishimpi@gmail.com (Devarshi Shimpi)</author>
      <enclosure url="https://static.devarshi.dev/blog/1600/TheEndOfGoogleURLShortener1600.png" type="image/png"/>
      <category>Technology</category>
      <category>Programming</category>
      <category>Development</category>
    </item>
    <item>
      <title><![CDATA[How to create a new Next.js project with Cloudflare Pages and Workers]]></title>
      <description><![CDATA[In this guide, we'll walk through creating a new Next.js 14 project using TypeScript and deploying it on Cloudflare Pages with Workers.]]></description>
      <content:encoded><![CDATA[<h2>Introduction</h2><p>In this guide, we'll walk through creating a new Next.js 14 project using TypeScript and deploying it on Cloudflare Pages with Workers for a full-stack solution. We'll use the <code>create-cloudflare</code> CLI (C3) to set up our project, and deploy the application.</p><h3>Step 1: Create a new Git repository</h3><p>Go to <a href="https://github.com/">GitHub</a>, click the "+" icon in the top right, and select <strong>"New repository"</strong>. Set the repository name to <code>nextjs-cf-pages-workers</code> or whatever you would like to, choose Public or Private visibility, and click <strong>"Create repository"</strong>.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-HowToCreateNextJSProjectWithCFPagesAndWorkers/new-git-repo.png">new-git-repo</a></p><p>Your new repository is now ready! Clone the repository and get ready for the next step!</p><h3>Step 2: Create a New Next.js Project</h3><p>To get started, we'll use the <code>create-cloudflare</code> CLI (C3) to create a new Next.js project. Open your terminal and run the following command:</p><pre><code class="language-bash">npm create cloudflare@latest my-next-app -- --framework=next<br/></code></pre><p>This command initializes a new Next.js project in a directory named <code>my-next-app</code>. Follow the prompts to configure your project. The CLI will install the necessary dependencies, including the Wrangler CLI and the <code>@cloudflare/next-on-pages</code> adapter.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-HowToCreateNextJSProjectWithCFPagesAndWorkers/npm-create-cloudflare.png">npm-create-cloudflare</a></p><p>In your terminal, this is how it should look like. After the project is created, navigate to the project directory, and run <code>npm run dev</code>. You should have a browser preview like this:</p><p>!<a href="https://static.devarshi.dev/blog/HLS-HowToCreateNextJSProjectWithCFPagesAndWorkers/next-browser-preview.png">next-browser-preview</a></p><h3>Step 3: Configure the Project for Cloudflare Pages</h3><p>You can deploy using mutliple options, I have covered 2 in this article.</p><p>Log in to the Cloudflare dashboard and select your account. Navigate to Workers & Pages > Create application > Pages > Connect to Git. Authorize access to your GitHub account and select the new repository you created.</p><p>Make sure you have added <code>nodejs_compat</code> as the compatibility flags or the build will fail!</p><h3>Step 4: Configure and Deploy Without C3</h3><p>If you prefer not to use C3, you can manually configure and deploy your project. Install the <code>@cloudflare/next-on-pages</code> adapter:</p><pre><code class="language-bash">npm install @cloudflare/next-on-pages<br/></code></pre><h3>Step 5: Set Up Bindings for Local Development</h3><p>Bindings allow your application to interact with Cloudflare developer products. To set up bindings for local development, modify your Next.js configuration:</p><pre><code class="language-javascript">// next.config.mjs<br/>import { setupDevPlatform } from "@cloudflare/next-on-pages/next-dev";</p><p>if (process.env.NODE_ENV === "development") {<br/>  await setupDevPlatform();<br/>}</p><p>/<em></em> @type {import('next').NextConfig} */<br/>const nextConfig = {};</p><p>export default nextConfig;<br/></code></pre><p>Ensure you have a <code>wrangler.toml</code> file at the root of your project with a KV binding:</p><pre><code class="language-toml"><h1>wrangler.toml</h1><br/>name = "my-next-app"<br/>compatibility_flags = ["nodejs_compat"]</p><p>[[kv_namespaces]]<br/>binding = "MY_KV"<br/>id = "<YOUR_KV_NAMESPACE_ID>"<br/></code></pre><p>Alternatively, you can run the following command and it should deploy the project as shown below.</p><pre><code class="language-bash">npm run deploy<br/></code></pre><p>!<a href="https://static.devarshi.dev/blog/HLS-HowToCreateNextJSProjectWithCFPagesAndWorkers/cf-deploy-terminal.png">cf-deploy-terminal</a></p><h2>Success!</h2><p>By following these steps, you've successfully created and deployed a full-stack Next.js 14 project with TypeScript on Cloudflare Pages and Workers. This setup leverages Cloudflare's powerful developer products to enhance your application's capabilities.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-HowToCreateNextJSProjectWithCFPagesAndWorkers/cf-dashboard.png">cf-dashboard</a></p><h2>Conclusion</h2><p>Thank you for reading! If you found this blog post helpful, please consider sharing it with others who might benefit. Feel free to check out my other blog posts and visit my socials!</p><p>- <a href="https://devarshi.dev">Profile</a><br/>- <a href="https://linkedin.com/in/devarshi-shimpi">Linkedin</a><br/>- <a href="https://twitter.com/devarshishimpi">Twitter</a><br/>- <a href="https://youtube.com/@devarshishimpi">Youtube</a><br/>- <a href="https://devarshishimpi.hashnode.dev">Hashnode</a><br/>- <a href="https://dev.to/devarshishimpi">DEV</a></p><h3>Read more</h3><p>- <a href="https://devarshi.dev/blog/what-are-docker-images-and-how-to-use-them">What Are Docker Images And How To Use Them</a><br/>- <a href="https://devarshi.dev/blog/creating-your-first-droplet-digitalocean-tutorials">Creating Your First Droplet - DigitalOcean Tutorials</a><br/>- <a href="https://devarshi.dev/blog/setting-up-an-ubuntu-ec2-instance-from-scratch-on-aws">Setting Up An Ubuntu EC2 Instance From Scratch on AWS</a><br/>]]></content:encoded>
      <link>https://devarshi.dev/blog/how-to-create-a-new-nextjs-project-with-cf-workers-and-pages</link>
      <guid isPermaLink="true">https://devarshi.dev/blog/how-to-create-a-new-nextjs-project-with-cf-workers-and-pages</guid>
      <pubDate>Thu, 18 Jul 2024 00:00:00 GMT</pubDate>
      <author>devarshishimpi@gmail.com (Devarshi Shimpi)</author>
      <enclosure url="https://static.devarshi.dev/blog/1600/HowToCreateNextJSProjectWithCFPagesAndWorkers1600.png" type="image/png"/>
      <category>Technology</category>
      <category>Programming</category>
      <category>Development</category>
    </item>
    <item>
      <title><![CDATA[Google's AI-Powered Cloud IDE Project IDX Goes Open Beta!]]></title>
      <description><![CDATA[Google unveiled an exciting new tool for developers—Project IDX. Now in open beta, Project IDX is set the way we approach web and mobile app development.]]></description>
      <content:encoded><![CDATA[<h2>Introduction</h2><p>At the <strong>2024 Google I/O developer conference</strong>, Google unveiled an exciting new tool for developers—Project IDX. Now in open beta, Project IDX is set to revolutionise the way we approach web and mobile app development.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-GoogleProjectIDX-goes-Open-Beta/project-idx-demo.png">project-idx-demo</a></p><p>With its AI-powered features and seamless cloud integration, this web-based integrated development environment (IDE) promises to simplify and enhance the development workflow.</p><h2>What is Project IDX?</h2><p>Project IDX is a next-generation, web-based IDE that aims to streamline the development process. Built on the popular Code OSS project and leveraging the robust infrastructure of Google Cloud, Project IDX offers a fully configurable virtual machine (VM) environment right in your browser.</p><p>For more details and to join the open beta, visit the <a href="https://idx.google.com">Project IDX website</a>.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-GoogleProjectIDX-goes-Open-Beta/idx-frontpage.png">idx-frontpage</a></p><p>This setup ensures reliability, safety, and complete configurability, making it an ideal choice for developers of all levels.</p><h2>Making the Most of Project IDX</h2><p>- <strong>Get Started Quickly</strong><br/>  Start new projects or import existing ones from GitHub effortlessly. Use pre-configured templates and choose from popular frameworks and languages like JavaScript, Dart, and soon Python and Go.<br/>- <strong>Leverage IDX AI for Enhanced Coding</strong><br/>  Utilize IDX AI for intelligent code completion, translations, and explanations of complex snippets, boosting coding speed and quality.</p><p>- <strong>Utilize Built-In Emulators for Mobile Development</strong><br/>  Test your mobile apps with built-in Android emulators and iOS simulators, previewing changes in real-time within Project IDX.</p><p>- <strong>Seamless Deployment with Firebase Hosting</strong><br/>  Deploy web and Flutter projects directly to Firebase Hosting with a few clicks, ensuring fast, secure, and global hosting.</p><p>- <strong>Collaborate with Ease</strong><br/>  Use the experimental collaborative workspace sharing to invite team members, enabling real-time collaboration on code, terminals, emulators, and more.</p><h2>Conclusion</h2><p>Google's Project IDX is set to transform the development landscape with its innovative, AI-powered, and cloud-based IDE. Now in open beta, it's the perfect time to explore its capabilities and integrate it into your development workflow.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-GoogleProjectIDX-goes-Open-Beta/idx-newproj.png">idx-newproj</a></p><p>Thank you for reading! If you found this blog post helpful, please consider sharing it with others who might benefit. Feel free to check out my other blog posts and visit my socials!</p><p>- <a href="https://devarshi.dev">Profile</a><br/>- <a href="https://linkedin.com/in/devarshi-shimpi">Linkedin</a><br/>- <a href="https://twitter.com/devarshishimpi">Twitter</a><br/>- <a href="https://youtube.com/@devarshishimpi">Youtube</a><br/>- <a href="https://devarshishimpi.hashnode.dev">Hashnode</a><br/>- <a href="https://dev.to/devarshishimpi">DEV</a></p><h3>Read more</h3><p>- <a href="https://devarshi.dev/blog/how-fast-is-bunsh-after-all">How Fast Is Bun.sh in 2024 After All?</a><br/>- <a href="https://devarshi.dev/blog/how-to-install-and-setup-a-ghost-blog-on-aws-lightsail">How to Install and Set Up a Ghost Blog on AWS Lightsail</a><br/>- <a href="https://devarshi.dev/blog/deploy-minio-on-amazon-eks-self-host-s3-storage">Deploy MinIO on Amazon EKS and use your S3 Compatible Storage</a><br/>]]></content:encoded>
      <link>https://devarshi.dev/blog/google-project-idx-cloud-ide-open-beta</link>
      <guid isPermaLink="true">https://devarshi.dev/blog/google-project-idx-cloud-ide-open-beta</guid>
      <pubDate>Mon, 10 Jun 2024 00:00:00 GMT</pubDate>
      <author>devarshishimpi@gmail.com (Devarshi Shimpi)</author>
      <enclosure url="https://static.devarshi.dev/blog/1600/GoogleProjectIDXgoesOpenBeta1600.png" type="image/png"/>
      <category>Technology</category>
      <category>Programming</category>
      <category>Development</category>
    </item>
    <item>
      <title><![CDATA[Deploy MinIO on Amazon EKS and use your S3 Compatible Storage]]></title>
      <description><![CDATA[Tired of the limitations and costs of AWS S3? Unlock a powerful alternative with MinIO, seamlessly integrated with Amazon EKS.]]></description>
      <content:encoded><![CDATA[<h2>Introduction</h2><p>Tired of the limitations and costs of AWS S3? Unlock a powerful alternative with MinIO, seamlessly integrated with Amazon EKS. This guide provides a step-by-step walkthrough to deploy MinIO, a scalable, multi-tenant object storage solution, on Amazon EKS in just 15 minutes.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-Deploy-MinIO-on-AWS-EKS-and-use-your-S3-Compatible-Storage/minio-banner.png">minio-banner</a></p><p>Amazon EKS, a managed Kubernetes service on AWS, simplifies Kubernetes management, while MinIO, available on the AWS Marketplace, brings robust object storage capabilities. Imagine handling terabytes to exabytes of data, all while isolating tenants in their own namespaces, all without the confines of S3.</p><p>This guide empowers you to ditch AWS S3 and embrace a superior alternative. Let's get started!</p><h2>Prerequisites</h2><p>Before diving in, ensure you have the following tools installed:</p><p>- <code>awscli</code><br/>- <code>kubectl</code><br/>- <code>eksctl</code></p><p>Have these three configuration parameters handy:</p><p>1. <strong>AWS Account Number:</strong> Find it in the AWS Console or using this command:<br/>   <pre><code class="language-sh">   export AWS_ACCOUNT_NUMBER=<code>aws sts get-caller-identity --query "Account" --output text</code><br/>   echo $AWS_ACCOUNT_NUMBER<br/>   </code></pre><br/>2. <strong>Region:</strong> For example, <code>us-west-2</code>.<br/>3. <strong>Cluster Name:</strong> For example, <code>minio-cluster</code>.</p><h2>Initial Setup</h2><h3>1. Set Up Cluster</h3><p><strong>New Cluster:</strong><br/>Replace <code><CLUSTER_NAME></code> and execute:</p><pre><code class="language-sh">eksctl create cluster \<br/>--name <CLUSTER_NAME> \<br/>--version 1.21 \<br/>--node-type=c6i.24xlarge \<br/>--nodes-min=4 \<br/>--nodes=4 \<br/>--nodes-max=4 \<br/>--zones=us-west-2a,us-west-2b,us-west-2c<br/></code></pre><h3>2. Install AWS EBS CSI Driver</h3><p>This driver allows using gp3 and sc1 storage types within EKS:</p><pre><code class="language-sh">kubectl apply -k "github.com/kubernetes-sigs/aws-ebs-csi-driver/deploy/kubernetes/overlays/stable/?ref=release-1.5"<br/></code></pre><h2>Cluster Configuration</h2><h3>1. Create IAM Policy</h3><p>Replace <code><CLUSTER_NAME></code> and <code><AWS_ACCOUNT_NUMBER></code> in <code>iam-policy.json</code>:</p><pre><code class="language-sh">aws iam create-policy \<br/>--policy-name minio-eks-<CLUSTER_NAME> \<br/>--policy-document file://iam-policy.json<br/></code></pre><h3>2. Create an OIDC Provider</h3><pre><code class="language-sh">eksctl utils associate-iam-oidc-provider --region=us-west-2 --cluster=<CLUSTER_NAME> --approve<br/></code></pre><h3>3. Create Trust, Role, and Service Account</h3><p>For MinIO Operator:</p><pre><code class="language-sh">eksctl create iamserviceaccount \<br/>   --name minio-operator \<br/>   --namespace minio-operator \<br/>   --cluster <CLUSTER_NAME> \<br/>   --attach-policy-arn arn:aws:iam::<AWS_ACCOUNT_NUMBER>:policy/minio-eks-<CLUSTER_NAME> \<br/>   --approve \<br/>   --override-existing-serviceaccounts<br/></code></pre><p>For AWS EBS CSI Driver:</p><pre><code class="language-sh">eksctl create iamserviceaccount<br/>   --name ebs-csi-controller-sa<br/>   --namespace kube-system<br/>   --cluster <CLUSTER_NAME><br/>   --attach-policy-arn arn:aws:iam::<AWS_ACCOUNT_NUMBER>:policy/minio-eks-<CLUSTER_NAME><br/>   --approve<br/>   --override-existing-serviceaccounts<br/></code></pre><h2>Installing MinIO</h2><p>Deploy the MinIO Operator:</p><pre><code class="language-sh">kubectl apply -k github.com/miniohq/marketplace/eks/resources<br/></code></pre><h2>Accessing MinIO</h2><h3>1. Retrieve the JWT for Operator Console</h3><pre><code class="language-sh">kubectl -n minio-operator get secret $(kubectl -n minio-operator get serviceaccount console-sa -o jsonpath="{.secrets[0].name}") -o jsonpath="{.data.token}" | base64 --decode<br/></code></pre><h3>2. Port Forward to Operator Console</h3><pre><code class="language-sh">kubectl -n minio-operator port-forward svc/console 9090<br/></code></pre><p>Open <a href="http://localhost:9090">http://localhost:9090</a> in your browser and log in with the retrieved JWT.</p><h3>3. Create a Tenant</h3><p>Log in and create your first tenant, specifying the desired size and storage type.</p><h3>Conclusion</h3><p>Congratulations! In just 15 minutes, you've successfully deployed MinIO on Amazon EKS, paving the way for a robust and scalable object storage solution. This guide offers a powerful starting point for migrating away from AWS S3, empowering you with flexibility, cost-efficiency, and a superior alternative for your data storage needs.</p><p>Thank you for reading! If you found this blog post helpful, please consider sharing it with others who might benefit. Feel free to check out my other blog posts and visit my socials!</p><p>- <a href="https://devarshi.dev">Profile</a><br/>- <a href="https://linkedin.com/in/devarshi-shimpi">Linkedin</a><br/>- <a href="https://twitter.com/devarshishimpi">Twitter</a><br/>- <a href="https://youtube.com/@devarshishimpi">Youtube</a><br/>- <a href="https://devarshishimpi.hashnode.dev">Hashnode</a><br/>- <a href="https://dev.to/devarshishimpi">DEV</a></p><h3>Read more</h3><p>- <a href="https://devarshi.dev/blog/setting-up-an-ubuntu-ec2-instance-from-scratch-on-aws">Setting Up An Ubuntu EC2 Instance From Scratch on AWS</a><br/>- <a href="https://devarshi.dev/blog/how-to-install-and-setup-a-ghost-blog-on-aws-lightsail">How to Install and Set Up a Ghost Blog on AWS Lightsail</a><br/>- <a href="https://devarshi.dev/blog/creating-your-first-droplet-digitalocean-tutorials">Creating Your First Droplet - DigitalOcean Tutorials</a><br/>]]></content:encoded>
      <link>https://devarshi.dev/blog/deploy-minio-on-amazon-eks-self-host-s3-storage</link>
      <guid isPermaLink="true">https://devarshi.dev/blog/deploy-minio-on-amazon-eks-self-host-s3-storage</guid>
      <pubDate>Tue, 23 May 2023 00:00:00 GMT</pubDate>
      <author>devarshishimpi@gmail.com (Devarshi Shimpi)</author>
      <enclosure url="https://static.devarshi.dev/blog/1600/DeployMinIOonAWSEKSanduseyourS3CompatibleStorage1600.png" type="image/png"/>
      <category>Technology</category>
      <category>Programming</category>
      <category>Development</category>
    </item>
    <item>
      <title><![CDATA[How To Create An AI Chatbot with Google GEMINI using Node.js]]></title>
      <description><![CDATA[This tutorial provides step-by-step instructions on integrating and building with Google Gemini, and customizing the chatbot.]]></description>
      <content:encoded><![CDATA[<h2>Introduction</h2><p>Generative AI has become a popular topic in the field of technology over the past year. Many developers are creating interesting projects using this technology. Google has developed its own generative AI model called Gemini.</p><p>In this article, we will be building a simple Node.js ChatBot and integrating Google Gemini into it. We will utilize the Google Gemini SDK for this purpose.</p><h3>What is Gemini?</h3><p>!<a href="https://static.devarshi.dev/blog/HLS-HowToCreateAIChatBotWithGemini/gemini-google.png">gemini-google</a></p><p><a href="<https://en.wikipedia.org/wiki/Gemini_(language_model">Google Gemini</a>>) is an advanced AI model developed by Google AI. Unlike traditional AI models, Gemini is not limited to processing text alone. It can also comprehend and operate on diverse formats such as code, audio, images, and video. This feature opens up exciting possibilities for your Node.js projects.</p><h3>Project Setup</h3><p>#### 1. Creating a Node.js Project</p><p>To begin our project, we need to set up a Node.js environment. Let's create a new Node.js project by running the following command in the terminal:</p><pre><code class="language-">npm init -y<br/></code></pre><p>This command will initialize a new Node.js project.</p><p>#### 2. Add boilerplate from Google AI Studio</p><p>Get the initial code from <a href="https://aistudio.google.com/app/prompts/new_chat">Google AI Studio</a>, then click <strong>Get Code</strong> and copy the code for the Node.js and paste it into a file called as <code>index.js</code></p><p>!<a href="https://static.devarshi.dev/blog/HLS-HowToCreateAIChatBotWithGemini/aistudio-boilerplate.png">aistudio-boilerplate</a></p><p>Also, make sure to generate an API key from the AI Studio. Select your Google Cloud project and click <strong>Create</strong></p><p>!<a href="https://static.devarshi.dev/blog/HLS-HowToCreateAIChatBotWithGemini/api-key.png">api-key</a></p><p>#### 3. Install Dependencies:</p><p>Now, We'll install the required dependencies of our project.</p><pre><code class="language-">npm install @google/generative-ai ora chalk prompt-sync<br/></code></pre><p>The packages are used for the following:</p><p>1. <code>@google/generative-ai</code>: Google's package for generative AI tasks like text and image generation.<br/>2. <code>ora</code>: Creates loading spinners and progress bars in the terminal.<br/>3. <code>chalk</code>: Styles text in the terminal with colors and styles.<br/>4. <code>prompt-sync</code>: Allows synchronous user input prompts in Node.js applications.</p><p>#### 4. Create a chatbot and customize it</p><p>In the initial version of our chatbot script, we relied on CommonJS require statements for importing modules. However, in the final iteration, we embraced ES6 import syntax for cleaner and more modern code organization.</p><p>Go to your <code>package.json</code> file and add the following line below <code>"main": "index.js",</code>:</p><pre><code class="language-json">"type": "module",<br/></code></pre><p>It should look something like this (Top section only):</p><pre><code class="language-json">{<br/>  "name": "devarshishimpi-google-gemini-nodejs-chatbot",<br/>  "version": "1.0.0",<br/>  "description": "Simple Google Gemini ChatBot for Nodejs",<br/>  "main": "index.js",<br/>  "type": "module",<br/>  "scripts": {<br/>    "test": "echo \"Error: no test specified\" && exit 1"<br/>  },<br/></code></pre><p>and continued...</p><p>Then, we update from using <code>const</code> to using <code>import</code></p><pre><code class="language-javascript">import {<br/>  GoogleGenerativeAI,<br/>  HarmCategory,<br/>  HarmBlockThreshold,<br/>} from "@google/generative-ai";<br/>import chalk from "chalk";<br/>import ora from "ora";<br/>import prompt from "prompt-sync";<br/></code></pre><p>One significant enhancement was the introduction of a user input mechanism using the <code>prompt-sync</code> library. This allowed users to interact with the chatbot in real-time, entering their messages directly into the console.</p><pre><code class="language-javascript">const userInput = promptSync(chalk.green("You: "));<br/></code></pre><p>Then, we customize the user interface with <code>ora</code> and <code>chalk</code> and make it more user responsive and easy to use</p><pre><code class="language-javascript">while (true) {<br/>  const userInput = promptSync(chalk.green("You: "));<br/>  if (userInput.toLowerCase() === "exit") {<br/>    console.log(chalk.yellow("Goodbye!"));<br/>    process.exit(0);<br/>  }<br/>  const result = await chat.sendMessage(userInput);<br/>  const response = result.response;<br/>  console.log(chalk.blue("AI:"), response.text());<br/>}<br/></code></pre><p>Then, we add some error handling logic to our code:</p><pre><code class="language-javascript">if (result.error) {<br/>    console.error(chalk.red('AI Error:'), result.error.message);<br/>    continue;<br/>}<br/>const response = result.response.text();<br/>console.log(chalk.blue('AI:'), response);<br/></code></pre><p>#### 5. Final Output</p><p>Please find the final code for project at, please star ⭐️ the repo if you found it useful:</p><p>Output:</p><p>We use <code>node index.js</code> to run our code. Make sure to replace <code>YOUR_API_KEY</code> with your generated API Key from Google API Studio.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-HowToCreateAIChatBotWithGemini/gemini-chatbot-output.gif">gemini-chatbot-output</a></p><h2>Conclusion</h2><p>Thank you for reading! If you found this blog post helpful, please consider sharing it with others who might benefit. Feel free to check out my other blog posts and visit my socials!</p><p>- <a href="https://devarshi.dev">Profile</a><br/>- <a href="https://linkedin.com/in/devarshi-shimpi">Linkedin</a><br/>- <a href="https://twitter.com/devarshishimpi">Twitter</a><br/>- <a href="https://youtube.com/@devarshishimpi">Youtube</a><br/>- <a href="https://devarshishimpi.hashnode.dev">Hashnode</a><br/>- <a href="https://dev.to/devarshishimpi">DEV</a></p><h3>Read more</h3><p>- <a href="https://devarshi.dev/blog/top-ten-vscode-extensions-you-need-in-twentytwentytwo">Top 10 VS CODE Extensions You Need In 2022!</a><br/>- <a href="https://devarshi.dev/blog/easiest-way-to-install-wordpress-for-beginners">Easiest Way to Install WordPress Locally for Beginners</a><br/>- <a href="https://devarshi.dev/blog/what-is-digitalocean-everything-you-need-to-know">What is DigitalOcean? - Everything You Need to Know</a><br/>]]></content:encoded>
      <link>https://devarshi.dev/blog/how-to-create-ai-chatbot-google-gemini-using-nodejs</link>
      <guid isPermaLink="true">https://devarshi.dev/blog/how-to-create-ai-chatbot-google-gemini-using-nodejs</guid>
      <pubDate>Wed, 17 Apr 2024 00:00:00 GMT</pubDate>
      <author>devarshishimpi@gmail.com (Devarshi Shimpi)</author>
      <enclosure url="https://static.devarshi.dev/blog/1600/HowToCreateAIChatBotWithGemini1600.png" type="image/png"/>
      <category>Technology</category>
      <category>Programming</category>
      <category>Development</category>
    </item>
    <item>
      <title><![CDATA[WordPress.com vs. WordPress.org The Differences & Which To Choose]]></title>
      <description><![CDATA[Are WordPress.com and WordPress.org the same? It's a question that may seem obvious, but the three letters make a huge difference]]></description>
      <content:encoded><![CDATA[<h2>Introduction</h2><p>Are WordPress.com and WordPress.org the same? It's a question that may seem obvious, but the truth is that those three little letters after the period make a huge difference and could impact the success of your website in the future.</p><p>So, what are the differences between WordPress.com and WordPress.org? Besides sharing the name 'WordPress', there are significant differences to consider when choosing the platform for your website.</p><h2>What Is The Difference Between WordPress.com and WordPress.org?</h2><p>!<a href="https://static.devarshi.dev/blog/HLS-WordpressCOMVSWordpressORGTheKeyDifferences/wordpress1.png">wordpress1</a></p><p>To make things clear, let's cover all the differences between WordPress.com and WordPress.org, starting with the fundamental difference:</p><h3>The Fundamental Difference</h3><p>WordPress.org is managed by the non-profit WordPress Foundation, and it is a self-hosted content management system. This means that you can install it anywhere and buy your own domain to set up a website. It is not only a self-hosted content management system, but it is also the world's leading content management system.</p><p>WordPress.com, on the other hand, is essentially the largest WordPress-as-a-Service (WaaS) platform owned by Automattic, the company run by WordPress co-founder, Matt Mullenweg. It is powered by the WordPress.org open-source software.</p><h3>TL;DR – WordPress.com vs. WordPress.org Differences</h3><p>In short, WordPress.com is a limited version of WordPress.org that has been simplified for a different demographic.</p><p>The main differences between the two are:</p><p><strong>WordPress.com:</strong></p><p>- Hosting is provided by WordPress.com<br/>- Limited monetization options - no advertising options other than the "official" WordPress.com advertising program<br/>- Limited plugin installation or updates on the free plan (higher-tier plans have similar limitations)<br/>- Limited choice of free themes<br/>- Limited customization options<br/>- No Google Analytics on the free plan<br/>- Upgrade required for the use of custom domains without the WordPress.com subdomain<br/>- No eCommerce features or integrated payment options on the free plan<br/>- No membership websites</p><p><strong>WordPress.org:</strong></p><p>- Requires external hosting (e.g., using a cloud provider or a shared hosting service)<br/>- More flexibility in monetization options<br/>- Unrestricted plugin installation and updates<br/>- Access to a wide range of free and premium themes<br/>- Customization options are not limited<br/>- Google Analytics and other tracking tools can be used<br/>- Ability to use custom domains<br/>- eCommerce features and integrated payment options available<br/>- Membership websites can be created</p><h3>Verdict</h3><p>While WordPress.com may have its advantages, there are more limitations compared to WordPress.org. Your decision on whether to choose WordPress.com or WordPress.org should be based on the requirements and goals of your website.</p><h3>Pricing and Cost Differences</h3><p>Budget is always one of the first things you have to figure out when you’re building something. In this case, there are big differences between the pricing and costs of WordPress.com and WordPress.org, so to help you plan your budget better, we have broken down both solutions.</p><p>WordPress.com offers four different pricing plans that can be paid annually, upfront, or monthly.</p><p>Here’s a detailed pricing breakdown for WordPress.com</p><p>!<a href="https://static.devarshi.dev/blog/HLS-WordpressCOMVSWordpressORGTheKeyDifferences/wordpress2.png">wordpress2</a></p><p>Besides these, WordPress.com does offer a free plan, and all you have to do is buy the domain. However, you will have their subdomain displayed e.g www.yourwebsite.wordpress.com.</p><p>When it comes to WordPress.org, it’s completely free to use. However, there are other costs that WordPress.org doesn’t cover, which WordPress.com covers for you.</p><p>- <strong>Hosting</strong> – You can either set up a server with a cloud provider like <a href="https://go.devarshi.dev/digitalocean-200">DigitalOcean</a>, <a href="https://www.linode.com/">Linode</a> or <a href="https://www.vultr.com/?ref=9043736">Vultr</a> or <a href="https://go.devarshi.dev/railway-free">using a shared hosting service</a><br/>- <strong>Security</strong> — Depending on your hosting, you might need some premium security features or plugins that can cost up to $250 per year.<br/>- <strong>Premium themes</strong> — there are free ones, but to get the most out of WordPress.org, you’ll probably want to go with premium themes. They usually cost up to $150 per year.<br/>- <strong>Premium plugins</strong> — another optional thing, but if you’re serious about scaling your website fast, you will probably want to go with some premium plugins like Rank Math for SEO.</p><h3>Ease of Use</h3><p>Both WordPress.com and WordPress.org have a learning curve, but the ease of use may vary depending on your level of experience and needs.</p><p>WordPress.com is designed for blogging, and its setup is more straightforward. However, it comes with limitations and fewer options for customization.</p><p>WordPress.org offers more freedom and flexibility but may require more technical expertise to set up and configure.</p><h3>Plugins</h3><p>Plugins play a crucial role in extending the functionality of your website. Here's how plugins are handled on WordPress.com and WordPress.org:</p><p>WordPress.com restricts plugin usage to the Business plan. On the free plan and lower-tier plans, you won't have the ability to install or upload plugins. This limits your control over the website's features.</p><p>With WordPress.org, you have no limitations when it comes to plugins. You can freely install and configure any plugin, whether free or premium, to customize your website.</p><h2>After Action Report – Use WordPress.org for Maximum Versatility & Control</h2><p>Although both platforms have their advantages and disadvantages, there's no question that WordPress.org is the best solution for businesses that are already established or planning significant growth.</p><p>With WordPress.org, you have complete control over your website. You can choose from a vast selection of addons and plugins to integrate various functionalities, customize themes, and have full control over your website's appearance.</p><h2>Happy Coding!!!</h2><p>Thank you for reading! If you found this blog post helpful, please consider sharing it with others who might benefit. Feel free to check out my other blog posts and visit my socials!</p><p>- <a href="https://devarshi.dev">Profile</a><br/>- <a href="https://linkedin.com/in/devarshi-shimpi">Linkedin</a><br/>- <a href="https://twitter.com/devarshishimpi">Twitter</a><br/>- <a href="https://youtube.com/@devarshishimpi">Youtube</a><br/>- <a href="https://devarshishimpi.hashnode.dev">Hashnode</a><br/>- <a href="https://dev.to/devarshishimpi">DEV</a></p><h3>Read more</h3><p>- <a href="https://devarshi.dev/blog/self-hosting-your-own-cloud-storage-on-aws-using-nextcloud">Self-Hosting Your Own Cloud Storage on AWS using NextCloud</a><br/>- <a href="https://devarshi.dev/blog/creating-your-first-droplet-digitalocean-tutorials">Creating Your First Droplet - DigitalOcean Tutorials</a><br/>- <a href="https://devarshi.dev/blog/complete-markdown-tutorial-for-beginners">Complete Markdown Tutorial for Beginners</a><br/>]]></content:encoded>
      <link>https://devarshi.dev/blog/wordpresscom-wordpressorg-the-differences-which-to-choose</link>
      <guid isPermaLink="true">https://devarshi.dev/blog/wordpresscom-wordpressorg-the-differences-which-to-choose</guid>
      <pubDate>Sat, 17 Feb 2024 00:00:00 GMT</pubDate>
      <author>devarshishimpi@gmail.com (Devarshi Shimpi)</author>
      <enclosure url="https://static.devarshi.dev/blog/1600/WordpressCOMVSWordpressORGTheKeyDifferences1600.png" type="image/png"/>
      <category>Technology</category>
      <category>Programming</category>
      <category>Development</category>
    </item>
    <item>
      <title><![CDATA[How to Install and Set Up a Ghost Blog on AWS Lightsail]]></title>
      <description><![CDATA[Welcome to this step-by-step tutorial on how to install and set up a Ghost blog on AWS Lightsail. Ghost is a popular open-source publishing platform CMS.]]></description>
      <content:encoded><![CDATA[<h2>Introduction</h2><p>Welcome to this step-by-step tutorial on how to install and set up a Ghost blog on AWS Lightsail. Ghost is a popular open-source publishing platform that is simple, lightweight, and designed specifically for bloggers. With AWS Lightsail, you can easily deploy your own Ghost blog in just a few simple steps.</p><p>Feel free to checkout the below video I made for this tutorial as well.</p><p>In this tutorial, we will walk you through the complete process of installing and configuring Ghost on an AWS Lightsail instance. By the end of this guide, you will have your own fully functional Ghost blog up and running.</p><h2>Prerequisites</h2><p>Before we begin, make sure you have the following:</p><p>- An AWS Lightsail account<br/>- Basic knowledge of AWS Lightsail and its services<br/>- A registered domain name (Optional)</p><h2>Step 1: Create an AWS Lightsail Instance</h2><p>The first step is to create an AWS Lightsail instance. Here's how you can do it:</p><p>1.Log in to your AWS Lightsail account and Click on the <strong>Create instance</strong> button.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-InstallAndSetupYourOwnBlogOnAWSLightsail/aws-lightsail.png">aws-lightsail</a></p><p>2.Select your preferred instance location, operating system, and instance plan.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-InstallAndSetupYourOwnBlogOnAWSLightsail/lightsail-create-1.png">lightsail-create-1</a></p><p>!<a href="https://static.devarshi.dev/blog/HLS-InstallAndSetupYourOwnBlogOnAWSLightsail/lightsail-create-2.png">lightsail-create-2</a></p><p>3.Click on the "Create" button to create the instance.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-InstallAndSetupYourOwnBlogOnAWSLightsail/lightsail-create-3.png">lightsail-create-3</a></p><p>Once the instance is created, note down the public IP address of your instance. We will need it later.</p><h2>Step 2: Connect to Your Lightsail Instance</h2><p>To connect to your Lightsail instance, follow these instructions:</p><p>Open your terminal or SSH client. Use the following command to connect to your instance:</p><pre><code class="language-">ssh -i path/to/your/key.pem ubuntu@your_instance_ip<br/></code></pre><p>Replace <code>path/to/your/key.pem</code> with the path to your private key file, and <code>your_instance_ip</code> with the public IP address of your instance.</p><h2>Step 3: Update Packages and Install Dependencies</h2><p>Once you are connected to your Lightsail instance, update the packages and install the necessary dependencies using the following commands:</p><pre><code class="language-">sudo su<br/></code></pre><pre><code class="language-">sudo apt update && apt upgrade -y<br/></code></pre><pre><code class="language-">sudo apt-get install nginx mysql-server -y<br/></code></pre><pre><code class="language-">sudo ufw allow 'Nginx Full'<br/></code></pre><h2>Step 4: Install Nodejs, NPM and Ghost-CLI</h2><p>Next steps is to install nodejs and npm which we'll doing using nodesource github repository:</p><pre><code class="language-">sudo apt-get install ca-certificates curl gnupg -y<br/></code></pre><pre><code class="language-">sudo mkdir -p /etc/apt/keyrings<br/></code></pre><pre><code class="language-">curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg<br/></code></pre><pre><code class="language-">NODE_MAJOR=18<br/>sudo apt-get update && sudo apt-get install nodejs -y<br/></code></pre><p>Next up, let's install Ghost-CLI package globally.</p><pre><code class="language-">sudo npm install ghost-cli@latest -g<br/></code></pre><h2>Step 5: Install and Configure Ghost</h2><p>Now it's time to install and configure Ghost on your Lightsail instance. Follow these steps:</p><h3>Create a new user with required permissions</h3><pre><code class="language-">adduser <user><br/></code></pre><pre><code class="language-">usermod -aG sudo <user><br/></code></pre><pre><code class="language-">su - <user><br/></code></pre><p>_Note: Using the user name ghost causes conflicts with the Ghost-CLI, so it’s important to use an alternative name._</p><p>_Note: replace <code><user></code> with the username of the username you want to add_</p><h3>Create a new directory, set correct permissions and navigate to it for your Ghost blog:</h3><pre><code class="language-">sudo mkdir -p /var/www/sitename<br/></code></pre><pre><code class="language-">sudo chown <user>:<user> /var/www/sitename<br/></code></pre><pre><code class="language-">sudo chmod 775 /var/www/sitename<br/></code></pre><pre><code class="language-">cd /var/www/sitename<br/></code></pre><h3>Install and Start Ghost:</h3><pre><code class="language-">ghost install<br/></code></pre><p>!<a href="https://static.devarshi.dev/blog/HLS-InstallAndSetupYourOwnBlogOnAWSLightsail/ghost-setup-1.png">ghost-setup-1</a></p><p>!<a href="https://static.devarshi.dev/blog/HLS-InstallAndSetupYourOwnBlogOnAWSLightsail/ghost-setup-2.png">ghost-setup-2</a></p><p><strong>During the installation, Ghost-CLI will ask you a series of questions. Provide the following answers:</strong></p><p>- Blog URL: Enter your domain name (e.g., <code>https://your_domain.com</code>).<br/>- MySQL hostname: Press Enter to use the default value (<code>localhost</code>).<br/>- MySQL username / password: Enter the MySQL username and password you want to use for your Ghost blog.<br/>- Ghost database name: Enter the name for your Ghost database. You can use the default value.<br/>- Set up a Ghost MySQL user? (Recommended): Choose "Yes" to create a custom MySQL user for Ghost.<br/>- Set up NGINX? (Recommended): Choose "Yes" to automatically set up NGINX for your Ghost blog.<br/>- Set up SSL? (Recommended): Choose "Yes" if you have an SSL certificate for your domain. Otherwise, choose "No".<br/>- Set up systemd? (Recommended): Choose "Yes" to use systemd as the process manager for Ghost.</p><h2>Step 6: Access Your Ghost Blog</h2><p>To access your Ghost blog, open a web browser and enter your domain name (e.g., <code>https://your_domain.com</code>). You should see the Ghost setup page, where you can create your admin account and customize your blog.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-InstallAndSetupYourOwnBlogOnAWSLightsail/ghost-preview-blog.png">ghost-preview-blog</a></p><h2>Conclusion</h2><p>Congratulations! Your Ghost blog is now up and running on your AWS Lightsail instance.</p><p>Feel free to checkout the below video I made for this tutorial as well.</p><p>Now it's time to start creating and publishing your own content on your brand new Ghost blog. Happy blogging! Feel free to check out my other blog posts and visit my socials!</p><p>- <a href="https://devarshi.dev">Profile</a><br/>- <a href="https://linkedin.com/in/devarshi-shimpi">Linkedin</a><br/>- <a href="https://twitter.com/devarshishimpi">Twitter</a><br/>- <a href="https://youtube.com/@devarshishimpi">Youtube</a><br/>- <a href="https://devarshishimpi.hashnode.dev">Hashnode</a><br/>- <a href="https://dev.to/devarshishimpi">DEV</a></p><h3>Read more</h3><p>- <a href="https://devarshi.dev/blog/creating-your-first-droplet-digitalocean-tutorials">Creating Your First Droplet - DigitalOcean Tutorials</a><br/>- <a href="https://devarshi.dev/blog/top-ten-vscode-extensions-you-need-in-twentytwentytwo">Top 10 VS CODE Extensions You Need In 2022!</a><br/>- <a href="https://devarshi.dev/blog/setting-up-an-ubuntu-ec2-instance-from-scratch-on-aws">Setting Up An Ubuntu EC2 Instance From Scratch on AWS</a><br/>]]></content:encoded>
      <link>https://devarshi.dev/blog/how-to-install-and-setup-a-ghost-blog-on-aws-lightsail</link>
      <guid isPermaLink="true">https://devarshi.dev/blog/how-to-install-and-setup-a-ghost-blog-on-aws-lightsail</guid>
      <pubDate>Sat, 21 Oct 2023 00:00:00 GMT</pubDate>
      <author>devarshishimpi@gmail.com (Devarshi Shimpi)</author>
      <enclosure url="https://static.devarshi.dev/blog/1600/InstallAndSetupYourOwnBlogOnAWSLightsail1600.png" type="image/png"/>
      <category>Technology</category>
      <category>Programming</category>
      <category>Development</category>
    </item>
    <item>
      <title><![CDATA[Creating Your First Droplet - DigitalOcean Tutorials]]></title>
      <description><![CDATA[Welcome to another exciting tutorial on DigitalOcean! Today, we are going to dive deeper into the concept of a droplet.]]></description>
      <content:encoded><![CDATA[<h2>Introduction</h2><p>In the previous <a href="https://devarshi.dev/blog/what-is-digitalocean-everything-you-need-to-know">tutorial</a> we discussed the basics of DigitalOcean and how to get started with the platform. In this tutorial, we will explore the process of creating your first droplet on DigitalOcean.</p><p>Feel free to checkout the below video I made for this tutorial as well.</p><h2>But what exactly is a droplet?</h2><p>To understand a droplet, let's start with some internet magic. When you enter a web address like <code>google.com</code> in your browser, your computer and operating system work behind the scenes to translate that address into something called an <strong>IP address</strong>. You can actually see the IP address your computer used by navigating to a tool like <a href="https://tools.keycdn.com/geo">KeyCDN IP Location finder</a>.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-CreatingYourOwnDroplet-DigitalOceanTutorials/google-homepage.png">google-homepage</a></p><p><strong>An IP address</strong> is associated with a computer somewhere on our planet. It represents the computer that sends you all the web content you see on your screen. For example, when you visit Google's homepage, that IP address is responsible for delivering all the HTML elements to your browser.</p><h3>If you are considering hosting your own website, here are the basics:</h3><p>1.  Get yourself a computer _you probably already have one_.<br/>2.  Obtain a public IP address for your computer, which connects it to the internet.<br/>3.  Optionally, register a domain name _like google.com_ for easy access.<br/>4.  Configure your computer to respond to requests, similar to how Google does it.</p><p>Now, here comes the interesting part. DigitalOcean helps you skip the first two steps altogether. When you create a droplet on DigitalOcean, you essentially get a virtual computer located anywhere in the world, complete with its own unique IP address.</p><p>In other words, a droplet is like your personal virtual computer that is ready to serve your web content to the world. It saves you the hassle of setting up physical hardware and obtaining a public IP address.</p><h2>Creating a droplet with DigitalOcean</h2><p>Now that we understand the basics, let's take a look at the step-by-step process of creating a droplet on DigitalOcean using Ubuntu as the operating system.</p><p>1. Sign in to your <a href="https://go.devarshi.dev/digitalocean-200">DigitalOcean</a> account or create a new one if you don't have an account already.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-CreatingYourOwnDroplet-DigitalOceanTutorials/digitalocean-dashboard.png">digitalocean-dashboard</a></p><p>2.  Once you're logged in, navigate to the dashboard and click on the <strong>"Create"</strong> button. Choose the option to create a droplet.</p><p>3.  Select the region of the droplet you want create into. If you are just starting out! Prefer selecting the closest region to you for faster network access and less lag!</p><p>!<a href="https://static.devarshi.dev/blog/HLS-CreatingYourOwnDroplet-DigitalOceanTutorials/digitalocean-region.png">digitalocean-region</a></p><p>4.  Select the operating system you want to use, for this tutorial, we will go with Ubuntu 22.04 LTS.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-CreatingYourOwnDroplet-DigitalOceanTutorials/digitalocean-os.png">digitalocean-os</a></p><p>5.  Next, choose the plan and region that best fit your needs. We'll be going with the basic $6 plan.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-CreatingYourOwnDroplet-DigitalOceanTutorials/digitalocean-plans.png">digitalocean-plans</a></p><p>6.  You can optionally set up authentication methods such as password authentication or SSH keys. We'll going with the password authentication method for this tutorial.</p><p>7.  Finally, give it a name and click on the <strong>"Create Droplet"</strong> button to initiate the creation process.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-CreatingYourOwnDroplet-DigitalOceanTutorials/digitalocean-droplet.png">digitalocean-droplet</a></p><h2>Connecting to our newly created droplet</h2><p>After creating your droplet, you will receive the necessary information to access and manage it. To access the droplet, you can use SSH to connect to it.</p><pre><code class="language-">ssh root@<yourdropletipaddress><br/></code></pre><p>Once connected to your droplet via SSH, it is a good practice to update the packages on your server. Simply run the appropriate commands to apply updates and upgrade any outdated software.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-CreatingYourOwnDroplet-DigitalOceanTutorials/droplet-created.png">droplet-created</a></p><p>For Ubuntu, you can use the following commands:</p><pre><code class="language-">sudo apt update && sudo apt upgrade -y<br/></code></pre><p>Moreover, installing useful tools like neofetch can provide you with system information at a glance. To install neofetch, you can use the following command:</p><pre><code class="language-">sudo apt install neofetch -y<br/></code></pre><p>After successful installation, you can run the <code>neofetch</code> command to see your system's configuration details.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-CreatingYourOwnDroplet-DigitalOceanTutorials/do-neofetch.png">do-neofetch</a></p><p>Stay tuned for more DigitalOcean tutorials where we will dive deeper into other exciting features and functionalities.</p><p>In the meantime, feel free to explore the <a href="https://www.youtube.com/watch?v=T6a4OxTDc4M&list=PLHb-q3SQD4ifZ5fLtvGI69UGKh-XEDHQa">playlist</a> I have created on DigitalOcean where you can find more informative videos. Happy hosting!</p><h2>Conclusion</h2><p>By following these steps, you are now well on your way to creating your first droplet on DigitalOcean and configuring it to serve your web content. With DigitalOcean's user-friendly interface and powerful infrastructure, hosting your website becomes a seamless experience.</p><p>Feel free to checkout the below video I made for this tutorial as well.</p><p>Thank you for reading! If you found this blog post helpful, please consider sharing it with others who might benefit. Feel free to check out my other blog posts and visit my socials!</p><p>- <a href="https://devarshi.dev">Profile</a><br/>- <a href="https://linkedin.com/in/devarshi-shimpi">Linkedin</a><br/>- <a href="https://twitter.com/devarshishimpi">Twitter</a><br/>- <a href="https://youtube.com/@devarshishimpi">Youtube</a><br/>- <a href="https://devarshishimpi.hashnode.dev">Hashnode</a><br/>- <a href="https://dev.to/devarshishimpi">DEV</a></p><h3>Read more</h3><p>- <a href="https://devarshi.dev/blog/top-ten-vscode-extensions-you-need-in-twentytwentytwo">Top 10 VS CODE Extensions You Need In 2022!</a><br/>- <a href="https://devarshi.dev/blog/what-are-docker-images-and-how-to-use-them">What Are Docker Images And How To Use Them</a><br/>- <a href="https://devarshi.dev/blog/everything-you-need-to-know-about-github-copilot">Everything You Need To Know About Github Copilot!</a><br/>]]></content:encoded>
      <link>https://devarshi.dev/blog/creating-your-first-droplet-digitalocean-tutorials</link>
      <guid isPermaLink="true">https://devarshi.dev/blog/creating-your-first-droplet-digitalocean-tutorials</guid>
      <pubDate>Tue, 12 Sep 2023 00:00:00 GMT</pubDate>
      <author>devarshishimpi@gmail.com (Devarshi Shimpi)</author>
      <enclosure url="https://static.devarshi.dev/blog/1600/CreatingYourOwnDropletDigitalOceanTutorials1600.png" type="image/png"/>
      <category>Technology</category>
      <category>Programming</category>
      <category>Development</category>
    </item>
    <item>
      <title><![CDATA[Complete Markdown Tutorial for Beginners]]></title>
      <description><![CDATA[Introduction Markdown is a lightweight markup language that allows you to format plain text and in a structured way.]]></description>
      <content:encoded><![CDATA[<h2>Introduction</h2><p>Markdown is a lightweight markup language that allows you to format plain text in a structured way, making it a popular choice for creating content across various platforms. Whether you're a coding enthusiast or a novice, Markdown's simplicity and versatility can streamline your content creation process. In this comprehensive guide, we'll explore the key features of Markdown that can empower you to create visually appealing and organized documents.</p><p><strong>Feel free to checkout the below video I made for this tutorial as well.</strong></p><p><strong>Feel free to star ⭐️ the Github repo as well. Where I have added everything in a systematic order in the repository. Feel free to raise issues/PRs in the repo as well!</strong></p><h2>1. Structuring Your Content with Headings</h2><p>Headings play a crucial role in organising your content. Markdown offers six levels of headings, each indicated by an increasing number of hash symbols (#).</p><p>These headings provide hierarchy and improve readability, allowing readers to navigate your content effortlessly.</p><pre><code class="language-"><h1>Heading 1</h1><br/><h2>Heading 2</h2><br/><h3>Heading 3</h3><br/></code></pre><p>Output:</p><p>!<a href="https://static.devarshi.dev/blog/HLS-MarkdownCrashCourseForBeginners/heading-output.png">heading-output</a></p><h2>2. Showcasing Code with Code Blocks</h2><p>Markdown's ability to display code snippets in a clean and readable manner is invaluable. To display inline code, wrap it with backticks. For example:</p><pre><code class="language-"><code>This is inline code</code><br/></code></pre><p>Output:</p><p><code>This is inline code</code></p><p>To present larger code blocks, use triple backticks:</p><p>!<a href="https://static.devarshi.dev/blog/HLS-MarkdownCrashCourseForBeginners/codeblock-input.png">codeblock-input</a></p><p>Output:</p><pre><code class="language-">This is a codeblock.<br/></code></pre><h2>3. Organizing Information with Lists</h2><p>Lists are effective for presenting information in a structured manner. Markdown supports both unordered and ordered lists.</p><p>For unordered lists, use hyphens (-), plus signs (+), or asterisks (\*) followed by a space:</p><pre><code class="language-">* Item 1<br/>* Item 2<br/>* Item 3<br/></code></pre><p>Output:</p><p>- Item 1<br/>- Item 2<br/>- Item 3</p><p>Ordered lists use numbers followed by periods and spaces:</p><pre><code class="language-">1. Step 1<br/>2. Step 2<br/>3. Step 3<br/></code></pre><p>Output:</p><p>1. Step 1<br/>2. Step 2<br/>3. Step 3</p><h2>4. Interactive Content with Checkbox Task Lists</h2><p>Markdown allows you to create interactive task lists using checkboxes:</p><pre><code class="language-">- [X] Task 1<br/>- [ ] Task 2<br/></code></pre><p>Output:</p><p>!<a href="https://static.devarshi.dev/blog/HLS-MarkdownCrashCourseForBeginners/tasks-output.png">tasks-output</a></p><p>These lists are handy for tracking to-do items or tasks within your documents.</p><h2>5. Emphasis and Style with Text Formatting</h2><p>Markdown offers various text formatting options. For bold text, enclose it with double asterisks (bold text). For italic text, use single asterisks (italic text). And for strikethrough text, use double tildes (strikethrough).</p><pre><code class="language-"><strong>This is a bold text</strong></p><p><em>This is italic text</em></p><p><strong><em>This is combined of both</strong></em><br/></code></pre><p>Output:</p><p><strong>This is a bold text</strong></p><p>_This is italic text_</p><p><strong>_This is combined of both_</strong></p><h2>6. Enhancing Interaction with Links and Images</h2><p>Adding links and images enriches your content. To insert links, enclose link text in square brackets followed by the URL in parentheses:</p><pre><code class="language-"><a href="https://github.com/devarshishimpi">Visit my Github</a><br/></code></pre><p>Output:</p><p><a href="https://github.com/devarshishimpi">Visit my Github</a></p><p>For images, use an exclamation mark followed by alt text in square brackets and the image URL in parentheses:</p><pre><code class="language-">!<a href="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kmdwh9bus9lo1e2wm139.png">markdownimage</a><br/></code></pre><p>Output:</p><p>!<a href="https://static.devarshi.dev/blog/HLS-MarkdownCrashCourseForBeginners/HLS-MarkdownCrashCourseForBeginners.png">markdownimage</a><br/>￼</p><h2>7. Organizing Data with Tables</h2><p>Markdown's table syntax is excellent for tabular data:</p><pre><code class="language-">| Fruit (left) | Emoji (center) | Taste (right) |<br/>| :--- | :----: | ---: |<br/>| Mango is the king of Fruits | :mango: | Sweet and I love it |<br/>| Lemon is good for health | :lemon: | Sour, mix it in the water |<br/></code></pre><p>Output:</p><p>!<a href="https://static.devarshi.dev/blog/HLS-MarkdownCrashCourseForBeginners/output-table.png">output-table</a></p><h2>8. Separating Sections with Horizontal Lines</h2><p>Horizontal lines help divide your content into distinct sections, enhancing readability:</p><pre><code class="language-">---<br/></code></pre><p>Output:</p><p>!<a href="https://static.devarshi.dev/blog/HLS-MarkdownCrashCourseForBeginners/line-output.png">line-output</a></p><h2>9. Custom Formatting with HTML in Markdown</h2><p>Markdown's flexibility is further extended by allowing HTML tags for advanced formatting. For instance, you can align content using HTML attributes like align:</p><pre><code class="language-"><p align="center"><br/>Yes, you can use allowed raw HTML in a Markdown file. This is a paragraph aligned in the center.<br/><br/></code></pre><p>Output:</p><p>!<a href="https://static.devarshi.dev/blog/HLS-MarkdownCrashCourseForBeginners/html-md.png">html-md</a></p><h2>10. Embedding YouTube Videos for Dynamic Content</h2><p>You can embed YouTube videos directly into Markdown:</p><pre><code class="language-"><a href="./markdownyt.png"><img src="https://www.youtube.com/watch?v=jCgVc9885oQ" alt="Video</a>" /><br/></code></pre><p>Output:</p><p>This makes your content more engaging by incorporating multimedia elements.</p><h2>11. Including Mathematical Expressions for Technical Content</h2><p>For math enthusiasts, Markdown supports inline and block mathematical expressions using dollar signs ($):</p><p>Inline:</p><pre><code class="language-">$\sqrt{5}+1$<br/></code></pre><p>Block:</p><pre><code class="language-">$$\sqrt{5}+1$$<br/></code></pre><h2>14. Annotating Your Content with Comments</h2><p>Markdown supports comments that won't appear in the final output:</p><pre><code class="language-"><!-- This is a comment that won't be visible --><br/></code></pre><h2>Conclusion</h2><p>Markdown is a versatile tool that empowers you to create structured and visually appealing content. With its support for headings, code blocks, lists, formatting, links, images, tables, and interactive elements like checkboxes and drop-downs, Markdown transforms plain text into an engaging and organized document.</p><p><strong>Feel free to star ⭐️ the Github repo as well. Where I have added everything in a systematic order in the repository. Feel free to raise issues/PRs in the repo as well!</strong></p><p>Feel free to experiment with these features, and remember that practice is key to mastering Markdown. Whether you're writing a blog post, a technical document, or a simple to-do list, Markdown can be your trusty companion for content creation. Happy Markdowning!</p><p>Thank you for reading! If you found this blog post helpful, please consider sharing it with others who might benefit. Feel free to check out my other blog posts and visit my socials!</p><p>- <a href="https://devarshi.dev">Profile</a><br/>- <a href="https://linkedin.com/in/devarshi-shimpi">Linkedin</a><br/>- <a href="https://twitter.com/devarshishimpi">Twitter</a><br/>- <a href="https://youtube.com/@devarshishimpi">Youtube</a><br/>- <a href="https://devarshishimpi.hashnode.dev">Hashnode</a><br/>- <a href="https://dev.to/devarshishimpi">DEV</a></p><h3>Read more</h3><p>- <a href="https://devarshi.dev/blog/top-ten-vscode-extensions-you-need-in-twentytwentytwo">Top 10 VS CODE Extensions You Need In 2022!</a><br/>- <a href="https://devarshi.dev/blog/what-are-docker-images-and-how-to-use-them">What Are Docker Images And How To Use Them</a><br/>- <a href="https://devarshi.dev/blog/everything-you-need-to-know-about-github-copilot">Everything You Need To Know About Github Copilot!</a><br/>]]></content:encoded>
      <link>https://devarshi.dev/blog/complete-markdown-tutorial-for-beginners</link>
      <guid isPermaLink="true">https://devarshi.dev/blog/complete-markdown-tutorial-for-beginners</guid>
      <pubDate>Fri, 25 Aug 2023 00:00:00 GMT</pubDate>
      <author>devarshishimpi@gmail.com (Devarshi Shimpi)</author>
      <enclosure url="https://static.devarshi.dev/blog/1600/MarkdownCrashCourseForBeginners1600.png" type="image/png"/>
      <category>Technology</category>
      <category>Programming</category>
      <category>Development</category>
    </item>
    <item>
      <title><![CDATA[What is DigitalOcean? - Everything You Need to Know]]></title>
      <description><![CDATA[Cloud computing has become an important of the tech industry. And when it comes to cloud infrastructure providers, DigitalOcean is a name that often pops up.]]></description>
      <content:encoded><![CDATA[<h2>Introduction</h2><p>In today's digital age, cloud computing has become an integral part of the tech industry. And when it comes to cloud infrastructure providers, DigitalOcean is a name that often pops up. In this blog, we will explore DigitalOcean and what it has to offer for developers and businesses alike.</p><p>Feel free to checkout the below video I made for this tutorial as well.</p><h2>DigitalOcean: The Virtual Landlord</h2><p>DigitalOcean can be best described as a virtual landlord for your software applications. Just like you need a physical space to run your apps, databases, or other tech stuff, DigitalOcean provides the virtual computers, known as servers, that you need up in the cloud.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-WhatIsDigitalOcean-DigitalOceanTutorials/digitalocean-landingpage.png">digitalocean-landingpage</a></p><p>The beauty of DigitalOcean lies in its simplicity. They take care of the heavy lifting by owning and managing the servers, while giving you the control to customize and set things up according to your requirements. It's like renting your own tech playground!</p><h2>Flexible and Cost-Efficient</h2><p>DigitalOcean offers flexible payment options, allowing you to only pay for what you use. Similar to how you pay for electricity or water, DigitalOcean offers different plans with varying resources. These resources can be seen as the power and space your virtual playground gets.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-WhatIsDigitalOcean-DigitalOceanTutorials/digitalocean-products.png">digitalocean-products</a></p><p>The plans, which include Basic, Standard, and Premium, cater to different needs and budgets. The best part is that you are not locked into any long-term contracts. You can choose to pay monthly or even hourly, providing great flexibility.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-WhatIsDigitalOcean-DigitalOceanTutorials/digitalocean-plans.png">digitalocean-plans</a></p><p>If you're just looking to tinker or experiment, you can opt for the hourly pricing model, allowing you to pay as you go. This is particularly useful for developers and small businesses who want to test out their applications before committing to larger resources.</p><h2>DigitalOcean vs. the Competition</h2><p>While DigitalOcean is a popular choice, it is important to mention that there are other cloud infrastructure providers available, such as Google Cloud, Microsoft Azure, and AWS. Each provider has its own set of offerings and features. However, DigitalOcean stands out with its user-friendly interface and easy-to-understand pricing structure.</p><h2>Getting Started with DigitalOcean</h2><p>!<a href="https://static.devarshi.dev/blog/HLS-WhatIsDigitalOcean-DigitalOceanTutorials/digitalocean-dashboard.png">digitalocean-dashboard</a></p><p>To give DigitalOcean a try, you can sign up using the special <a href="https://go.devarshi.dev/digitalocean-200">link</a> provided. By doing so, you will receive <a href="https://go.devarshi.dev/digitalocean-200">$200 free credit</a>, allowing you to explore and experiment with the platform without any financial commitment. It's a great opportunity to dive into the world of cloud computing and experience the benefits of DigitalOcean firsthand.</p><h2>Conclusion</h2><p>DigitalOcean provides developers and businesses with a user-friendly and cost-effective platform for running their applications and services in the cloud. With its virtual playground approach, flexible payment options, and easy-to-understand interface, it has become a go-to choice for many in the tech industry.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-WhatIsDigitalOcean-DigitalOceanTutorials/digitalocean-dashboard2.png">digitalocean-dashboard2</a></p><p>So, if you're looking for a reliable cloud infrastructure provider, DigitalOcean might just be the virtual landlord you've been searching for. Sign up today using the link below and embark on your cloud computing journey with <a href="https://go.devarshi.dev/digitalocean-200">$200 free credit</a>. Get ready to take your software applications to new heights with DigitalOcean!</p><p>Thank you for reading! If you found this blog post helpful, please consider sharing it with others who might benefit. Feel free to check out my other blog posts and visit my socials!</p><p>- <a href="https://devarshi.dev">Profile</a><br/>- <a href="https://linkedin.com/in/devarshi-shimpi">Linkedin</a><br/>- <a href="https://twitter.com/devarshishimpi">Twitter</a><br/>- <a href="https://youtube.com/@devarshishimpi">Youtube</a><br/>- <a href="https://devarshishimpi.hashnode.dev">Hashnode</a><br/>- <a href="https://dev.to/devarshishimpi">DEV</a></p><h3>Read more</h3><p>- <a href="https://devarshi.dev/blog/easiest-way-to-install-wordpress-for-beginners">Easiest Way to Install WordPress Locally for Beginners</a><br/>- <a href="https://devarshi.dev/blog/complete-markdown-tutorial-for-beginners">Complete Markdown Tutorial for Beginners</a><br/>- <a href="https://devarshi.dev/blog/creating-your-first-droplet-digitalocean-tutorials">Creating Your First Droplet - DigitalOcean Tutorials</a><br/>]]></content:encoded>
      <link>https://devarshi.dev/blog/what-is-digitalocean-everything-you-need-to-know</link>
      <guid isPermaLink="true">https://devarshi.dev/blog/what-is-digitalocean-everything-you-need-to-know</guid>
      <pubDate>Wed, 16 Aug 2023 00:00:00 GMT</pubDate>
      <author>devarshishimpi@gmail.com (Devarshi Shimpi)</author>
      <enclosure url="https://static.devarshi.dev/blog/1600/WhatIsDigitalOceanDigitalOceanTutorials1600.png" type="image/png"/>
      <category>Technology</category>
      <category>Programming</category>
      <category>Development</category>
    </item>
    <item>
      <title><![CDATA[Self-Hosting Your Own Cloud Storage on AWS using NextCloud]]></title>
      <description><![CDATA[Nextcloud is a popular open-source file hosting and sharing platform that allows you to store, sync, and share your files, contacts, calendars, and more.]]></description>
      <content:encoded><![CDATA[<h2>Introduction</h2><p>Ever thought of self-hosting your own private cloud server?? Nextcloud is a popular open-source file hosting and sharing platform that allows you to store, sync, and share your files, contacts, calendars, and more. Feel free to checkout the below video I made for this tutorial as well.</p><p>In this tutorial, we will walk you through the process of self-hosting Nextcloud on AWS using EC2 and the snap package of Nextcloud.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-SelfHostingYourOwnCloudStorageOnAWSUsingNextCloud/nextcloud-landingpage.png">nextcloud-landingpage</a></p><h2>Prerequisites:</h2><p>Before getting started, you will need the following:</p><p>1. An AWS account: Sign up for an AWS account if you don't have one already.<br/>2. Basic knowledge of AWS services, particularly EC2.<br/>3. Familiarity with Linux command line and server administration.<br/>4. A domain name (optional): You can use a domain name to access your Nextcloud instance.</p><h3>Step 1: Launch an EC2 Instance:</h3><p>Log in to your AWS Management Console. Navigate to the EC2 service. Select the region closest to you.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-SelfHostingYourOwnCloudStorageOnAWSUsingNextCloud/aws-region.png">aws-region</a></p><p>Launch a new EC2 instance, choosing an appropriate Amazon Machine Image (AMI) based on your preferred Linux distribution (e.g., Ubuntu, CentOS). Select the desired instance type, storage options, and security group settings.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-SelfHostingYourOwnCloudStorageOnAWSUsingNextCloud/aws-instancesettings.png">aws-instancesettings</a></p><p>!<a href="https://static.devarshi.dev/blog/HLS-SelfHostingYourOwnCloudStorageOnAWSUsingNextCloud/aws-cloudcmd.png">aws-cloudcmd</a></p><p>Make sure to enable <strong>HTTP</strong> and <strong>HTTPS</strong> along with <strong>SSH</strong></p><p>!<a href="https://static.devarshi.dev/blog/HLS-SelfHostingYourOwnCloudStorageOnAWSUsingNextCloud/aws-network.png">aws-network</a></p><p>!<a href="https://static.devarshi.dev/blog/HLS-SelfHostingYourOwnCloudStorageOnAWSUsingNextCloud/aws-launch.png">aws-launch</a></p><p>Create or select an existing key pair to access your EC2 instance securely.<br/>Launch the instance and wait for it to be ready.</p><h3>Step 2: Connect to your EC2 Instance:</h3><p>Obtain the public IP address or public DNS of your EC2 instance from the EC2 management console or use the web console by AWS.</p><p>Open a terminal or SSH client and connect to your EC2 instance using the following command:</p><p><code>ssh -i <path_to_key_pair_file> <username>@<public_ip_or_dns></code></p><h3>Step 3: Install Nextcloud via Snap Package:</h3><p>Update and Upgrade the package lists on your EC2 instance:</p><p><code>sudo apt update && sudo apt upgrade -y</code></p><p>Install the snap package management system:</p><p><code>sudo apt install snapd</code><br/>Install Nextcloud snap package:</p><p><code>sudo snap install nextcloud</code></p><p>!<a href="https://static.devarshi.dev/blog/HLS-SelfHostingYourOwnCloudStorageOnAWSUsingNextCloud/snapd-nextcloud.png">snapd-nextcloud</a></p><p>Replace <code><username></code> with the username you want to set and replace <code><password></code> with the password you want to set. Make sure to remove <code><></code> while typing.</p><p><code>sudo nextcloud.manual-install <username> <password></code></p><p>Wait for the installation to complete. Nextcloud and its dependencies will be automatically installed.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-SelfHostingYourOwnCloudStorageOnAWSUsingNextCloud/nextcloud-snap-install.png">nextcloud-snap-install</a></p><h3>Step 4: Configure Nextcloud:</h3><p>Now set the IP address/domain name you want to use to access your NextCloud server. You will need to add trusted domains through which it can be accessed.</p><p>Replace <code><domain name></code> with the domain name/IP address you want to set. Make sure to remove <code><></code> while typing.</p><p><strong>Set Trusted Domains</strong></p><p><code>sudo nextcloud.occ config:system:set trusted domains 1 --value=<domain name></code></p><p><strong>Get Trusted Domains</strong></p><p><code>sudo nextcloud.occ config:system:get trusted domains</code></p><p>!<a href="https://static.devarshi.dev/blog/HLS-SelfHostingYourOwnCloudStorageOnAWSUsingNextCloud/nextcloud-trusted-domains.png">nextcloud-trusted-domains</a></p><h3>Step 5: Finalize NextCloud</h3><p>Open your web browser and enter the public IP address or DNS of your EC2 instance.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-SelfHostingYourOwnCloudStorageOnAWSUsingNextCloud/nextcloud-homepage-ec2.png">nextcloud-homepage-ec2</a></p><p>Complete the initial setup wizard, providing the required information such as admin username, password, and database configuration.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-SelfHostingYourOwnCloudStorageOnAWSUsingNextCloud/nextcloud-files-page.png">nextcloud-files-page</a></p><p>Customize Nextcloud settings according to your preferences, including storage location, external storage options, and encryption settings.</p><h2>Conclusion</h2><p>Congratulations! 🎉 You have successfully self-hosted Nextcloud on AWS EC2 using the snap package. With Nextcloud, you have full control over your data and can enjoy secure file hosting, sharing, and collaboration features. Enjoy the benefits of self-hosted cloud storage with Nextcloud on AWS!</p><p>Thank you for reading! If you found this blog post helpful, please consider sharing it with others who might benefit. Feel free to check out my other blog posts and visit my socials!</p><p>- <a href="https://devarshi.dev">Profile</a><br/>- <a href="https://linkedin.com/in/devarshi-shimpi">Linkedin</a><br/>- <a href="https://twitter.com/devarshishimpi">Twitter</a><br/>- <a href="https://youtube.com/@devarshishimpi">Youtube</a><br/>- <a href="https://devarshishimpi.hashnode.dev">Hashnode</a><br/>- <a href="https://dev.to/devarshishimpi">DEV</a></p><h3>Read more</h3><p>- <a href="https://devarshi.dev/blog/easiest-way-to-install-wordpress-for-beginners">Easiest Way to Install WordPress Locally for Beginners</a><br/>- <a href="https://devarshi.dev/blog/complete-markdown-tutorial-for-beginners">Complete Markdown Tutorial for Beginners</a><br/>- <a href="https://devarshi.dev/blog/creating-your-first-droplet-digitalocean-tutorials">Creating Your First Droplet - DigitalOcean Tutorials</a><br/>]]></content:encoded>
      <link>https://devarshi.dev/blog/self-hosting-your-own-cloud-storage-on-aws-using-nextcloud</link>
      <guid isPermaLink="true">https://devarshi.dev/blog/self-hosting-your-own-cloud-storage-on-aws-using-nextcloud</guid>
      <pubDate>Thu, 27 Jul 2023 00:00:00 GMT</pubDate>
      <author>devarshishimpi@gmail.com (Devarshi Shimpi)</author>
      <enclosure url="https://static.devarshi.dev/blog/1600/SelfHostingYourOwnCloudStorageOnAWSUsingNextCloud1600.png" type="image/png"/>
      <category>Technology</category>
      <category>Programming</category>
      <category>Development</category>
    </item>
    <item>
      <title><![CDATA[Setting Up An Ubuntu EC2 Instance From Scratch on AWS]]></title>
      <description><![CDATA[We will be setting up an Ubuntu EC2 instance from scratch on AWS. Amazon EC2 is a web service that provides scalable and inexpensive compute power in the cloud]]></description>
      <content:encoded><![CDATA[<h2>Introduction</h2><p>In this article, we will be setting up an Ubuntu EC2 instance from scratch on AWS. Amazon EC2 is a web service that provides scalable and inexpensive compute power in the cloud. Feel free to checkout the below video I made for this tutorial as well.</p><h2>Steps To Create Ubuntu Instance on AWS</h2><p>Amazon EC2 makes it easy to set up a virtual machine (VM) running Ubuntu on AWS.</p><h3>Selecting AWS Region</h3><p>To create a Ubuntu instance on AWS, you first need to select an EC2 region. In this tutorial we will be using the <strong>ap-south-1</strong> region as it has low latency and availability for us.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-SettingUpUbuntuEC2InstanceOnAWS/aws-region.png">aws-region</a></p><h3>Configuring Our AWS Instance</h3><p>Now you'll need to name your AWS Instance and select the Operating System(OS) to run on your AWS Instance. For this tutorial, we'll be going with the <strong>Ubuntu 22.04 LTS</strong> Version which is also part of the AWS Free Tier.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-SettingUpUbuntuEC2InstanceOnAWS/aws-instance-name.png">aws-instance-name</a></p><p>!<a href="https://static.devarshi.dev/blog/HLS-SettingUpUbuntuEC2InstanceOnAWS/aws-instance-os.png">aws-instance-os</a></p><p>Now, You need to choose an <strong>instance type</strong> and <strong>instance size</strong>. You will have to choose how many CPUs and how much memory you want for your Ubuntu instance. You can also change this later on but it is not recommended unless you know what you are doing. I am going with the <code>t2.micro</code> instance size for this tutorial.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-SettingUpUbuntuEC2InstanceOnAWS/aws-instance-size.png">aws-instance-size</a></p><p>Now you will be prompted to assign a key pair to access your instance.<br/>Select <strong>Create A New Key Pair</strong>.<br/>Enter a name to your key.<br/>Click Create.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-SettingUpUbuntuEC2InstanceOnAWS/aws-keypair-1.png">aws-keypair-1</a></p><p>!<a href="https://static.devarshi.dev/blog/HLS-SettingUpUbuntuEC2InstanceOnAWS/aws-keypair-2.png">aws-keypair-2</a></p><p>_Important: Save the key pair, if you miss this key you wont be able to access your instance using SSH._</p><p>Now select the <strong>Disk Size</strong> you want, you can choose different disk type as well and select tags for your instance.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-SettingUpUbuntuEC2InstanceOnAWS/aws-instance-disk.png">aws-instance-disk</a></p><p>Then click on "launch" button and wait until it connects with AWS servers in few minutes. After that your Ubuntu EC2 Instance is ready!</p><p>!<a href="https://static.devarshi.dev/blog/HLS-SettingUpUbuntuEC2InstanceOnAWS/aws-instance-launch.png">aws-instance-launch</a></p><p>Let it setup itself, takes approx few seconds to minutes.<br/>It should show <strong>Pending</strong> and once it's ready, it's state should change to <strong>Running</strong></p><p>!<a href="https://static.devarshi.dev/blog/HLS-SettingUpUbuntuEC2InstanceOnAWS/aws-launch-pending.png">aws-launch-pending</a></p><p>!<a href="https://static.devarshi.dev/blog/HLS-SettingUpUbuntuEC2InstanceOnAWS/aws-launch-running.png">aws-launch-running</a></p><h3>Connecting to our AWS Instance</h3><p>Now we'll head to the instance details and click on <strong>Connect</strong>. Ideally you would want to use <code>ssh</code> to connect to your EC2 instance but for this tutorial, we'll be using the WebUI. The default username is <code>ubuntu</code> so click Connect.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-SettingUpUbuntuEC2InstanceOnAWS/aws-connect.png">aws-connect</a></p><p>YAY!!🥳 And there's our welcome message to Ubuntu which is running on AWS.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-SettingUpUbuntuEC2InstanceOnAWS/aws-welcome.png">aws-welcome</a></p><h3>Extra</h3><p>Now we'll install neofetch and check system configuration of the virtual machine. Run the following commands.</p><p><code>sudo apt update</code></p><p><code>sudo apt upgrade -y</code></p><p><code>sudo apt install neofetch -y</code></p><p>And there you go! Now it shows up our virtual machine specification in the terminal and in friendly design-style.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-SettingUpUbuntuEC2InstanceOnAWS/aws-neofetch.png">aws-neofetch</a></p><h2>Conclusion</h2><p>Setting up an Ubuntu EC2 instance from scratch on AWS is a fun little project. It's relatively easy, and it gives you an opportunity to learn some more about AWS and the command line.</p><p>Thank you for reading! If you found this blog post helpful, please consider sharing it with others who might benefit. Feel free to check out my other blog posts and visit my socials!</p><p>- <a href="https://devarshi.dev">Profile</a><br/>- <a href="https://linkedin.com/in/devarshi-shimpi">Linkedin</a><br/>- <a href="https://twitter.com/devarshishimpi">Twitter</a><br/>- <a href="https://youtube.com/@devarshishimpi">Youtube</a><br/>- <a href="https://devarshishimpi.hashnode.dev">Hashnode</a><br/>- <a href="https://dev.to/devarshishimpi">DEV</a></p><h3>Read more</h3><p>- <a href="https://devarshi.dev/blog/self-hosting-your-own-cloud-storage-on-aws-using-nextcloud">Self-Hosting Your Own Cloud Storage on AWS using NextCloud</a><br/>- <a href="https://devarshi.dev/blog/creating-your-first-droplet-digitalocean-tutorials">Creating Your First Droplet - DigitalOcean Tutorials</a><br/>- <a href="https://devarshi.dev/blog/complete-markdown-tutorial-for-beginners">Complete Markdown Tutorial for Beginners</a><br/>]]></content:encoded>
      <link>https://devarshi.dev/blog/setting-up-an-ubuntu-ec2-instance-from-scratch-on-aws</link>
      <guid isPermaLink="true">https://devarshi.dev/blog/setting-up-an-ubuntu-ec2-instance-from-scratch-on-aws</guid>
      <pubDate>Thu, 06 Jul 2023 00:00:00 GMT</pubDate>
      <author>devarshishimpi@gmail.com (Devarshi Shimpi)</author>
      <enclosure url="https://static.devarshi.dev/blog/1600/SettingUpUbuntuEC2InstanceOnAWS1600.png" type="image/png"/>
      <category>Technology</category>
      <category>Programming</category>
      <category>Development</category>
    </item>
    <item>
      <title><![CDATA[What Are Docker Images And How To Use Them]]></title>
      <description><![CDATA[A Docker image is simply a read-only file thats used to run code within a Docker container. Containerising is the way to go with it's performance!]]></description>
      <content:encoded><![CDATA[<p>A Docker image is simply a read-only file that’s used to run code within a Docker container. Think of it as a template that contains all the instructions needed to run the code. All of the code and dependencies are packaged in one file.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-WhatAreDockerImagesAndHowToUseThem/homepagedocker.png">homepagedocker</a></p><p>The Docker image contains all of the tools, packages, libraries, and source code required to run the software. These instructions can be used to build Docker containers, often containing multiple layers, with each one originating from the previous layer.</p><p>Docker images can be deployed on any host, and they are reusable, allowing developers to take images from one project and use them in another, saving them considerable time and effort.</p><h2>Docker Images vs. Containers</h2><p>Before we proceed further, it’s important to understand the differences between a Docker image and a container. A container is a self-contained space that lets you run an application.</p><p>Docker containers are completely isolated, so they don’t affect the system, and the environment they run in can’t affect the software either. A Docker image, on the other hand, runs the code within a container.</p><p>A Docker image can exist outside of a container, but a container will need to execute an image for it to have something to “contain”. Therefore, a container is fully dependent on a Docker image to execute an application.</p><p>Think of an image as a template, so while it can exist independently, you can’t execute it. It’s important to mention that a container is just an executed image. As you build a container, it automatically creates another layer on top of the image, letting you modify the container layer (images are read-only).</p><p>This also means that with the help of a single image base, you can easily create multiple Docker images. Over time, you’ll have images that contain different layers, with each iteration slightly similar to the previous one.</p><p><strong>How to Build Docker Images</strong></p><p>Primarily, Dockerfiles are used to build Docker images. Dockerfiles contain the commands you need to build and customize Docker images. Every instruction you execute with Dockerfiles creates an intermediate layer.</p><p>To create a Docker image, your first step would be to create a Dockerfile. Docker uses the Dockerfile to build images, so all instructions must be stored there. It’s a simple text file where you can add all the commands needed to create an image.</p><p>To write one, you can use the simple Express application generator. Creating a basic Node.js app is a good way to start. Express application generator is a CLI (command-line interface) that lets you create basic app skeletons.</p><p>If you’re on Linux, just fire up the Terminal, and install the generator using the following commands:</p><pre><code class="language-">$ npm install express-generator -g<br/>$ express docker-app<br/>$ npm install<br/>$ npm start<br/></code></pre><p>Once installed, head to the root directory (where you saved the application) and create a simple text file. You can name it whatever you want, but let’s go with “Dockerfile”.</p><p>Now, to create an image using this file, run the following commands:</p><pre><code class="language-"><h1>Filename: Dockerfile</h1><br/>FROM node:14-alpine<br/>WORKDIR /usr/src/app<br/>COPY package*.json ./<br/>RUN npm install<br/>COPY . .<br/>$ docker build .<br/></code></pre><p>Docker will now build the image. To check whether the image was created, you can run the docker images command.</p><p>Once you build a Dockerfile, you don’t need to rebuild an image manually. The table below contains the basic Dockerfile commands you need to build images.</p><h2>Few Commands Functions</h2><p>- FROM Specifies the base image.<br/>- RUN Specifies the shell command you want to execute in your image.<br/>- COPY Used to import external files from a specified location.<br/>- ENV Used to define environment variables.<br/>- EXPOSE Defines the port to access your container application.<br/>- LABEL Used to describe your image.<br/>- CMD Used to execute a specific command within a container.</p><p>To build Docker images from Dockerfiles, follow these steps:</p><p>- Create your Dockerfiles: Here, you need to create a new file and directory for your Docker image.<br/>- Run <a href="https://docs.docker.com/engine/reference/commandline/build/">Docker build</a> to build your Docker image. The <code>build</code> command uses instructions from specific files in a directory to build a Docker image.<br/>- After creating the Docker image, use the <code>Docker run</code> command to create your container.</p><p>Alternatively, you can use the interactive method to manually build Docker images from preexisting images. To do this, follow these steps:</p><p>- Open a terminal session after installing Docker.<br/>- Use the <strong>Docker run</strong> command <strong>image_name:tag_name</strong> to start an interactive shell session with the container specified by the command. But there’s a caveat: Docker will automatically pull the most recent image version if you omit the tag name. If the images aren’t on any local file, Docker will build the container using resources from the Docker hub.</p><p>And, if you want to run your Docker image, you can use the following command:</p><pre><code class="language-">docker run -i -t Dockerfile /bin/bash<br/></code></pre><p>You can replace the name with that of your image if you’ve renamed it.</p><h2>How to Maximize Docker Image Security</h2><p>The images that you use to build the container obviously play an important role in ensuring the overall safety of the container itself. In case the image is infected, the container will be too.</p><p>It’s important to take certain security precautions when using Docker images. Here are some key points to keep in mind.</p><h3>Only Use Verified and Signed Images</h3><p>There are numerous third-party image repositories available, but ideally, you should steer clear of them. Instead, always use verified images from the Docker Hub to maintain project integrity.</p><p>Furthermore, it’s important that you only use signed images to mitigate your risk. In case someone tampered with the image, you’ll know right away.</p><h3>Use Minimal Images with No Unnecessary Libraries</h3><p>Instead of using images that have several layers and contain various components that you won’t need, try to avoid downloading images that install additional system libraries that you won’t require. This can help you reduce your overall exposure.</p><h3>Define a Privileged User</h3><p>It’s important that you specify a USER for each Dockerfile. If you don’t, the container will run with root privileges on the host machine. That exposes your container to severe security issues and can lead to hackers eventually hacking into the host machine.</p><h3>Regularly Check Images for Vulnerabilities</h3><p>It’s important to note that vulnerabilities might be introduced as you continue to build new layers. While you may have checked the image originally, and verified it, make it a habit to check it regularly to identify issues and fix them at the earliest.</p><h2>Happy Coding!!!</h2><p>Thank you for reading! If you found this blog post helpful, please consider sharing it with others who might benefit. Feel free to check out my other blog posts and visit my socials!</p><p>- <a href="https://devarshi.dev">Profile</a><br/>- <a href="https://linkedin.com/in/devarshi-shimpi">Linkedin</a><br/>- <a href="https://twitter.com/devarshishimpi">Twitter</a><br/>- <a href="https://youtube.com/@devarshishimpi">Youtube</a><br/>- <a href="https://devarshishimpi.hashnode.dev">Hashnode</a><br/>- <a href="https://dev.to/devarshishimpi">DEV</a></p><h3>Read more</h3><p>- <a href="https://devarshi.dev/blog/self-hosting-your-own-cloud-storage-on-aws-using-nextcloud">Self-Hosting Your Own Cloud Storage on AWS using NextCloud</a><br/>- <a href="https://devarshi.dev/blog/creating-your-first-droplet-digitalocean-tutorials">Creating Your First Droplet - DigitalOcean Tutorials</a><br/>- <a href="https://devarshi.dev/blog/complete-markdown-tutorial-for-beginners">Complete Markdown Tutorial for Beginners</a><br/>]]></content:encoded>
      <link>https://devarshi.dev/blog/what-are-docker-images-and-how-to-use-them</link>
      <guid isPermaLink="true">https://devarshi.dev/blog/what-are-docker-images-and-how-to-use-them</guid>
      <pubDate>Fri, 16 Sep 2022 00:00:00 GMT</pubDate>
      <author>devarshishimpi@gmail.com (Devarshi Shimpi)</author>
      <enclosure url="https://static.devarshi.dev/blog/1600/WhatAreDockerImagesAndHowToUseThem1600.png" type="image/png"/>
      <category>Technology</category>
      <category>Programming</category>
      <category>Development</category>
    </item>
    <item>
      <title><![CDATA[Easiest Way to Install WordPress Locally for Beginners]]></title>
      <description><![CDATA[Are you a beginner whos tired of using Apache server to learn and install WordPress locally? Setting up server on your local system can be daunting.]]></description>
      <content:encoded><![CDATA[<p>Are you a beginner who’s tired of using Apache server to learn and install WordPress locally? Beginner or a pro, setting up server on your local system can be daunting! Hence it’s time you know about this awesome tool to ease and speed up your learning process; Enter: Local by Flywheel!</p><h2>What is Local?</h2><p><a href="https://localwp.com">Local</a> is a (free) tool to install WordPress locally, without the hassle of setting things up yourself! As a beginner (or even a pro-developer), your primary focus should be on learning to use or develop for WordPress, and Local helps you do just that.</p><p>Need a new development site? Local can create one instantly!<br/>Need a multisite network? Once again, Local can help in a couple of clicks!</p><p>Want to temporarily share a link to your local site on the internet? Local’s Live Link feature can solve that!<br/>Wanna compress images without the hassle of paid plugins? Local provides an inbuilt feature for optimizing your media!<br/>And what’s more? We have only scratched the surface!</p><h2>How to Download Local?</h2><p>You can download Local from <a href="https://localwp.com">localwp.com</a> and it free for everyone, forever.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-EasiestWayToInstallWordpressLocallyForBeginners/localwp.png">localwp</a></p><p>Click on <strong>Download For Free</strong>, then choose your platform\*, fill in the form (only the email ID is enough, you can skip other fields) and finally click on <strong>GET IT NOW</strong>.</p><p>_\*Local is currently available for Windows, Mac and Ubuntu/Debian._</p><h2>How to Install WordPress Locally?</h2><p>Installed Local? Great, now let’s use it to install WordPress locally (no pun intended) and create our first development/learning-site. Keep in mind that you can create and activate multiple sites local sites because they are created in different environment (don’t worry if you are confused as a newcomer, just keep in mind that Local makes it easy to have multiple sites on the same system).</p><p>When you first start Local, agree to their Terms and Conditions and skip through the screen which asks you to create an account, as shown above.</p><p>Now, simply follow the instructions below to get started:</p><h3>1. Create A Site</h3><p>!<a href="https://static.devarshi.dev/blog/HLS-EasiestWayToInstallWordpressLocallyForBeginners/createsite-2.png">createsite-1</a></p><p>Either click on <strong>Create a New Site</strong> button or the plus icon on the bottom-left.</p><h3>2. Name Your Site</h3><p>!<a href="https://static.devarshi.dev/blog/HLS-EasiestWayToInstallWordpressLocallyForBeginners/createsite-2.png">createsite-2</a></p><p>Give a cool name to your Local site. As you can see, I’ve chosen the coolest name ever: <strong>mylocalsetup</strong>. By default, the site link will look like _https://site-title.local_ (in this case: _https://mylocalsetup.local_). Hit continue.</p><h3>3. Choose Your Environment</h3><p>!<a href="https://static.devarshi.dev/blog/HLS-EasiestWayToInstallWordpressLocallyForBeginners/choose.png">choose</a></p><p>Continue with the preferred environment unless you need a specific version of PHP, web server or MySQL.</p><h3>4. Set WordPress Admin’s Username and Password</h3><p>!<a href="https://static.devarshi.dev/blog/HLS-EasiestWayToInstallWordpressLocallyForBeginners/username.png">username</a></p><p>Set the credentials for admin username and password. For the WordPress email field, you can go with the default one. After you are done, click on <strong>Add Site</strong>.</p><p>Local will now provision the necessary resources and download WordPress for you. Wait for a couple of minutes and…</p><h2>BOOM, You Now Have a Local WordPress Site!</h2><p>!<a href="https://static.devarshi.dev/blog/HLS-EasiestWayToInstallWordpressLocallyForBeginners/livesite.png">livesite</a></p><p>The WordPress site is now active on your system! You can access it via the link (_https://site-name.local_) or check Local’s site panel to open the site, or visit it’s Admin Dashboard using your given credentials.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-EasiestWayToInstallWordpressLocallyForBeginners/final.png">final</a></p><p>After you are done, you can stop the site and enable it again as needed.</p><h2>Happy Coding!!!</h2><p>Thank you for reading! If you found this blog post helpful, please consider sharing it with others who might benefit. Feel free to check out my other blog posts and visit my socials!</p><p>- <a href="https://devarshi.dev">Profile</a><br/>- <a href="https://linkedin.com/in/devarshi-shimpi">Linkedin</a><br/>- <a href="https://twitter.com/devarshishimpi">Twitter</a><br/>- <a href="https://youtube.com/@devarshishimpi">Youtube</a><br/>- <a href="https://devarshishimpi.hashnode.dev">Hashnode</a><br/>- <a href="https://dev.to/devarshishimpi">DEV</a></p><h3>Read more</h3><p>- <a href="https://devarshi.dev/blog/top-ten-vscode-extensions-you-need-in-twentytwentytwo">Top 10 VS CODE Extensions You Need In 2022!</a><br/>- <a href="https://devarshi.dev/blog/complete-markdown-tutorial-for-beginners">Complete Markdown Tutorial for Beginners</a><br/>- <a href="https://devarshi.dev/blog/everything-you-need-to-know-about-github-copilot">Everything You Need To Know About Github Copilot!</a><br/>]]></content:encoded>
      <link>https://devarshi.dev/blog/easiest-way-to-install-wordpress-for-beginners</link>
      <guid isPermaLink="true">https://devarshi.dev/blog/easiest-way-to-install-wordpress-for-beginners</guid>
      <pubDate>Tue, 06 Sep 2022 00:00:00 GMT</pubDate>
      <author>devarshishimpi@gmail.com (Devarshi Shimpi)</author>
      <enclosure url="https://static.devarshi.dev/blog/1600/EasiestWayToInstallWordpressLocallyForBeginners1600.png" type="image/png"/>
      <category>Technology</category>
      <category>Programming</category>
      <category>Development</category>
    </item>
    <item>
      <title><![CDATA[How Fast Is Bun.sh (JS Runtime) After All?]]></title>
      <description><![CDATA[Bun is the ultra fast JavaScript runtime that is set to dominate the JavaScript development market in the coming years with it's speed.]]></description>
      <content:encoded><![CDATA[<p>Bun is the ultra fast JavaScript runtime that has taken the internet by storm and that is set to dominate the JavaScript development market in the coming years. At least that's what people are saying online. But whether there's any truth to that, is another story.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-HowFastIsBunShAfterAll/bunhomepage.png">bunhomepage</a></p><h2>What is a JavaScript engine?</h2><p>Before we get into Bun directly, let's get into what a JS engine actually is and does.</p><p>For as long as developers can remember, JavaScript was mainly confined to running inside of a web browser.</p><p>And to do so, it needs some kind of engine to parse the JavaScript and to turn it into a functional application that users can interact with and see.<br/>Welcome to JavaScript engines.</p><p>There is a good chance that you have at least heard of 1 popular JavaScript engine, that being the V8 engine created by Google and intended for use on Chrome. It is also the engine used by Node.js currently.<br/>It's popular and for good reason. It's well maintained and it is backed by Google. Two big reasons. But there are a few competitors that it needs to contend with.</p><p>SpiderMonkey is the JavaScript engine that Mozilla uses for its FireFox browsers, which also implements WebAssembly as well.</p><p>And JavaScriptCore is the engine created by Apple for it's Safari browser. And JavaScriptCore is fast. Typically faster than the other 2.</p><p>You can see a pattern here. Essentially, every major browser currently on the market had to create its own JavaScript engine. But in some cases, they might use an existing engine such as Opera, which uses V8 internally.</p><h2>What is a runtime?</h2><p>And a runtime, is essentially where a program is executed on your machine, using one of these engines.</p><p>Node.js and Deno are currently the dominant forces in that area, both using the V8 engine from Google and both created (and co-created) by Ryan Dahl.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-HowFastIsBunShAfterAll/bunfast.png">bunfast</a></p><h2>What is Bun?</h2><p>Bun is a JavaScript runtime, much like Node.js and Deno, that is built from the ground up to focus on speed and overall performance and if the benchmarks are true, then it pretty dominates over its competitors. And it comes out of the box with plenty of features (down below) that can definitely replace your current JavaScript engine implementations.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-HowFastIsBunShAfterAll/bungraph.png">bungraph</a></p><p>Bun implements hundreds of Node.js and Web API's and it supports fs, path and Buffer as well. You can currently install Bun on MacOS x64, Linux x64 or Windows Subsystem for Linux (WSL).</p><p>You can check out <a href="https://github.com/oven-sh/bun">Bun's GitHub repository</a> for the official source.</p><p>But let's get into the features that really make Bun standout above the rest, because there's quite a few.</p><h2>Features</h2><p>!<a href="https://static.devarshi.dev/blog/HLS-HowFastIsBunShAfterAll/featuresgif.gif">featuresgif</a></p><p>Bun currently supports Web API's, such as <code>fetch</code>, <code>WebSocket</code> and <code>ReadableStream</code>. And from the sounds of it, it looks like it will be able to support any new API's added in the future.<br/>Bun also transpiles every file, meaning that TypeScript and JSX work out of the box without requiring any extra dependencies.</p><p>Bun also automatically loads environment variables from any <code>.env</code> files with needing any extra requires or imports. Meaning overall less overhead when it comes to setting up a new project.</p><p>And currently, Bun implements around 90% of Node API functions, again, meaning that incorporating the new runtime into your projects will be a near seamless process.</p><p>And lastly, though not least, Bun also comes packaged with a SQLite3 client, bun:sqlite. And based on the queries per second that it can perform, it is several times faster than some of its competitors, such as better-sqlite3 or deno.</p><p>So in a sense, Bun is a feature-rich, built from scratch, and high performing JavaScript runtime with vital components built right into the engine from the start.</p><h2>Will it replace Node.js?</h2><p>Personally, I love what I see being done here with Bun. The performance first approach will become vital in the coming years as applications get more and more complex and as data sets get larger and larger.</p><p>But it still has a long way to go before it can play with the big players. For one, most vendors currently do not support Bun as an official runtime.</p><p>More notable though, is that Bun is still very young and it isn't done implementing all current Node.js API's. And once it has done so, we still have to see if it performs equally as well. Because what Node.js and Deno have going for them is that they have been around for a while now, so plenty of bugs have come to light and have been fixed.</p><h2>Happy Coding!!!</h2><p>Thank you for reading! If you found this blog post helpful, please consider sharing it with others who might benefit. Feel free to check out my other blog posts and visit my socials!</p><p>- <a href="https://devarshi.dev">Profile</a><br/>- <a href="https://linkedin.com/in/devarshi-shimpi">Linkedin</a><br/>- <a href="https://twitter.com/devarshishimpi">Twitter</a><br/>- <a href="https://youtube.com/@devarshishimpi">Youtube</a><br/>- <a href="https://devarshishimpi.hashnode.dev">Hashnode</a><br/>- <a href="https://dev.to/devarshishimpi">DEV</a></p><h3>Read more</h3><p>- <a href="https://devarshi.dev/blog/top-ten-vscode-extensions-you-need-in-twentytwentytwo">Top 10 VS CODE Extensions You Need In 2022!</a><br/>- <a href="https://devarshi.dev/blog/complete-markdown-tutorial-for-beginners">Complete Markdown Tutorial for Beginners</a><br/>- <a href="https://devarshi.dev/blog/everything-you-need-to-know-about-github-copilot">Everything You Need To Know About Github Copilot!</a><br/>]]></content:encoded>
      <link>https://devarshi.dev/blog/how-fast-is-bunsh-after-all</link>
      <guid isPermaLink="true">https://devarshi.dev/blog/how-fast-is-bunsh-after-all</guid>
      <pubDate>Fri, 02 Sep 2022 00:00:00 GMT</pubDate>
      <author>devarshishimpi@gmail.com (Devarshi Shimpi)</author>
      <enclosure url="https://static.devarshi.dev/blog/1600/HowFastIsBunShAfterAll1600.png" type="image/png"/>
      <category>Technology</category>
      <category>Programming</category>
      <category>Development</category>
    </item>
    <item>
      <title><![CDATA[Everything You Need To Know About Github Copilot!]]></title>
      <description><![CDATA[AI has a significant impact on our daily life, but have you ever wondered of the capabilities? A great example of this becoming reality is the GitHub Copilot.]]></description>
      <content:encoded><![CDATA[<h2>Introduction</h2><p>Not so long ago, artificial intelligence was the main antagonist of Sci-Fi movies. And today, it is all around us. Almost every product that comes out of the technology world seems to have some element of artificial intelligence. AI has a significant impact on our daily life, but have you ever wondered what AI is really capable of? A great example of a futuristic vision becoming reality is the <a href="https://github.com/features/copilot">GitHub Copilot</a>.</p><p>!<a href="https://static.devarshi.dev/blog/HLS-EverythingYouNeedToKnowAboutGithubCopilot/copilot-homepage.png">copilot-homepage</a></p><h2>GitHub Copilot is super cool, but what is it?</h2><p>Copilot is a tool built into the code editor that is capable of writing code itself based on the code you’ve already written in your project. The only thing you need to do is type a function name or some comments and Copilot will automatically fill in the implementation. The tool processes the user’s input in the cloud and comes back with a snippet that you just accept, decline, or ask for further solution suggestions.</p><h2>But, What's the Price?</h2><p>GitHub Copilot licenses, which are currently only available to individual users, cost <strong>$10 per month</strong> or <strong>$100 per year</strong>. However, students enrolled in <a href="https://education.github.com/pack">GitHub's Global Campus Program</a> and maintainers of popular open source GitHub projects -- identified when a user navigates to the GitHub Copilot subscription page -- will still be able to use the tool for free.</p><h2>Can GitHub Copilot be any threat to developers?</h2><p>!<a href="https://static.devarshi.dev/blog/HLS-EverythingYouNeedToKnowAboutGithubCopilot/ai-copilot.png">ai-copilot</a></p><p>After hitting the programmer’s market, it has been widely discussed whether it is a big step toward the death of computer programming or just another autocomplete tool on steroids. Well, it still requires some serious knowledge to build software. Even with Copilot’s help, you need to know what you are doing, verify and understand generated code. It’s not possible (yet) for non-programmers to jump on Copilot and build whatever they want.</p><p><strong>The tool is not perfect</strong>. It doesn’t always generate the correct code. There are a lot of bad practices and deprecated code out there. Even worse, Copilot can write security vulnerabilities, especially in memory unsafe languages. It isn’t 100% reliable yet. You absolutely need to review Copilot’s code. This is AI. AI needs to learn. It will get better with time, but we need to wait.</p><h2>Conclusion</h2><p>Copilot is just one of many tools that improve and will keep improving our work. In fact, relying too much on tools like that might lead to unnecessary work or even serious problems.</p><p>Thank you for reading! If you found this blog post helpful, please consider sharing it with others who might benefit. Feel free to check out my other blog posts and visit my socials!</p><p>- <a href="https://devarshi.dev">Profile</a><br/>- <a href="https://linkedin.com/in/devarshi-shimpi">Linkedin</a><br/>- <a href="https://twitter.com/devarshishimpi">Twitter</a><br/>- <a href="https://youtube.com/@devarshishimpi">Youtube</a><br/>- <a href="https://devarshishimpi.hashnode.dev">Hashnode</a><br/>- <a href="https://dev.to/devarshishimpi">DEV</a></p><h3>Read more</h3><p>- <a href="https://devarshi.dev/blog/self-hosting-your-own-cloud-storage-on-aws-using-nextcloud">Self-Hosting Your Own Cloud Storage on AWS using NextCloud</a><br/>- <a href="https://devarshi.dev/blog/what-is-digitalocean-everything-you-need-to-know">What is DigitalOcean? - Everything You Need to Know</a><br/>- <a href="https://devarshi.dev/blog/how-to-install-and-setup-a-ghost-blog-on-aws-lightsail">How to Install and Set Up a Ghost Blog on AWS Lightsail</a><br/>]]></content:encoded>
      <link>https://devarshi.dev/blog/everything-you-need-to-know-about-github-copilot</link>
      <guid isPermaLink="true">https://devarshi.dev/blog/everything-you-need-to-know-about-github-copilot</guid>
      <pubDate>Thu, 01 Sep 2022 00:00:00 GMT</pubDate>
      <author>devarshishimpi@gmail.com (Devarshi Shimpi)</author>
      <enclosure url="https://static.devarshi.dev/blog/1600/EverythingYouNeedToKnowAboutGithubCopilot1600.png" type="image/png"/>
      <category>Technology</category>
      <category>Programming</category>
      <category>Development</category>
    </item>
    <item>
      <title><![CDATA[Top 10 VSCODE Extensions You Need In 2022!]]></title>
      <description><![CDATA[VS Code is a powerful, lightweight code editor. The capabilities of VS Code can be extended, and boost your productivity with the help of extensions.]]></description>
      <content:encoded><![CDATA[<h2>Introduction</h2><p>As is well-known, Visual Studio Code (VS Code) is a powerful, lightweight code editor available for free on Windows, macOS, and Linux. It’s one of the most popular code editors coming with a robust set of features out of the box. The capabilities of VS Code can be extended, which in return will enhance your working productivity in many ways.</p><p>Let’s go over the top 10 VS Code extensions and how they can make coding life easier for any web developer!</p><h2>1. <a href="https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint">ESLint</a></h2><p>!<a href="https://static.devarshi.dev/blog/HLS-Top10VSCodeExtensionsYouNeedIn2022/eslint.gif">eslint</a></p><p>As JavaScript is, in its nature, a loosely typed language, it’s more prone to errors. Each developer has their own style of writing (i.e., naming conventions or single and double quotes for a string). ESLint allows you to impose specific guidelines for developers to stay with coding standards and minimize the chances of errors. ESLint is an extension that helps you find and fix problems with your JavaScript code.</p><p>This extension aims to make your code more consistent and bug-free. It uses static analysis to identify and highlight problems within your JS code as you type. Most of the issues can be fixed automatically by ESLint, every time you save your file. You can even add your own custom rules or disable existing ones.</p><h2>2. <a href="https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode">Prettier</a></h2><p>!<a href="https://static.devarshi.dev/blog/HLS-Top10VSCodeExtensionsYouNeedIn2022/prettier.gif">prettier</a></p><p>In addition to ESLint, you can use Prettier to format your files when saving them or committing them to a version control system. It formats your source code for you, so you don’t have to worry about it. You can use the extension for personal projects and when working in a team with other developers.</p><p>It helps you enforce consistent styling across the whole codebase, maintaining proper alignment and giving spaces between the words in the code, enhancing the overall readability and maintainability of both small and large code. Developers looking at the code will effortlessly understand the logic and structure.</p><p>Prettier supports various languages (JavaScript, TypeScript, JSX, Angular, Vue, CSS, HTML, JSON, GraphQL), and it is used by many big companies like Facebook, Spotify, Discord, PayPal, and others.</p><h2>3. <a href="https://marketplace.visualstudio.com/items?itemName=christian-kohler.path-intellisense">Path Intellisense</a></h2><p>!<a href="https://static.devarshi.dev/blog/HLS-Top10VSCodeExtensionsYouNeedIn2022/intellisense.gif">intellisense</a></p><p>Linking correct file paths for your CSS and other assets has never been easier. As the name suggests, the Path Intellisense extension helps you autocomplete filenames and their paths. This simple but powerful extension can index both the working directory and remote drives. When you divide your code into multiple modules, this comes in very handy.</p><p>Whenever you start typing the file name, Path Intellisense will begin to search for that name in your project and give you suggestions. It makes it easier to work with lots of node modules or files.</p><h2>4. <a href="https://marketplace.visualstudio.com/items?itemName=rodrigovallades.es7-react-js-snippets">ES7+ React/Redux/React-Native snippets</a></h2><p>!<a href="https://static.devarshi.dev/blog/HLS-Top10VSCodeExtensionsYouNeedIn2022/snippets.gif">snippets</a></p><p>When working on a React project, “snippets” will help you improve your workflow and code pace by providing neatly packaged and pre-written templates for you to use. All you have to do is start typing the trigger commands.</p><p>By simply typing “rfce” as a command, the extension will generate a React functional component for you, import React, and export the component.</p><p>This extension can be used for React and also for React-Native projects. It’ll give you many snippets for React that you’ll find helpful and speed up your development process. Apart from React, it also has snippets for Redux and GraphQL.</p><p>This is a trendy extension with a few million downloads and a 5-star rating.</p><h2>5. <a href="https://marketplace.visualstudio.com/items?itemName=planbcoding.vscode-react-refactor">React Refactor</a></h2><p>!<a href="https://static.devarshi.dev/blog/HLS-Top10VSCodeExtensionsYouNeedIn2022/react-refactor.gif">react-refactor</a></p><p>Every once in a while, some of the codebases will require refactoring. When working on large projects, this task could become problematic, and that’s when React Refactor tool comes in.</p><p>With a couple of clicks, it can extract parts of JSX code to a new functional component. It might not be as helpful for large components, but it is perfect for any small ones. It has support for TypeScript and TSX, and it’s compatible with React Hooks API. This extension works well with the classes, functions, and arrow functions.</p><h2>6. <a href="https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens">GitLens</a></h2><p>!<a href="https://static.devarshi.dev/blog/HLS-Top10VSCodeExtensionsYouNeedIn2022/git-lens.gif">git-lens</a></p><p>The purpose of GitLens is to help developers navigate and understand how their code is changed over time. Working with git from the console can be difficult, depending on what you want to achieve. The main feature is the ability to visualize who, why, and how changed the lines of code in the past. You can navigate through the history of file changes back and forth. Among many other features, it can inspect a single line in the code, show you the last commit that modified it, and provide you with a link for the pull request in which that change was made. The extension is also highly customizable.</p><h2>7. <a href="https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer">Live Server</a></h2><p>!<a href="https://static.devarshi.dev/blog/HLS-Top10VSCodeExtensionsYouNeedIn2022/live-server.png">live-server</a></p><p>If you are working on website development in VS Code and need to visualize your work so far, you can use Live Server. It creates a local and temporary server just for the website being developed. You can visualize both dynamic and static website pages using this extension.</p><p>- Live and reloadable browser-based web server for website visualization.<br/>- Users can stop or start the server with a single click from the status bar of the add-on.<br/>- Compatible with Chrome Debugging Attachment.</p><h2>8. <a href="https://marketplace.visualstudio.com/items?itemName=eg2.vscode-npm-script">npm</a></h2><p>!<a href="https://static.devarshi.dev/blog/HLS-Top10VSCodeExtensionsYouNeedIn2022/npm.png">npm</a></p><p>If you work on JavaScript projects, you must try npm as the package manager. Now, when you need to shift your work to VS Code editor, you can do that. Because the npm extension lets you enjoy the npm supportability on VS Code editor like other IDEs.</p><p>- Recalling the last npm script that you used after installing this extension.<br/>- Run an npm script<br/>- Terminating any running scripts<br/>- Run npm install</p><h2>9. <a href="https://marketplace.visualstudio.com/items?itemName=pranaygp.vscode-css-peek">CSS Peek</a></h2><p>!<a href="https://static.devarshi.dev/blog/HLS-Top10VSCodeExtensionsYouNeedIn2022/css-peek.png">css-peek</a></p><p>Do you want to get rid of having to toggle over to your .css file to inspect the properties attached to an id or class? You need to try the CSS Peek add-on for VS Code. It lets you view the hover image of CSS code from the HTML file.</p><p>The extension also converts IDs and class names into hyperlinks. Thus, when you click on these hyperlinks, you can instantly access the ID definition and class of your CSS.</p><h2>10. <a href="https://marketplace.visualstudio.com/items?itemName=ecmel.vscode-html-css">HTML and CSS Support</a></h2><p>!<a href="https://static.devarshi.dev/blog/HLS-Top10VSCodeExtensionsYouNeedIn2022/htmlandcsssupport.png">htmlandcsssupport</a></p><p>HTML CSS support visual studio code<br/>The Extension Highlights</p><p>- HTML id and class Auto-completion features.<br/>- Upholds connected and implanted templates.<br/>- Support layout legacy.<br/>- Upholds extra templates.<br/>- Support other HTML-like coding languages.<br/>- Approves CSS selectors on request.</p><h3>How to Use HTML and CSS Support extension?</h3><p>You can see a rundown of id and class suggested ideas by pressing ctrl + space.</p><h2>Happy Coding!</h2><p>This concludes our list of top ten VS Code extensions that we think provide the most boost to developers’ performance, speed, and accuracy. Hope they help you produce amazing work!</p><p>Thank you for reading! If you found this blog post helpful, please consider sharing it with others who might benefit. Feel free to check out my other blog posts and visit my socials!</p><p>- <a href="https://devarshi.dev">Profile</a><br/>- <a href="https://linkedin.com/in/devarshi-shimpi">Linkedin</a><br/>- <a href="https://twitter.com/devarshishimpi">Twitter</a><br/>- <a href="https://youtube.com/@devarshishimpi">Youtube</a><br/>- <a href="https://devarshishimpi.hashnode.dev">Hashnode</a><br/>- <a href="https://dev.to/devarshishimpi">DEV</a></p><h3>Read more</h3><p>- <a href="https://devarshi.dev/blog/self-hosting-your-own-cloud-storage-on-aws-using-nextcloud">Self-Hosting Your Own Cloud Storage on AWS using NextCloud</a><br/>- <a href="https://devarshi.dev/blog/what-is-digitalocean-everything-you-need-to-know">What is DigitalOcean? - Everything You Need to Know</a><br/>- <a href="https://devarshi.dev/blog/how-to-install-and-setup-a-ghost-blog-on-aws-lightsail">How to Install and Set Up a Ghost Blog on AWS Lightsail</a><br/>]]></content:encoded>
      <link>https://devarshi.dev/blog/top-ten-vscode-extensions-you-need-in-twentytwentytwo</link>
      <guid isPermaLink="true">https://devarshi.dev/blog/top-ten-vscode-extensions-you-need-in-twentytwentytwo</guid>
      <pubDate>Wed, 31 Aug 2022 00:00:00 GMT</pubDate>
      <author>devarshishimpi@gmail.com (Devarshi Shimpi)</author>
      <enclosure url="https://static.devarshi.dev/blog/1600/Top10VSCodeExtensionsYouNeedIn20221600.png" type="image/png"/>
      <category>Technology</category>
      <category>Programming</category>
      <category>Development</category>
    </item>
  </channel>
</rss>