<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Ukagha Nzubechukwu </title>
    <description>The latest articles on Forem by Ukagha Nzubechukwu  (@backendbro).</description>
    <link>https://forem.com/backendbro</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F854516%2F0b3ba350-8846-46e1-9b22-f5015946a672.jpeg</url>
      <title>Forem: Ukagha Nzubechukwu </title>
      <link>https://forem.com/backendbro</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/backendbro"/>
    <language>en</language>
    <item>
      <title>Why Most Business AI Fails — And How RAGS Gives Companies a Real Brain.</title>
      <dc:creator>Ukagha Nzubechukwu </dc:creator>
      <pubDate>Tue, 13 Jan 2026 07:52:28 +0000</pubDate>
      <link>https://forem.com/backendbro/why-most-business-ai-fails-and-how-rags-gives-companies-a-real-brain-201f</link>
      <guid>https://forem.com/backendbro/why-most-business-ai-fails-and-how-rags-gives-companies-a-real-brain-201f</guid>
      <description>&lt;p&gt;Most businesses fail at AI, not because the technology is flawed, but because their AI doesn’t know the business. It talks, it responds, it even sounds confident, but underneath the surface, there’s no understanding, no memory, no connection to how the business works. That’s where the gap opens up. When AI lacks context of your policies, data, processes, or decisions, it produces noise instead of value. And in today’s market, that gap (the presence or absence of real intelligence) is what separates companies that successfully use AI for growth from those that waste money on it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdcs205qvj1adzsxz6hsh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdcs205qvj1adzsxz6hsh.png" alt="Comparison of generic AI vs RAGS-powered AI answering the same question" width="800" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;The same question, one generated by a general-purpose AI, and the other by an AI informed by the organization’s internal policies and rules.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The most effective AI doesn’t rely on generic answers or prewritten flows; it actively pulls from internal documents, reports, policies, and historical records to respond with precision. This approach is known as RAGS (&lt;strong&gt;Retrieval-Augmented Generation Systems&lt;/strong&gt;), which enables AI to retrieve relevant information in real-time and utilize it to form accurate, context-aware responses. Instead of guessing, the system answers based on what your company actually knows, making it more dependable, more scalable, and far better aligned with real business needs.&lt;/p&gt;

&lt;p&gt;This post looks at why AI without real knowledge fails in business, and why systems built with RAGS consistently outperform those that aren’t. More importantly, it shows why RAGS isn’t an add-on or a nice-to-have, but the foundation that determines whether AI becomes a real asset or an ongoing expense. To understand why this difference matters so much, we need to examine how most business AI is currently built, and where it falls short.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Here is the &lt;a href="https://github.com/backendbro/RAGs" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt; where you can find the policy documents and the n8n RAGS workflow used in this article.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Most Business AI Breaks Before It Delivers Value
&lt;/h2&gt;

&lt;p&gt;Most business AI relies on lengthy prompts, predefined workflows, and carefully written rules meant to cover every scenario. It looks efficient at first, but it only works when employees or customers ask the “right” questions in the “right” way — something real businesses rarely do. Without RAGS, AI has no access to real company knowledge, so it begins to guess.&lt;/p&gt;

&lt;p&gt;The AI may respond quickly and confidently, but its answers are assumptions, not facts. Without &lt;strong&gt;RAGS grounding responses in actual documents, data, and decisions&lt;/strong&gt;, AI becomes a source of uncertainty, causing employees to lose trust and customers to get frustrated; humans are pulled back in to fix mistakes the system was supposed to prevent.&lt;/p&gt;

&lt;p&gt;As the business grows, the problem compounds. Every new policy, product, or process introduces rules the AI doesn’t know, requiring manual prompt updates and constant maintenance. Teams spend more time managing the AI than benefiting from it, and leadership begins to question the return on investment. This isn’t a technology failure — it’s the absence of &lt;strong&gt;RAGS&lt;/strong&gt;. AI that isn’t connected to real business knowledge doesn’t fail loudly; it fails slowly, draining trust, time, and resources.&lt;/p&gt;

&lt;p&gt;At this point, better prompts won’t help. The system doesn’t need more instructions — it needs RAGS, a way to understand and retrieve the business knowledge it’s meant to support.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is RAGS and Why It Matters
&lt;/h2&gt;

&lt;p&gt;RAGS stands for &lt;strong&gt;Retrieval-Augmented Generation Systems&lt;/strong&gt;. RAGs change how AI language models generate answers. AI models produce text based only on patterns they learned during training. With RAGS, the AI first looks up information from trusted sources, like company documents, databases, reports, or knowledge bases, before generating an answer. &lt;/p&gt;

&lt;p&gt;RAGs make AI’s responses more accurate and up-to-date. For example, large language models like GPT-4, or LLaMA are very good at predicting text, but don't know an employee’s current leave balance or the latest project deadlines. Without RAGS, these models might give confident but incorrect answers, mix reliable and unreliable information, or misinterpret specialized terms.&lt;/p&gt;

&lt;p&gt;RAGS works in four steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Retrieve relevant knowledge&lt;/strong&gt;: When a user asks a question, the system searches across approved knowledge sources ( documents, databases, policies, reports, or APIs ) to find the most relevant information. This search is done using embeddings, which allow the system to match meaning, not just keywords.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add context to the prompt&lt;/strong&gt;: The retrieved information is injected into the prompt as context. This step is what “augments” the model. Instead of guessing, the AI now has direct access to the exact material it should be using to answer the question.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generate a grounded response&lt;/strong&gt;: The large language model uses both its training and the retrieved context to produce a response that is accurate, specific, and aligned with current business knowledge.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stay current without retraining&lt;/strong&gt;: When documents or data change, the knowledge sources are updated — not the model. This keeps responses current without the cost or risk of retraining the AI.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqgsh4muaskv0x8p2x5xj.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqgsh4muaskv0x8p2x5xj.jpg" alt="RAGS Image Description" width="800" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In business, RAGS turns AI from a “confident guesser” into a reliable decision-support tool. For example, an employee could ask, “How many vacation days do I have left this year?” and the system would retrieve the actual balance from the HR database before answering, while a manager could ask, “Which suppliers meet our latest compliance standards?” and the AI would pull the relevant documents to provide a precise response. &lt;/p&gt;

&lt;p&gt;With RAGS, companies get answers that are accurate, relevant, and traceable. Leaders can trust that the AI reflects how the organization actually works and not just patterns in text it has seen before.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why RAGS Is a Foundation, Not a Feature
&lt;/h2&gt;

&lt;p&gt;When AI is built on RAGS, the change is immediate and practical. In large insurance organizations, this shift has enabled customer service teams to answer inquiries more accurately by pulling directly from official policy documents and internal guidelines. The result is less time spent repeating explanations, fewer errors in describing processes or exceptions, and smoother handoffs across teams. Across the organization, friction drops not because people are working harder, but because the system finally understands what it’s talking about.&lt;/p&gt;

&lt;p&gt;This shift creates confidence at every level. Teams trust the answers they receive because they are consistent and traceable to real sources. Customers feel heard instead of redirected, which reduces escalations by approximately 30% and enhances resolution times by nearly 20%. Leaders achieve more predictable outcomes and lower operating costs, as AI improves by keeping knowledge up to date, not by retraining models or rebuilding systems from scratch. These improvements not only enhance customer experience but also contribute directly to the bottom line, showcasing a clear return on investment for adopting RAGS.&lt;/p&gt;

&lt;p&gt;Most importantly, RAGS changes the economics and longevity of AI. Building on these benefits, instead of constantly retraining models to keep up with business needs, companies update their knowledge sources and let the AI retrieve what it needs in real time — even across different product lines or regulatory environments. This keeps information current, reduces implementation costs, and gives organizations more control over what the system can access and say.&lt;/p&gt;

&lt;p&gt;Companies that build AI on RAGS can adapt policies, launch new products, and scale operations without re-engineering their systems each time, while keeping access to sensitive information tightly controlled to meet regulatory and compliance requirements. Those that don’t are forced into retraining models, fixing errors, and managing workarounds as complexity grows.&lt;/p&gt;

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

&lt;p&gt;AI doesn’t fail because it lacks intelligence, it fails because it lacks context. When systems aren’t connected to the knowledge that actually drives decisions, they drift, make mistakes, and slowly erode trust. Every confident answer becomes a potential risk, every recommendation a guess rather than a fact-based decision. RAGS closes that gap by grounding AI in the information that matters. For example, a retail company like Acme Retail can have AI instantly check inventory levels, pricing rules, and promotion policies before responding to a customer query — turning a system that guesses into a system that reliably informs decisions.&lt;/p&gt;

&lt;p&gt;For companies planning their AI strategy, the choice is no longer about picking the right model or software. It’s about whether the intelligence you deploy is grounded in knowledge or built on guesswork and whether it earns trust or requires constant supervision. AI powered by RAGS changes the game: it delivers accurate, context-aware responses, even outside business hours, so customers can complete transactions confidently, employees can make informed decisions, and every interaction buids trust. Grounded in knowledge, AI doesn’t just answer questions, it keeps users engaged, supports teams, and becomes a reliable asset that grows businesses.&lt;/p&gt;

</description>
      <category>rag</category>
      <category>buisness</category>
      <category>ai</category>
      <category>automation</category>
    </item>
    <item>
      <title>How to send Automated Personalized Cold Emails with n8n to Boost Response Rates</title>
      <dc:creator>Ukagha Nzubechukwu </dc:creator>
      <pubDate>Wed, 08 Oct 2025 22:19:12 +0000</pubDate>
      <link>https://forem.com/backendbro/how-to-send-automated-personalized-cold-emails-with-n8n-to-boost-response-rates-i3k</link>
      <guid>https://forem.com/backendbro/how-to-send-automated-personalized-cold-emails-with-n8n-to-boost-response-rates-i3k</guid>
      <description>&lt;p&gt;Generic cold emails get deleted faster than spam these days. Yet, personalizing each email for hundreds of prospects is a productivity nightmare no individual or sales team can afford.&lt;/p&gt;

&lt;p&gt;Many email marketing campaigns fail to achieve their desired impact primarily because they lack personalization and specificity. When email providers like Gmail perceive your email as "generic", they are more likely to be categorized as promotional content or, worse yet, as spam. This misclassification prevents their delivery to the intended individuals. &lt;/p&gt;

&lt;p&gt;Even if your emails bypass spam filters and land in the inbox, they risk being ignored or dismissed. Potential clients will skim over them, viewing your message as just another faceless message that takes up important space in their email storage. &lt;/p&gt;

&lt;p&gt;Personalizing your message signals authenticity and shows you’ve taken the time to understand the person and their interests. Mention a specific trigger, for example, “I noticed your team is hiring a new sales manager.” This shows awareness of their situation and opens a timely, relevant conversation. That kind of specificity makes recipients far more likely to stop, read, and respond.&lt;/p&gt;

&lt;p&gt;In this guide, I will show you how to build an n8n workflow that generates personalized email content and automates the sending process, all while ensuring compliance and deliverability. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Important — scope of this guide&lt;/strong&gt;&lt;br&gt;
This is an introductory walkthrough for setting up an n8n workflow that personalizes and sends emails. I don't cover list scraping or acquisition techniques; the guide assumes you already have a lawful, consented email list.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;To complete this guide, make sure you have the following items ready;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An &lt;a href="https://n8n.io/" rel="noopener noreferrer"&gt;n8n&lt;/a&gt; account.&lt;/li&gt;
&lt;li&gt;A prepared email list (&lt;a href="https://docs.google.com/spreadsheets/" rel="noopener noreferrer"&gt;Google Sheet&lt;/a&gt; recommended). I've provided a template for you. Open this &lt;a href="https://docs.google.com/spreadsheets/d/e/2PACX-1vROdUPEYFazqY78djrGmujANRsmt1mJU8ChExdSdIdD_ELDZGSiygNutkpdAzcbQ2luAik8o7p3EOFV/pubhtml" rel="noopener noreferrer"&gt;spreadsheet&lt;/a&gt; and make a copy for your use. This Google Sheet already includes the necessary headers, such as &lt;strong&gt;First Name, Email, Title, Company, LinkedIn, Website, Summary, Industry,&lt;/strong&gt; and &lt;strong&gt;Location&lt;/strong&gt;. Additionally, you can add extra columns for further personalization.
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Don’t worry if fields like &lt;em&gt;Subject, icebreaker, elevatorPitch, callToAction,&lt;/em&gt; or &lt;em&gt;postscript&lt;/em&gt; are empty, the workflow will fill those automatically.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;No n8n experience required, this guide walks you step-by-step through the entire process.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Traditional Cold Email Doesn’t Work Anymore
&lt;/h2&gt;

&lt;p&gt;The old strategy of mass “spray and pray” emails has lost its effectiveness. These impersonal communications are quickly flagged as spam or deleted, often before they even get a chance to be read.&lt;/p&gt;

&lt;p&gt;While high-touch outreach from Sales Development Representatives (SDRs) can yield better replies, this method is not scalable. A single SDR may only be able to send a limited number of meticulously crafted emails each day, resulting in a slow and costly process that can burn teams out. Manual research produces quality, but not the volume most teams need.&lt;/p&gt;

&lt;p&gt;A more effective strategy is to adopt a hybrid approach that combines the benefits of automation with genuine contextual personalization. n8n allows you to personalize messages with warm triggers and craft introductory lines that feel human. This method ensures that your outreach feels thoughtfully composed and tailored to each individual, all while helping you to reach a much larger audience. By doing this, you increase your inbox hit rate and also significantly improve response rates, transforming your outreach from mere noise into meaningful conversations.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Send Automated Personalized Cold Emails with n8n
&lt;/h2&gt;

&lt;p&gt;You will sign up for n8n to create a workflow that automatically pulls your email list, generates personalized outreach messages with ChatGPT, and sends your first targeted campaign.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1 — Create an n8n account
&lt;/h3&gt;

&lt;p&gt;To begin, visit &lt;a href="https://n8n.io/" rel="noopener noreferrer"&gt;n8n&lt;/a&gt;’s website and create a free account, no credit card required. You get a 14-day free trial, so there’s no need to worry about being charged while you try the platform.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2 — Add your trigger
&lt;/h3&gt;

&lt;p&gt;After login, you’ll land on your n8n dashboard.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frkk8q5oj8jjfkwdc26c6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frkk8q5oj8jjfkwdc26c6.jpg" alt="n8n homepage"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click “&lt;strong&gt;Start from scratch&lt;/strong&gt;” to open the workflow editor, and then, hit the “&lt;strong&gt;Add first step&lt;/strong&gt;” button to add your trigger node, the starting point of everything your workflow will do.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1sxnuregttcr4ni3i0mj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1sxnuregttcr4ni3i0mj.png" alt="n8n workflow editor"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Quick note&lt;/strong&gt;: A trigger node is what starts your automation. Think of it as the “on switch.” It can be almost anything: a button you click, someone submitting a form, a new row appearing in your spreadsheet, or even a schedule (like “every morning at 9 am”).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For this guide, choose Trigger manually.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0fr7ta7bo76mptkqwq64.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0fr7ta7bo76mptkqwq64.png" alt="Trigger options for n8n"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This starts the workflow only when you click the play button. It’s the easiest way to test things while you’re just getting started.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8milj3fcpilurtw6inp8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8milj3fcpilurtw6inp8.png" alt="n8n manual trigger"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 3 — Connect your Google Sheet to the workflow
&lt;/h3&gt;

&lt;p&gt;Now that your workflow has a trigger, it’s time to bring in your spreadsheet. This is where your email list lives, so you want n8n to grab that data and pass it along to the rest of your automation.&lt;/p&gt;

&lt;p&gt;Click the "&lt;strong&gt;+&lt;/strong&gt;" button after your trigger node, search for Google Sheets, and select it. From the list of actions, choose "&lt;strong&gt;Get Row(s) in Sheet&lt;/strong&gt;". &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F22j9p7b2snvhlmmqkxdr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F22j9p7b2snvhlmmqkxdr.png" alt="n8n editing canva"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It’s okay if your “&lt;strong&gt;Credential to connect with&lt;/strong&gt;” looks different. That just means I’ve already set one up; I’ll guide you through the process anyway.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the Credentials field, open the dropdown and select "&lt;strong&gt;Create new credential&lt;/strong&gt;". Then, click "&lt;strong&gt;Sign in with Google&lt;/strong&gt;", and sign in with your account. Once connected, you will see a message that says "Account connected."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3qnyspgdywntbandrr5i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3qnyspgdywntbandrr5i.png" alt="n8n editing canva"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the Resource field, select “&lt;strong&gt;Sheet within Document.&lt;/strong&gt;”  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvq7vzjdygjf7ri61u80c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvq7vzjdygjf7ri61u80c.png" alt="n8n resource field"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For Operation, choose “&lt;strong&gt;Get Row(s).&lt;/strong&gt;” &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbda3md8mfp58oa846k1e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbda3md8mfp58oa846k1e.png" alt="n8n Operation field"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Under Document, keep “&lt;strong&gt;From list&lt;/strong&gt;” and select the spreadsheet that contains your email list. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foht8jkkwrl4oojnq1n76.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foht8jkkwrl4oojnq1n76.png" alt="n8n Document description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In Sheet, keep “&lt;strong&gt;From list&lt;/strong&gt;” and choose the sheet with your contacts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqvvij419vo40328aro54.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqvvij419vo40328aro54.png" alt="n8n sheet"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can ignore the filter options for now; they’re only useful if you want to pull specific rows.&lt;/p&gt;

&lt;p&gt;Finally, test your spreadsheet node by clicking &lt;strong&gt;Execute step&lt;/strong&gt;. If everything is working, you’ll see your spreadsheet data appear in the output tab, ready to be used in the next step of your workflow.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp6lc9a033ax5xb00fk8l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp6lc9a033ax5xb00fk8l.png" alt="n8n output"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Make sure to click the pin icon in the top-right corner of the output panel so the data is visible while you configure the next node. This way, you don’t have to rerun this node every time.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  Step 4 — Personalize your emails with ChatGPT
&lt;/h3&gt;

&lt;p&gt;In this step, you’ll pass each row from your Google Sheet into an OpenAI model, which will generate a personalized email for you. &lt;/p&gt;

&lt;p&gt;Click the “&lt;strong&gt;+&lt;/strong&gt;” button after the Google Sheets node, search for OpenAI, and choose "&lt;strong&gt;Message a model&lt;/strong&gt;". &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You’ll see the Google Sheets data in the left panel. This is what the model will use for personalization.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyqhvlj0w47umate4n03s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyqhvlj0w47umate4n03s.png" alt="n8n input panel"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the "&lt;strong&gt;Credential to connect with&lt;/strong&gt;" input, open the dropdown and click  "&lt;strong&gt;Create new credential&lt;/strong&gt;". A pop-up will appear where you can enter your OpenAI API key.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flz4huawrh2wt9k5i9b6l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flz4huawrh2wt9k5i9b6l.png" alt="OPEN AI pop up"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To retrieve your API key, visit the &lt;a href="https://auth.openai.com/create-account" rel="noopener noreferrer"&gt;OpenAI&lt;/a&gt; platform. Then, return to the n8n popup, paste the secret into the API key field, and save. If everything is done correctly, you will see a message saying the connection was tested successfully.&lt;/p&gt;

&lt;p&gt;Keep the Resource input set to its default option, which is "&lt;strong&gt;Text&lt;/strong&gt;". &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuytl8nccixsldp759yzm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuytl8nccixsldp759yzm.png" alt="Resource input"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the Operation input, leave it at its default setting as "&lt;strong&gt;Message a model&lt;/strong&gt;".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7hczvdabn27b12yqcwmg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7hczvdabn27b12yqcwmg.png" alt="Operation input"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select a model from the dropdown menu: if you're using n8n's free credits or a free OpenAI account, choose a smaller model; if you have a paid OpenAI account, opt for a more powerful one.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flnz0jjxhjgj9akg3jve0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flnz0jjxhjgj9akg3jve0.png" alt="model input"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the message field, you have two sub-fields: "&lt;strong&gt;prompt&lt;/strong&gt;" and "&lt;strong&gt;role&lt;/strong&gt;". In the prompt sub-field, enter the following text:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You are a helpful assistant whose role is to personalize emails and make them more human.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the role sub-field, select "System."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhxlw1zw9292xeigmqsg6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhxlw1zw9292xeigmqsg6.png" alt="message field"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To proceed, click on "&lt;strong&gt;Add message&lt;/strong&gt;" to add another sub-field. In the prompt input, enter the following block of text below and set the role to &lt;strong&gt;User&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;
  Full prompt —  &lt;strong&gt;Click to expand!&lt;/strong&gt;
  &lt;br&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You are a concise outbound email writer. For each spreadsheet row, you are given the following input fields:
Civility, First Name, Last Name, Full Name, Title Description, Email, Profile (URL), Title, Company, Company Legal, Company Phone, Company Website, Company LinkedIn, Company Summary, Industry, Company Location.

Goal: produce a short, human-feeling outreach email broken into 5 parts:
{"subjectLine":"", "iceBreaker":"", "elevatorPitch":"", "callToAction":"", "ps":""}

Task steps (must follow in order):
1. Quick research (web): using the Profile URL, Company Website, Company LinkedIn and public sources (news, Crunchbase/AngelList, product pages, recent posts), gather 3 one-line facts:
   a. What the person actually does / focus (paraphrase — do NOT copy LinkedIn text verbatim).
   b. One recent signal or behavior you can mention (product launch, press, hiring, content they posted, conference talk).
   c. A concise, credible gap or opportunity for the company (one sentence) — e.g., lead-gen funnel unclear, demo scheduling low/no automation, pricing page confusing, low content-to-conversion flow, no obvious appointment pipeline. When unsure, default to a safe, general, plausible gap framed as an *opportunity* rather than a failure.

2. Third-party/company comparison: identify one relevant peer/competitor/adjacent company and note a single, tactful difference or shortcoming you can use as a contrast to frame an opportunity for your prospect. Keep it high-level and non-judgmental.

3. Build `thingAboutThem` and `relatedThing`:
   - `thingAboutThem`: a short phrase (3–6 words) summarizing the person’s focus or recent initiative (e.g., "lead gen for SMBs", "product-led growth", "enterprise onboarding").
   - `relatedThing`: a related phrase you can reference in the icebreaker (e.g., "your recent blog on demo conversions", "the webinar you did on onboarding").

4. Compose outputs with these constraints:
   - Tone: "casual bar conversation", spartan, plain language, short sentences.
   - No fancy jargon. Use one human-sounding sentence for each field where possible.
   - Subject line: lowercase, ≤60 characters, include First Name and `thingAboutThem` if natural (format: `hey {FirstName}, quick thought re: {thingAboutThem}`).
   - Icebreaker: 10–25 words. Specific detail from research, paraphrased (do not paste profile copy).
   - Elevator pitch: one short sentence (≤18 words) with a plausible, quantifiable result (use ranges like "~$X/mo" or "% lift" and hedge with "can", "likely", "typically").
   - Call to action: 1–2 sentences. Offer a low-friction next step (15–30 min call / free audit) and a risk-minimizing guarantee (e.g., "I'll guarantee X or you don't pay", or "I'll prove value in 2 weeks").
   - PS: 5–12 words, curious &amp;amp; conversational.

5. Safety &amp;amp; accuracy rules:
   - Do NOT invent awards, numbers, or proprietary customer names. If no public evidence exists, say something plausible but hedged ("looks like", "appears", "seems").
   - Never state private data you can’t verify. If profile or company pages are unavailable, use neutral, general icebreakers referencing industry trends.
   - Keep claims defensible and small. Avoid legal, medical, political claims.

6. Output: only return one JSON object exactly in this format (no extra text):
{"subjectLine":"", "iceBreaker":"", "elevatorPitch":"", "callToAction":"", "ps":""}

7. If a required field from the spreadsheet is missing, fall back:
   - Missing Profile URL: use Company Website / Company LinkedIn first. If none, use industry-level icebreaker.
   - Missing CompanySummary: summarize the Company Website homepage (1 short phrase).
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;/p&gt;

&lt;p&gt;Add yet another sub-field. In the prompt input, enter the following block of text below and set the role to &lt;strong&gt;User&lt;/strong&gt;. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This block represents the JSON data from your spreadsheet, and it’s important because it passes the right fields (like name, company, and profile) into the prompt so each email can be personalized correctly&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;
  Full prompt —  &lt;strong&gt;Click to expand!&lt;/strong&gt;
  &lt;br&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Civility: {{ $json.Civility }}
First Name:  {{ $json['First Name'] }} 
Last Name: {{ $json['Last Name'] }} 
Full Name: {{ $json['Full Name'] }}
Title Description: {{ $json.Title }} 
Email: {{ $json.Email }} 
Profile (URL): {{ $json.Profile }} 
Title: {{ $json.Title }}
Company:{{ $json.Company }} 
Company Legal: {{ $json['Company Legal Name'] }} 
Company Phone: {{ $json['Company Phone'] }} 
Company Website: {{ $json.Website }}
Company LinkedIn:{{ $json.Linkedin }} 
Company Summary: {{ $json.Summary }} 
Industry: {{ $json.Industry }} 
Company Location: {{ $json['Company Location'] }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;/p&gt;

&lt;p&gt;Finally, toggle "&lt;strong&gt;Output Content as JSON&lt;/strong&gt;" to ON.&lt;/p&gt;

&lt;p&gt;We are ready to execute this step; click the "&lt;strong&gt;Execute step&lt;/strong&gt;" button. Your AI will return a JSON object containing fields like subject line, icebreaker, and call-to-action.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5 - Update Google Spreadsheet
&lt;/h3&gt;

&lt;p&gt;Now that your OpenAI node is generating personalized emails, the next step is to send those results back to your spreadsheet. &lt;/p&gt;

&lt;p&gt;To begin, click the “&lt;strong&gt;+&lt;/strong&gt;” button after your OpenAI node, search for Google Sheets, and select “&lt;strong&gt;Update row in sheet&lt;/strong&gt;”. You’ve already worked with this node earlier, so most of the setup will feel familiar. Let’s walk through the key parts quickly:&lt;/p&gt;

&lt;p&gt;In the “&lt;strong&gt;Credential to connect with&lt;/strong&gt;” field, keep the default option. n8n will automatically reuse the same Google Sheets credential you created earlier.&lt;/p&gt;

&lt;p&gt;Leave Resource set to “&lt;strong&gt;Sheet within document&lt;/strong&gt;” and Operation as “&lt;strong&gt;Update Row&lt;/strong&gt;”. &lt;/p&gt;

&lt;p&gt;In the Document field, choose “&lt;strong&gt;FROM ID&lt;/strong&gt;”. Next, go to your Google Sheet and copy the ID from its URL. A typical spreadsheet URL looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://docs.google.com/spreadsheets/d/&amp;lt;1YjJeRUDXAKGEc-xYv_GfSj3E8s7YDPQwhgDrx9fYsCQ&amp;gt;/edit#gid=784785913
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;The spreadsheet URL does not include angle brackets (&amp;lt; &amp;gt;). I added them to indicate where to copy. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Copy the Google Sheet ID from the URL and paste it into the input field next to “&lt;strong&gt;FROM ID&lt;/strong&gt;”.&lt;/p&gt;

&lt;p&gt;For the Sheet field, leave “From list” selected, then choose the specific sheet that holds your email data.&lt;/p&gt;

&lt;p&gt;Keep Mapping Column Mode as it is. In the Column to match on, select "&lt;strong&gt;Email&lt;/strong&gt;". This ensures that each row is matched to the correct contact, preventing updates to the wrong row.&lt;/p&gt;

&lt;p&gt;Now, fill in the values to match the fields with the data from your previous steps.&lt;br&gt;
You can paste the expressions below or drag and drop the fields from the left panel.&lt;/p&gt;

&lt;p&gt;
  Full prompt —  &lt;strong&gt;Click to expand!&lt;/strong&gt;
  &lt;br&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Email (using to match): {{ $('Get row(s) in sheet').item.json.Email }}
Civility: {{ $('Get row(s) in sheet').item.json.Civility }}
First Name: {{ $('Get row(s) in sheet').item.json['First Name'] }}
Last Name: {{ $('Get row(s) in sheet').item.json['Last Name'] }}
Full Name: {{ $('Get row(s) in sheet').item.json['Full Name'] }}
Title: {{ $('Get row(s) in sheet').item.json.Title }}
Profile: {{ $('Get row(s) in sheet').item.json.Profile }}
Company Name: {{ $('Get row(s) in sheet').item.json['Company Name'] }}
Company Legal Name: {{ $('Get row(s) in sheet').item.json['Company Legal Name'] }}
Company Phone: {{ $('Get row(s) in sheet').item.json['Company Phone'] }}
Company Website: {{ $('Get row(s) in sheet').item.json['Company Website'] }}
Company LinkedIn: {{ $('Get row(s) in sheet').item.json['Company LinkedIn'] }}
Company Summary: {{ $('Get row(s) in sheet').item.json['Company Summary'] }}
Industry: {{ $('Get row(s) in sheet').item.json.Industry }}
Company Location: {{ $('Get row(s) in sheet').item.json['Company Location'] }}
Title Description: {{ $('Get row(s) in sheet').item.json['Title Description'] }}
Subject: {{ $json.message.content.subjectLine }}
Icebreaker: {{ $json.message.content.iceBreaker }}
Elevator Pitch: {{ $json.message.content.elevatorPitch }}
Call To Action: {{ $json.message.content.callToAction }}
Postscript: {{ $json.message.content.ps }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;/p&gt;

&lt;p&gt;Make sure every field has a value; otherwise, n8n might skip empty ones.&lt;/p&gt;

&lt;p&gt;You can also drag-and-drop values directly into each input if you prefer. Here is a video to show you how it's done. &lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/Qmz0QNq1c8M"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;p&gt;And finally, click "&lt;strong&gt;Execute Step&lt;/strong&gt;" to append your personalized email content to your spreadsheet. &lt;/p&gt;

&lt;h3&gt;
  
  
  Step 6 — Send your personalized emails automatically
&lt;/h3&gt;

&lt;p&gt;Now that your spreadsheet has all the personalized fields (subject line, icebreaker, pitch, call-to-action, and postscript), you can automatically send your emails using the "&lt;strong&gt;Send a message&lt;/strong&gt;" Gmail node.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In this step, you can either use your Gmail account to send emails or choose the SMTP option if you prefer to connect your own mail server or a service like SendGrid. For this example, use the Gmail option; the SMTP method is straightforward and similar.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To begin, click the “+” button after your last Google Sheets node, search for Gmail, and select "&lt;strong&gt;Send a message&lt;/strong&gt;".&lt;/p&gt;

&lt;p&gt;In Credential to connect with, click "&lt;strong&gt;Create new credential&lt;/strong&gt;" and sign in with the Gmail account you’ll use to send.&lt;/p&gt;

&lt;p&gt;Leave the Resource field set to Message and Operation as Send.&lt;/p&gt;

&lt;p&gt;Set the To field to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{{ $json.Email }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Set the subject field to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{{ $json['Subject'] }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Set Email type to HTML and paste the HTML template into the Message field:&lt;/p&gt;

&lt;p&gt;
  Full html —  &lt;strong&gt;Click to expand!&lt;/strong&gt;
  &lt;br&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!doctype html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"utf-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Email&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"x-preheader"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"{{ ($json['iceBreaker'] || 'Quick thought for you') }}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
      &lt;span class="nd"&gt;:root&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="py"&gt;color-scheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;light&lt;/span&gt; &lt;span class="n"&gt;dark&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="py"&gt;supported-color-schemes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;light&lt;/span&gt; &lt;span class="n"&gt;dark&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prefers-color-scheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dark&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#111111&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nc"&gt;.body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#0b0b0b&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nc"&gt;.text&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#f2f2f2&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nc"&gt;.muted&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#bbbbbb&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nc"&gt;.btn&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#4f46e5&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#ffffff&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nc"&gt;.divider&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;border-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#2a2a2a&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nc"&gt;.chip&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#1c1c1c&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#e5e7eb&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"body"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"margin:0;padding:0;background:#f6f7fb;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;table&lt;/span&gt; &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"presentation"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"100%"&lt;/span&gt; &lt;span class="na"&gt;cellpadding=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt; &lt;span class="na"&gt;cellspacing=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"background:#f6f7fb;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;td&lt;/span&gt; &lt;span class="na"&gt;align=&lt;/span&gt;&lt;span class="s"&gt;"center"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"padding:24px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;table&lt;/span&gt; &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"presentation"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"100%"&lt;/span&gt; &lt;span class="na"&gt;cellpadding=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt; &lt;span class="na"&gt;cellspacing=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"max-width:640px;background:#ffffff;border-radius:14px;overflow:hidden;box-shadow:0 6px 24px rgba(0,0,0,0.06);"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;td&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"padding:18px 22px;background:linear-gradient(135deg,#6366f1,#22d3ee);"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font:600 14px/1.2 -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Arial,sans-serif;color:#ffffff;letter-spacing:.3px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                  Quick intro for {{ $json['First Name'] || 'you' }}
                &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;td&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"padding:28px 24px 8px 24px;"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font:16px/1.6 -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Arial,sans-serif;color:#111827;"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                  &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"margin:0 0 14px 0;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                    Hi {{ ($json['Civility'] ? ($json['Civility'] + ' ') : '') + ($json['First Name'] || $json['Full Name'] || 'there') }},
                  &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
                  &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"margin:0 0 14px 0;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                    {{ $json['iceBreaker'] || 'Saw your recent work and had a quick idea that might help your team.' }}
                  &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
                  &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"margin:0 0 14px 0;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                    {{ $json['elevatorPitch'] || 'We help teams ship faster with fewer rollbacks by tightening CI and monitoring.' }}
                  &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
                  &lt;span class="nt"&gt;&amp;lt;table&lt;/span&gt; &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"presentation"&lt;/span&gt; &lt;span class="na"&gt;cellpadding=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt; &lt;span class="na"&gt;cellspacing=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"margin:18px 0 8px 0;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt;
                      &lt;span class="nt"&gt;&amp;lt;td&amp;gt;&lt;/span&gt;
                        &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"{{ $json['Company Website'] ? ('https://' + $json['Company Website'].replace(/^https?:\/\//,'')) : '#' }}"&lt;/span&gt;
                           &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display:inline-block;background:#111827;color:#ffffff;text-decoration:none;padding:12px 18px;border-radius:10px;font:600 14px/1 -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Arial,sans-serif;"&lt;/span&gt;
                           &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                          {{ ($json['First Name'] ? ('Quick 15–20 min chat, ' + $json['First Name']) : 'Quick 15–20 min chat') }}
                        &lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
                      &lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
                  &lt;span class="nt"&gt;&amp;lt;/table&amp;gt;&lt;/span&gt;
                  &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"margin:6px 0 16px 0;color:#374151;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                    {{ $json['callToAction'] || 'Open to a quick call? I can do a free audit and prove value in 2 weeks.' }}
                  &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
                  &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"margin:0 0 6px 0;color:#6b7280;"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"muted"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                    PS — {{ $json['ps '] || $json['ps'] || 'worth a brief pipeline audit?' }}
                  &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;td&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"padding:0 24px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;hr&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"border:none;border-top:1px solid #e5e7eb;margin:8px 0 0 0;"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"divider"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;td&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"padding:16px 24px 22px 24px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;table&lt;/span&gt; &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"presentation"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"100%"&lt;/span&gt; &lt;span class="na"&gt;cellpadding=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt; &lt;span class="na"&gt;cellspacing=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font:13px/1.5 -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Arial,sans-serif;color:#4b5563;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                  &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;td&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"padding:2px 0;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                      &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display:inline-block;padding:6px 10px;border-radius:999px;background:#f3f4f6;"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"chip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                        {{ $json['Full Name'] || (($json['First Name']||'') + ' ' + ($json['Last Name']||'')) || 'Your contact' }}
                      &lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
                      &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display:inline-block;padding:6px 10px;border-radius:999px;background:#f3f4f6;margin-left:6px;"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"chip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                        {{ $json['Title'] || 'Professional' }} @ {{ $json['Company Name'] || $json['Company Legal Name'] || 'Company' }}
                      &lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
                  &lt;span class="nt"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
                  &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;td&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"padding:2px 0;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                      &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display:inline-block;padding:6px 10px;border-radius:999px;background:#f3f4f6;"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"chip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                        {{ $json['Industry'] || 'Industry' }}
                      &lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
                      &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display:inline-block;padding:6px 10px;border-radius:999px;background:#f3f4f6;margin-left:6px;"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"chip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                        {{ $json['Company Location'] || 'Location' }}
                      &lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
                  &lt;span class="nt"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
                  &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;td&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"padding:2px 0;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                      &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"{{ $json['Company Website'] ? ('https://' + $json['Company Website'].replace(/^https?:\/\//,'')) : '#' }}"&lt;/span&gt;
                         &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"color:#4f46e5;text-decoration:none;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{{ $json['Company Website'] || 'website' }}&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
                      &lt;span class="ni"&gt;&amp;amp;nbsp;&lt;/span&gt;•&lt;span class="ni"&gt;&amp;amp;nbsp;&lt;/span&gt;
                      &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"{{ $json['Company LinkedIn'] || $json['Profile'] || '#' }}"&lt;/span&gt;
                         &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"color:#4f46e5;text-decoration:none;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;LinkedIn&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
                      &lt;span class="ni"&gt;&amp;amp;nbsp;&lt;/span&gt;•&lt;span class="ni"&gt;&amp;amp;nbsp;&lt;/span&gt;
                      &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;{{ $json['Company Phone'] || '' }}&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
                  &lt;span class="nt"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
                  &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;td&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"padding:6px 0;color:#6b7280;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                      {{ $json['Company Summary'] || 'Helping customers succeed with modern software.' }}
                    &lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
                  &lt;span class="nt"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/table&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/table&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"max-width:640px;margin:12px auto 0 auto;text-align:center;font:11px/1.6 -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Arial,sans-serif;color:#9ca3af;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            You’re getting this because someone reached out 1:1 — no list.
          &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/table&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;/p&gt;

&lt;p&gt;In the Options field, click “&lt;strong&gt;Add option&lt;/strong&gt;”. From the list that appears, select “&lt;strong&gt;Append n8n Attribution&lt;/strong&gt;”. You’ll see it added to your options panel; toggle it off.&lt;br&gt;
This prevents n8n from automatically adding the line “This email was sent automatically with n8n” to your messages.&lt;/p&gt;

&lt;p&gt;Finally, click “&lt;strong&gt;Execute node&lt;/strong&gt;” to send your first personalized email.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 7 — Automate the workflow
&lt;/h3&gt;

&lt;p&gt;Once you've tested the entire workflow and confirmed that everything is functioning properly, you can replace the manual trigger with a scheduled trigger. This allows n8n to automate the process, so you won't need to run the workflow manually in the future. By using a Cron trigger, you can set the workflow to execute on a regular schedule, such as every morning at 8 AM.&lt;/p&gt;

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

&lt;p&gt;In this guide, I showed you the process of feeding data into a workflow, personalizing each row of information, and outputting it in the provided spreadsheet. This is just a starting point, an introduction to the world of automated personalized cold emails. We can take this workflow a step further by adding several nodes that allow us to get recent posts of our prospects. This will help us identify more trigger words to provoke responses.&lt;/p&gt;

&lt;p&gt;As you advance beyond the basics, focus on the technical foundations that keep personalization effective at scale; Clean data practices, robust email authentication, and strict compliance with relevant regulations, such as GDPR and CAN-SPAM, are essential for ensuring that your messages do not get misclassified as spam. When it comes to sending practices, it's advisable to gradually warm up new mailboxes by beginning with small volumes of emails that mimic human-like behavior. This strategy helps prevent your messages from being flagged as junk.&lt;/p&gt;

&lt;p&gt;If you’d like help building more sophisticated workflows, perhaps pulling recent LinkedIn posts or other triggers into your outreach, I’m happy to help. Personalization done right is a competitive advantage, and investing in the tools and techniques to do it at scale will set you apart from peers who still do one‑size‑fits‑all blasts and time‑consuming manual research.&lt;/p&gt;

</description>
      <category>sales</category>
      <category>n8n</category>
      <category>marketing</category>
      <category>automation</category>
    </item>
    <item>
      <title>Step-by-Step Guide: Deploying a Full-Stack App on AWS EC2.</title>
      <dc:creator>Ukagha Nzubechukwu </dc:creator>
      <pubDate>Wed, 01 May 2024 16:03:27 +0000</pubDate>
      <link>https://forem.com/backendbro/step-by-step-guide-deploying-a-full-stack-app-on-aws-ec2-21e1</link>
      <guid>https://forem.com/backendbro/step-by-step-guide-deploying-a-full-stack-app-on-aws-ec2-21e1</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;After building an application, deploying it to a cloud service is crucial in making it accessible to your users. Amazon offers a service called Amazon Elastic Compute Cloud (EC2), which provides scalable and low-cost virtual servers in the cloud.&lt;/p&gt;

&lt;p&gt;With EC2, you can easily customize the various specs of your virtual server, such as operating systems, CPU, memory, storage, and other features. You also control your security and network settings, which ensures that data is only accessible to authorized users. EC2 is an ideal choice for hosting applications of different sizes and complexities. &lt;/p&gt;

&lt;p&gt;In this guide, you will learn how to deploy a full-stack application that comprises a Typescript Next.js client and Node.js server to Amazon EC2. You will cover steps to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set up an AWS EC2 instance.&lt;/li&gt;
&lt;li&gt;Install PostgreSQL and create a database.&lt;/li&gt;
&lt;li&gt;Deploy your application code onto the instance. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Additionally, this guide will cover how to configure your network and security settings for optimal performance and safety. Let’s get started.&lt;/p&gt;

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

&lt;p&gt;To complete this guide, make sure you have the following requirements: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;An &lt;strong&gt;&lt;a href="https://aws.amazon.com/" rel="noopener noreferrer"&gt;AWS&lt;/a&gt;&lt;/strong&gt; Account.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://git-scm.com/download/win" rel="noopener noreferrer"&gt;Git bash&lt;/a&gt;&lt;/strong&gt; (Standalone Installer). If you need help installing Git Bash, check out this tutorial — &lt;strong&gt;&lt;a href="https://www.youtube.com/watch?v=cJTXh7g-uCM" rel="noopener noreferrer"&gt;How to install Git on Windows 10&lt;/a&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.enterprisedb.com/downloads/postgres-postgresql-downloads" rel="noopener noreferrer"&gt;PostgreSQL&lt;/a&gt;&lt;/strong&gt; installed. Follow this tutorial — &lt;strong&gt;&lt;a href="https://www.youtube.com/watch?v=0n41UTkOBb0" rel="noopener noreferrer"&gt;How to Install PostgreSQL 15 on Windows Postgres&lt;/a&gt;&lt;/strong&gt; for guidance on how to install PostgreSQL. &lt;/li&gt;
&lt;li&gt;Some familiarity with &lt;strong&gt;&lt;a href="https://www.postgresql.org/" rel="noopener noreferrer"&gt;PostgreSQL&lt;/a&gt;&lt;/strong&gt; and basic &lt;strong&gt;&lt;a href="https://www.linux.org/" rel="noopener noreferrer"&gt;Linux&lt;/a&gt;&lt;/strong&gt; commands. However, if you don't have any prior experience, don't worry. This guide is beginner-friendly. 
But, If you are interested in learning more about these topics, you can acquire the necessary knowledge through the following courses: 

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://www.youtube.com/watch?v=qw--VYLpxG4" rel="noopener noreferrer"&gt;Learn PostgreSQL Tutorial - Full Course for Beginners&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;&lt;a href="https://www.youtube.com/watch?v=IVquJh3DXUA" rel="noopener noreferrer"&gt;Introduction to Linux and Basic Linux Commands for Beginners&lt;/a&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 1: Launch an EC2 instance.
&lt;/h2&gt;

&lt;p&gt;In this step, you will set up and launch an AWS EC2 Ubuntu instance. &lt;/p&gt;

&lt;p&gt;The Ubuntu operating system is a popular choice when setting up an AWS EC2 instance. It is open-source and comes with no licensing fees. Ubuntu supports a vast range of software and has a thriving community that makes it easier to find help.&lt;/p&gt;

&lt;p&gt;To start, log in to your &lt;strong&gt;&lt;a href="https://aws.amazon.com/console/" rel="noopener noreferrer"&gt;AWS console&lt;/a&gt;&lt;/strong&gt;. Next, search and select &lt;strong&gt;EC2&lt;/strong&gt; using the search bar.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9t2nfrjizt67gq3dbtqj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9t2nfrjizt67gq3dbtqj.png" alt="aws console" width="800" height="187"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on &lt;strong&gt;Launch instance&lt;/strong&gt; to begin set up and launch your AWS EC2 instance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdyupzgnysrvd14cfg52n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdyupzgnysrvd14cfg52n.png" alt="launch instance button " width="414" height="301"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To proceed, provide a unique and descriptive name for your instance. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F94wecpm5gskb0v5zig8p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F94wecpm5gskb0v5zig8p.png" alt="aws ec2 instance name field" width="800" height="188"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, in the &lt;strong&gt;Application and OS Images&lt;/strong&gt; section, select &lt;strong&gt;Ubuntu&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmbeftpsz7tzf1oavq98m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmbeftpsz7tzf1oavq98m.png" alt="aws ec2 application and os images section" width="780" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By default, the &lt;strong&gt;Instance type&lt;/strong&gt; section is preselected for you. The default option is sufficient for this guide and will save you money. But if you want more resources and power, you can select a higher instance type, which will come at a higher cost.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft3aeufrdmu050llzcr7a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft3aeufrdmu050llzcr7a.png" alt="aws instance type section" width="790" height="281"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the Key pair section, click &lt;strong&gt;Create new key pair&lt;/strong&gt; to generate a new key pair. This key pair will be used to securely connect to your AWS EC2 Ubuntu instance using SSH.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1fyld67tx0twrqfhhfso.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1fyld67tx0twrqfhhfso.png" alt="aws key pair section" width="796" height="239"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will next be prompted to set up your Key pair. Enter a Key pair name, keep the default options, and click on &lt;strong&gt;Create key pair&lt;/strong&gt;. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Once you click &lt;strong&gt;Create key pair&lt;/strong&gt;, your Key pair will be downloaded automatically.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdv6t797kc1gn1oxrpvrh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdv6t797kc1gn1oxrpvrh.png" alt="aws ec2 key pair section prompt" width="618" height="647"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;Network Settings&lt;/strong&gt; section, leave the first option as default. Beside the SSH checkbox, click the dropdown menu to select the location from which you want to connect to your instance.&lt;/p&gt;

&lt;p&gt;There are three options available in the dropdown menu:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;0.0.0.0/0&lt;/strong&gt; option allows you to connect to your instance from any machine.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;custom&lt;/strong&gt; option provides greater control over who and where your instance can accept connections.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;My IP&lt;/strong&gt; option allows you to &lt;strong&gt;only&lt;/strong&gt; connect to your instance from your local machine. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finally, enable the HTTP and HTTPS options to ensure your instance is accessible via the web. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fosylc2x1g4k3m1phznwx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fosylc2x1g4k3m1phznwx.png" alt="aws network and setting section" width="726" height="309"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Keep the default options for the &lt;strong&gt;Configure storage&lt;/strong&gt; and &lt;strong&gt;Advanced details&lt;/strong&gt; sections, as they offer the best performance for your EC2 instance. However, if you have specific requirements, you can customize them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flckx4nf2twg0ewzfdzdh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flckx4nf2twg0ewzfdzdh.png" alt="aws configure storage and advanced details section screenshot" width="768" height="537"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click the &lt;strong&gt;Launch instance&lt;/strong&gt; button to  launch your instance. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fymw8d2s3gt9temtv383k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fymw8d2s3gt9temtv383k.png" alt="aws instance being launched screenshot" width="800" height="175"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;You have successfully launched your instance. Next, you will establish a secure SSH connection to your instance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6u5zw4ppcuxni0ndiyf1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6u5zw4ppcuxni0ndiyf1.png" alt="successful aws instance launch screenshot" width="619" height="166"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2. Connect to your AWS EC2 Ubuntu Instance
&lt;/h2&gt;

&lt;p&gt;You will establish a connection to your AWS EC2 Ubuntu instance using SSH. SSH ensures secure and encrypted access to your instance. To authenticate the connection, you will use the key pair you created earlier to verify your identity and access the instance.&lt;/p&gt;

&lt;p&gt;Navigate to your EC2 dashboard and click on &lt;strong&gt;Instances (running)&lt;/strong&gt; in the resources tab to access your running instance(s). &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwtjnmtkxqxl4vxaac260.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwtjnmtkxqxl4vxaac260.png" alt="aws ec2 dashboard screenshot" width="800" height="303"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After navigating to the &lt;strong&gt;Instances&lt;/strong&gt; page, click on the instance that you created recently.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwaubddaq6otb359ovsnj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwaubddaq6otb359ovsnj.png" alt="aws instances page screenshot" width="800" height="205"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, click on the &lt;strong&gt;connect&lt;/strong&gt; button located in the top-right corner of your screen. This will take you to the &lt;strong&gt;Connect to Instance&lt;/strong&gt; page, where you can connect to your instance via several options. &lt;/p&gt;

&lt;p&gt;Select the &lt;strong&gt;SSH client&lt;/strong&gt; tab to review your connection details. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy2thhcpw8o7j5ehdlerf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy2thhcpw8o7j5ehdlerf.png" alt="aws ec2 connect to instance page screenshot" width="800" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To connect to your instance, open Git Bash, navigate to the directory where your Key pair was downloaded, and execute the following commands: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Press CTRL + C to copy and CTRL + Shift + Insert to paste in Git Bash.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod &lt;/span&gt;400 &lt;span class="s2"&gt;"your-key-pair-name"&lt;/span&gt;
ssh &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"your-key-pair-name"&lt;/span&gt; ubuntu@ec2-&lt;span class="k"&gt;*&lt;/span&gt;-&lt;span class="k"&gt;*&lt;/span&gt;-&lt;span class="k"&gt;*&lt;/span&gt;.eu-north-1.compute.amazonaws.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After executing the command, you will get the following prompt: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;The authenticity of host 'ec2-*-*-*-*.eu-north-1.compute.amazonaws.com (*.*.*.*)' can't be established.&lt;br&gt;
ED25519 key fingerprint is SHA256:&amp;lt;some-text&amp;gt;.&lt;br&gt;
This key is not known by any other names.&lt;br&gt;
Are you sure you want to continue connecting (yes/no/[fingerprint])?&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Type &lt;strong&gt;&lt;code&gt;yes&lt;/code&gt;&lt;/strong&gt; and hit the &lt;strong&gt;ENTER&lt;/strong&gt; button to proceed. &lt;/p&gt;

&lt;p&gt;If connected, your current directory should change to:&lt;br&gt;
&lt;strong&gt;&lt;code&gt;ubuntu@ip-your-ip:~$&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You have now successfully connected to your AWS EC2 Ubuntu instance. The next step is to update and upgrade your instance to ensure you have the latest security patches and features. &lt;/p&gt;
&lt;h2&gt;
  
  
  Step 3: Update and Upgrade your instance.
&lt;/h2&gt;

&lt;p&gt;Here, you will update and upgrade your instance to ensure it is up to date with the latest updates and upgrades.&lt;/p&gt;

&lt;p&gt;Run the following commands to update and upgrade your instance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update 
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt upgrade
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you run the &lt;strong&gt;&lt;code&gt;sudo apt upgrade&lt;/code&gt;&lt;/strong&gt; command, you may get this message:&lt;br&gt;
&lt;code&gt;After this operation, 36.9 KB of additional disk space will be used. Do you want to continue?[Y/n]&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;Type &lt;strong&gt;&lt;code&gt;Y&lt;/code&gt;&lt;/strong&gt; and press the &lt;strong&gt;ENTER&lt;/strong&gt; key to continue.&lt;/p&gt;

&lt;p&gt;Next, you may get a prompt to upgrade the kernel. Press the &lt;strong&gt;ENTER&lt;/strong&gt; button to proceed with the upgrade. Once you do that, a new prompt will appear where you will check specific values. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo646a8vknxvozqcy72y6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo646a8vknxvozqcy72y6.png" alt="ec2 ubuntu instance kernel upgrade prompt screenshot" width="735" height="504"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To continue, navigate the list of services using the &lt;strong&gt;ARROW&lt;/strong&gt; keys. Use the &lt;strong&gt;SPACEBAR&lt;/strong&gt; key to mark each unchecked checkbox. Once all the checkboxes are marked, press &lt;strong&gt;ENTER&lt;/strong&gt; to complete the process.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwh9inuckcb2clji1rbq0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwh9inuckcb2clji1rbq0.png" alt="items needed to be upgraded in your ec2 instance screenshot" width="733" height="504"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Your instance is now ready for use. Next, you will set up PostgreSQL.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 4: Setting up a PostgreSQL Database.
&lt;/h2&gt;

&lt;p&gt;In this step, you will install, and set-up PostgreSQL for your application on your EC2 instance. While you could have used other databases and saved time, being able to set up a traditional, relational database like PostgreSQL in a Linux environment is a valuable skill.&lt;/p&gt;

&lt;p&gt;It is recommended to create a database for your application in your local environment and then transfer a copy of it to your instance, rather than creating a new database on your instance. &lt;/p&gt;

&lt;p&gt;This approach saves time, particularly if you already have a database on your local environment. Additionally, transferring a copy of your local database ensures data accuracy, and consistency as your local database may contain a large amount of data.&lt;/p&gt;

&lt;p&gt;Run the commands below in your local environment using the command prompt or any terminal of your choice to: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;connect to postgres&lt;/li&gt;
&lt;li&gt;create a new database, connect to it&lt;/li&gt;
&lt;li&gt;create a table&lt;/li&gt;
&lt;li&gt;exit
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;psql &lt;span class="nt"&gt;-U&lt;/span&gt; postgres
create database todo_app&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="se"&gt;\c&lt;/span&gt; todo_app&lt;span class="p"&gt;;&lt;/span&gt;
create table todo &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id &lt;/span&gt;BIGSERIAL NOT NULL PRIMARY KEY, newItem VARCHAR&lt;span class="o"&gt;(&lt;/span&gt;255&lt;span class="o"&gt;)&lt;/span&gt; NOT NULL&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="se"&gt;\q&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Next, use the following command to create a backup of the newly created database in your local environment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pg_dump &lt;span class="nt"&gt;-U&lt;/span&gt; postgres &lt;span class="nt"&gt;-f&lt;/span&gt; todo_app.pgsql &lt;span class="nt"&gt;-C&lt;/span&gt; todo_app 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the command above: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;pg_dump&lt;/code&gt;&lt;/strong&gt; is a CLI tool for creating database backups.
&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;&lt;code&gt;-U&lt;/code&gt;&lt;/strong&gt; flag specifies the user to connect to PostgreSQL with.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;&lt;code&gt;-f&lt;/code&gt;&lt;/strong&gt; flag specifies the output file, which in this case is &lt;strong&gt;&lt;code&gt;todo_app.pgsql&lt;/code&gt;&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;&lt;code&gt;-C&lt;/code&gt;&lt;/strong&gt; flag is used to include commands for creating the &lt;strong&gt;&lt;code&gt;todo_app&lt;/code&gt;&lt;/strong&gt; database in the backup file specified by &lt;strong&gt;&lt;code&gt;-f&lt;/code&gt;&lt;/strong&gt;. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After running the &lt;strong&gt;&lt;code&gt;pg_dump&lt;/code&gt;&lt;/strong&gt; command, the &lt;strong&gt;&lt;code&gt;todo_app.pgsql&lt;/code&gt;&lt;/strong&gt; file will be downloaded in the current directory. Move the backup file to the directory where your AWS Key pair is. Your key pair will be needed to authenticate your connection and accept incoming files. &lt;/p&gt;

&lt;p&gt;You will use the &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Secure_copy_protocol" rel="noopener noreferrer"&gt;SCP&lt;/a&gt;&lt;/strong&gt; protocol to move your backup file to the home directory of your Ubuntu instance. To do this, run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;scp &lt;span class="nt"&gt;-i&lt;/span&gt; your-key-pair-name todo_app.pgsql ubuntu@ec2-&lt;span class="k"&gt;*&lt;/span&gt;-&lt;span class="k"&gt;*&lt;/span&gt;-&lt;span class="k"&gt;*&lt;/span&gt;-&lt;span class="k"&gt;*&lt;/span&gt;.eu-north-1.compute.amazonaws.com:/home/ubuntu/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the transfer was successful, you should get this message: &lt;br&gt;
&lt;code&gt;todo_app.pgsql      100% 2372    11.3KB/s   00:00&lt;/code&gt;                                                            &lt;/p&gt;

&lt;p&gt;Now that you have successfully created and transferred a copy of your local database to your instance. Head back to Git Bash to set up PostgreSQL in your instance. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;If you get logged out of your session, run the SSH command again to log back in.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"your-key-pair-name"&lt;/span&gt; ubuntu@ec2-&lt;span class="k"&gt;*&lt;/span&gt;-&lt;span class="k"&gt;*&lt;/span&gt;-&lt;span class="k"&gt;*&lt;/span&gt;.eu-north-1.compute.amazonaws.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To install PostgreSQL on your instance, use the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;postgresql postgresql-contrib &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After installing PostgreSQL, a default user called &lt;strong&gt;&lt;code&gt;postgres&lt;/code&gt;&lt;/strong&gt; is created. You can view the user by running the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo cat&lt;/span&gt; /etc/passwd | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; postgres
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;: &lt;br&gt;
&lt;code&gt;postgres:x:115:123:PostgreSQL administrator,,,:/var/lib/postgresql:/bin/bash&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To set up PostgreSQL, switch to the &lt;strong&gt;&lt;code&gt;postgres&lt;/code&gt;&lt;/strong&gt; user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; postgres
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If connected, your current directory should change to: &lt;br&gt;
&lt;strong&gt;&lt;code&gt;postgres@ip-your-ip:~&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a new user using the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;createuser &lt;span class="nt"&gt;--interactive&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will be prompted for the following information. Enter your answers accordingly: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enter name of role to add: ubuntu &lt;/li&gt;
&lt;li&gt;Shall the new role be a superuser? n
&lt;/li&gt;
&lt;li&gt;Shall the new role be allowed to create databases? y&lt;/li&gt;
&lt;li&gt;Shall the new role be allowed to create more new roles? n &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Exit the &lt;code&gt;postgres&lt;/code&gt; user using the command:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Use the command below to create a password for the &lt;code&gt;ubuntu&lt;/code&gt; user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; psql &lt;span class="nt"&gt;-d&lt;/span&gt; postgres
 ALTER USER ubuntu PASSWORD &lt;span class="s1"&gt;'password'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="se"&gt;\q&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;If you are curious why you can connect to your database using &lt;strong&gt;&lt;code&gt;psql -d &amp;lt;database&amp;gt;&lt;/code&gt;&lt;/strong&gt; without specifying a user, this happens because PostgreSQL will try to connect with the same user as your logged-in user, which in this case is &lt;strong&gt;ubuntu&lt;/strong&gt;. If the user &lt;strong&gt;ubuntu&lt;/strong&gt; exists in Postgres, the connection will go through without being prompted for a password, as PostgreSQL uses peer connections for local connections.&lt;/em&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, create a database and import the contents of the backup database file you created in your local environment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;psql &lt;span class="nt"&gt;-d&lt;/span&gt; postgres
create database todo_app&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="se"&gt;\q&lt;/span&gt; 
psql todo_app &amp;lt; /home/ubuntu/todo_app.pgsql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;: &lt;br&gt;
&lt;code&gt;.&lt;br&gt;
.&lt;br&gt;
.&lt;br&gt;
ALTER TABLE&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To connect to your &lt;strong&gt;&lt;code&gt;todo_app&lt;/code&gt;&lt;/strong&gt; database, execute the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;psql &lt;span class="nt"&gt;-d&lt;/span&gt; todo_app
&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; from todo&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="se"&gt;\q&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your PostgreSQL database is ready, you can proceed to set up your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Set up your application
&lt;/h2&gt;

&lt;p&gt;Now, you will clone the application code from &lt;strong&gt;&lt;a href="https://github.com/backendbro/todo-app-ubuntu.git" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/strong&gt; and get your server and client ready for deployment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Server set up
&lt;/h3&gt;

&lt;p&gt;To install &lt;strong&gt;&lt;a href="https://nodejs.org/en" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt;&lt;/strong&gt; run the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://deb.nodesource.com/setup_20.x | &lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; bash -
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; nodejs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;You may be prompted by the kernel, press &lt;strong&gt;ENTER&lt;/strong&gt; to proceed.&lt;/em&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Clone the application into your Ubuntu instance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~
git clone https://github.com/backendbro/todo-app-ubuntu.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install the dependencies required by the server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;todo-app-ubuntu/server 
npm &lt;span class="nb"&gt;install 
sudo &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; nodemon
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When working in a production environment, it's not recommended to run &lt;strong&gt;&lt;code&gt;node server.js&lt;/code&gt;&lt;/strong&gt; directly. This is because the Express server will shut down whenever you exit your instance. To avoid this, you can use &lt;strong&gt;&lt;a href="https://pm2.keymetrics.io/" rel="noopener noreferrer"&gt;PM2&lt;/a&gt;&lt;/strong&gt;. PM2 is a process manager that ensures your Express server stay up and running at all times. &lt;/p&gt;

&lt;p&gt;To install PM2 globally, run the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;pm2 &lt;span class="nt"&gt;-g&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before starting your server, compile your Typescript server with:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Now, start your server using PM2 by running the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~
pm2 start /home/ubuntu/todo-app-ubuntu/server/dist/server.js &lt;span class="nt"&gt;--name&lt;/span&gt; todo-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, configure PM2 to automatically restart your Express server in case of a crash or reboot using the command:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;: &lt;br&gt;
&lt;code&gt;[PM2] Init System found: systemd&lt;br&gt;
[PM2] To setup the Startup Script, copy/paste the following command:&lt;br&gt;
sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u ubuntu --hp /home/ubuntu&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To complete the setup for PM2, copy and run the startup script. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Ensure that you copy the script from your instance as yours may differ. The command below is only an example to guide you on what to copy and run.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo env &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd &lt;span class="nt"&gt;-u&lt;/span&gt; ubuntu &lt;span class="nt"&gt;--hp&lt;/span&gt; /home/ubuntu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, save your current list of running processes:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Client set up
&lt;/h3&gt;

&lt;p&gt;After starting the server, install the necessary dependencies and run the build command to prepare the client.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~ 
&lt;span class="nb"&gt;cd &lt;/span&gt;todo-app-ubuntu/client 
npm &lt;span class="nb"&gt;install
&lt;/span&gt;npm run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the next step, you will configure Nginx to serve your client so it can be accessible on the web.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Installing and Configuring Nginx
&lt;/h3&gt;

&lt;p&gt;In this step, you will configure Nginx to serve your client side. You will need a domain name to complete this step. Just in case you have no money to spare, check out this video — &lt;strong&gt;&lt;a href="https://www.youtube.com/watch?v=0bmopLboeIc" rel="noopener noreferrer"&gt;Free Domain Name — Use Anywhere, No Credit Cards, NO CATCH!&lt;/a&gt;&lt;/strong&gt; for help on how to get a domain name free of cost. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can find your Public IPv4 address on your instance dashboard to set up your domain.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To get started, execute the command below to install and enable Nginx:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;nginx &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To set up an Nginx server block, navigate to the sites-available folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /etc/nginx/sites-available
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you run the &lt;strong&gt;&lt;code&gt;ls&lt;/code&gt;&lt;/strong&gt; command to list the files in the current directory, you'll find a server block named &lt;strong&gt;&lt;code&gt;default&lt;/code&gt;&lt;/strong&gt; which is responsible for handling requests that don't match any other server blocks in the &lt;strong&gt;&lt;code&gt;sites-available&lt;/code&gt;&lt;/strong&gt; directory. &lt;/p&gt;

&lt;p&gt;To view the default server block, open &lt;strong&gt;&lt;code&gt;http://&amp;lt;your-ec2-instance-Public-IPv4-address&amp;gt;&lt;/code&gt;&lt;/strong&gt; or &lt;strong&gt;&lt;code&gt;http://&amp;lt;your-domain-name&amp;gt;&lt;/code&gt;&lt;/strong&gt;  in your web browser. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs937ccfgack5auipmy8y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs937ccfgack5auipmy8y.png" alt="nginx default web display" width="712" height="286"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can use the &lt;strong&gt;&lt;code&gt;default&lt;/code&gt;&lt;/strong&gt; server block as a template to create your server block. To do this, run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo cp &lt;/span&gt;default todo_app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open the &lt;strong&gt;&lt;code&gt;todo_app&lt;/code&gt;&lt;/strong&gt; server block for configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;vi todo_app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To begin configuring the &lt;strong&gt;&lt;code&gt;todo_app&lt;/code&gt;&lt;/strong&gt; server block, press the &lt;strong&gt;&lt;code&gt;I&lt;/code&gt;&lt;/strong&gt; key on your keyboard to enter &lt;strong&gt;INSERT&lt;/strong&gt; mode. This will enable you to type in the required changes. Replace the contents in the first &lt;strong&gt;&lt;code&gt;server&lt;/code&gt;&lt;/strong&gt; block with the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="s"&gt;[::]:80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

     &lt;span class="kn"&gt;root&lt;/span&gt; &lt;span class="n"&gt;/var/www/html&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="c1"&gt;# Add index.php to the list if you are using PHP&lt;/span&gt;
     &lt;span class="kn"&gt;index&lt;/span&gt; &lt;span class="s"&gt;index.html&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

     &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;your-ec2-public-ipv4-adddress&lt;/span&gt; &lt;span class="s"&gt;your-dmain-name.com&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

     &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="kn"&gt;try_files&lt;/span&gt; &lt;span class="nv"&gt;$uri&lt;/span&gt; &lt;span class="nv"&gt;$uri&lt;/span&gt;&lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;


   &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/api/v1/todo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kn"&gt;proxy_pass&lt;/span&gt; &lt;span class="s"&gt;http://localhost:4000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="kn"&gt;proxy_http_version&lt;/span&gt; &lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;Upgrade&lt;/span&gt; &lt;span class="nv"&gt;$http_upgrade&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;Connection&lt;/span&gt; &lt;span class="s"&gt;'upgrade'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;Host&lt;/span&gt; &lt;span class="nv"&gt;$host&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="kn"&gt;proxy_cache_bypass&lt;/span&gt; &lt;span class="nv"&gt;$http_upgrade&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

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

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

&lt;/div&gt;



&lt;p&gt;Once you have made the changes, press the &lt;strong&gt;&lt;code&gt;esc&lt;/code&gt;&lt;/strong&gt; key to exit &lt;strong&gt;INSERT&lt;/strong&gt; mode. Next, type &lt;strong&gt;&lt;code&gt;:wq&lt;/code&gt;&lt;/strong&gt; and press &lt;strong&gt;ENTER&lt;/strong&gt; to exit the vim terminal.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Make sure to memorize the sequence for inserting values and exiting in vim, as you will need it later.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, enable the new server block by running the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; /etc/nginx/sites-available/todo_app /etc/nginx/sites-enabled/
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use the command below to move your client build files to the &lt;strong&gt;&lt;code&gt;root&lt;/code&gt;&lt;/strong&gt; directory specified in the &lt;strong&gt;&lt;code&gt;todo_app&lt;/code&gt;&lt;/strong&gt; server block:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo mv&lt;/span&gt; /home/ubuntu/todo-app-ubuntu/client/dist/&lt;span class="k"&gt;*&lt;/span&gt; /var/www/html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, you should be able to access your website using &lt;strong&gt;&lt;code&gt;http://&amp;lt;your-Public-IPv4-address&amp;gt;&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;http://&amp;lt;your-domain-name&amp;gt;&lt;/code&gt;&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;But, at the moment you won’t be able to make request to the Express server, because the Express server cannot access its environment variables. In the next step, you will set up your environment variable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6: Setting up environment variables
&lt;/h2&gt;

&lt;p&gt;In this step, you will configure your environment to allow your Express server to access its PORT number and the PostgreSQL database.&lt;/p&gt;

&lt;p&gt;Create a &lt;strong&gt;&lt;code&gt;.env&lt;/code&gt;&lt;/strong&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~
&lt;span class="nb"&gt;sudo &lt;/span&gt;vi .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy and paste in the following environment variables into the &lt;strong&gt;&lt;code&gt;.env&lt;/code&gt;&lt;/strong&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;4000
&lt;span class="nv"&gt;DB_USER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ubuntu
&lt;span class="nv"&gt;DB_HOST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;localhost
&lt;span class="nv"&gt;DB_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;password
&lt;span class="nv"&gt;DB_DATABASE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;todo_app
&lt;span class="nv"&gt;DB_PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;5432
&lt;span class="nv"&gt;NODE_ENV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;If you must enter a different value in the &lt;strong&gt;&lt;code&gt;.env&lt;/code&gt;&lt;/strong&gt; file, ensure there are no space(s) between the variable name, equal sign and your variable value.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Moving on, open the &lt;strong&gt;&lt;code&gt;.profile&lt;/code&gt;&lt;/strong&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;vi /home/ubuntu/.profile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enter the following command below into the &lt;strong&gt;&lt;code&gt;.profile&lt;/code&gt;&lt;/strong&gt; file to ensure your environment variables is set at all times, even when your instance reboot or crash. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Make sure to enter the command at the bottom of the &lt;strong&gt;&lt;code&gt;.profile&lt;/code&gt;&lt;/strong&gt; file&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; allexport&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;source&lt;/span&gt; /home/ubuntu/.env&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt; +o allexport
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Visual illustration:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsw3n62sp7ikw75jmyw12.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsw3n62sp7ikw75jmyw12.png" alt=".profile illustration" width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For this change to take effect, restart your instance:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;You will be logged out from your Ubuntu instance. Re-connect to move on to the next step. &lt;/p&gt;

&lt;p&gt;After setting up your environment variables, you will enable a firewall to filter specific connections.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 7: Enable firewall
&lt;/h2&gt;

&lt;p&gt;In this step, you will enable the firewall to filter the type of requests that can reach your Ubuntu instance. &lt;/p&gt;

&lt;p&gt;To allow SSH, HTTP, and HTTPS requests, run the commands:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;To apply your changes, use:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;After running the &lt;strong&gt;&lt;code&gt;sudo ufw enable&lt;/code&gt;&lt;/strong&gt; command you will receive this message: &lt;br&gt;
&lt;code&gt;Command may disrupt existing ssh connections. Proceed with operation (y|n)? y&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
Type &lt;strong&gt;&lt;code&gt;y&lt;/code&gt;&lt;/strong&gt; and press &lt;strong&gt;ENTER&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;After filtering specific requests, the next step is to enable SSL. This will ensure your website is secure, and visitors can access it without encountering pesky security warnings on their browsers. With SSL, your site will be safe and trustworthy.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 8: Enable SSL
&lt;/h2&gt;

&lt;p&gt;In this step, you will generate an SSL certificate with &lt;strong&gt;&lt;a href="https://certbot.eff.org/" rel="noopener noreferrer"&gt;Certbot&lt;/a&gt;&lt;/strong&gt; and configure &lt;strong&gt;&lt;a href="https://www.nginx.com/" rel="noopener noreferrer"&gt;Nginx&lt;/a&gt;&lt;/strong&gt; to redirect HTTP traffic to HTTPS.&lt;/p&gt;

&lt;p&gt;Install Certbot by running the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;snap &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--classic&lt;/span&gt; certbot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enable certbot using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; /snap/bin/certbot /usr/bin/certbot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Configure Cerbot for Nginx, with the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;certbot &lt;span class="nt"&gt;--nginx&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When running the certbot configure command, you will be prompted for the following. Here's how you should answer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enter email address ... ? &lt;a href="mailto:valid-email@email.com"&gt;valid-email@email.com&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;Please read the Terms of Service at ... ? Y&lt;/li&gt;
&lt;li&gt;Would you be willing, once your first certificate is successfully issued... ? N&lt;/li&gt;
&lt;li&gt;Which names would you like to activate HTTPS for? ... ? 1&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your SSL certificate has been successfully set up. Now, head over to your website to view it.&lt;/p&gt;

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

&lt;p&gt;By  following this guide, you deployed a full-stack Next.js and Node.js application to an AWS EC2 Ubuntu instance. However, It is important to note that in larger applications, you might need to take a different approach where you may have to split your application services into two or more instances.&lt;/p&gt;

&lt;p&gt;In this guide, you covered the fundamental steps involved in the process. Firstly, you learned how to set up and configure an AWS instance. Next, you learned how to set up PostgreSQL on your AWS EC2 Ubuntu instance. You created a new Postgres user, and a new database. You also learned how to set up and configure Nginx and PM2 as a reverse proxy and process manager, respectively. In addition, you learned how to create an SSL certificate, which is crucial for secure and encrypted communication between your application and the user's web browser. &lt;/p&gt;

&lt;p&gt;Although some details may vary depending on your specific application, this guide provides a solid foundation for deploying an application on AWS EC2. With this knowledge, you can confidently deploy your application on AWS and take advantage of its scalability, reliability, and security. Happy deployment 😊  &lt;/p&gt;

</description>
      <category>aws</category>
      <category>devops</category>
      <category>tutorial</category>
      <category>cloud</category>
    </item>
    <item>
      <title>How to fix the “aws-elasticbeanstalk-ec2-role” error in AWS Elastic Beanstalk.</title>
      <dc:creator>Ukagha Nzubechukwu </dc:creator>
      <pubDate>Mon, 01 Apr 2024 09:38:35 +0000</pubDate>
      <link>https://forem.com/backendbro/how-to-fix-the-aws-elasticbeanstalk-ec2-role-error-in-aws-elastic-beanstalk-1ack</link>
      <guid>https://forem.com/backendbro/how-to-fix-the-aws-elasticbeanstalk-ec2-role-error-in-aws-elastic-beanstalk-1ack</guid>
      <description>&lt;p&gt;If you're reading this, chances are you have encountered the "aws-elasticbeanstalk-ec2-role" error. This error message is usually caused by missing security configurations, associated with the EC2 instance that Elastic Beanstalk launches. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fug7acp4mh0llj2gxbj7o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fug7acp4mh0llj2gxbj7o.png" alt="aws-elasticbeanstalk-ec2-role error screenshot" width="678" height="81"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this guide, you will learn how to troubleshoot and fix the "aws-elasticbeanstalk-ec2-role" error.&lt;/p&gt;

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

&lt;p&gt;To complete this guide, you'll need the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;An &lt;a href="https://aws.amazon.com/" rel="noopener noreferrer"&gt;AWS&lt;/a&gt; account. &lt;/li&gt;
&lt;li&gt;Some familiarity with &lt;a href="https://aws.amazon.com/iam/" rel="noopener noreferrer"&gt;AWS IAM&lt;/a&gt; and &lt;a href="https://aws.amazon.com/elasticbeanstalk/" rel="noopener noreferrer"&gt;AWS Elastic Beanstalk&lt;/a&gt;. If you are not familiar with the following topics, check out these tutorials —  &lt;a href="https://www.youtube.com/watch?v=uiM1xzOX8Qg" rel="noopener noreferrer"&gt;Introduction to AWS Elastic Beanstalk&lt;/a&gt; and &lt;a href="http://1.%20https://www.youtube.com/watch?v=ZNwdiYGIFrw" rel="noopener noreferrer"&gt;Lab 1 Introduction to AWS IAM&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Understanding the "aws-elasticbeanstalk-ec2-role" error
&lt;/h2&gt;

&lt;p&gt;It's important to understand the nature and cause of the error before attempting to solve it.&lt;/p&gt;

&lt;p&gt;In AWS, instance profiles are used to give permissions to EC2 instances. If an instance profile lacks the necessary permissions or configurations, the associated EC2 instance will not have access to AWS resources like S3, RDS, DynamoDB, and much more. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An instance profile is a container for an AWS IAM role that you can assign to an EC2 instance. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa3ttnv8lvkaybkpgymel.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa3ttnv8lvkaybkpgymel.png" alt="An image depicting the relationship between an instance profile and an AWS service like EC2" width="800" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The "aws-elasticbeanstalk-ec2-role" error occurs while setting up an environment in the Elastic Beanstalk console. The error originates when you choose the &lt;strong&gt;Create and use a new service role&lt;/strong&gt; option and do not provide an EC2 instance profile with the necessary permissions. It's important to note that this error is due to AWS security guidelines.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffebbnfv5mogtuzcjkk7b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffebbnfv5mogtuzcjkk7b.png" alt="AWS Configure service access page screenshot" width="800" height="640"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Way back, AWS services like EC2 were allowed to create a default “aws-elasticbeanstalk-ec2-role” instance profile on the spot, but this practice has been changed in line with security best practices.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to fix the “aws-elasticbeanstalk-ec2-role” error
&lt;/h2&gt;

&lt;p&gt;To fix the "aws-elasticbeanstalk-ec2-role" error, create an instance profile and assign it the necessary roles and permissions. &lt;/p&gt;

&lt;p&gt;Step 1. &lt;strong&gt;Create a new role&lt;/strong&gt;: In this step, you will create a role. &lt;/p&gt;

&lt;p&gt;To create a role, visit the &lt;a href="https://us-east-1.console.aws.amazon.com/iam/home?region=eu-north-1#/home" rel="noopener noreferrer"&gt;IAM&lt;/a&gt; page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7lg932shgixkwj4ujdwz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7lg932shgixkwj4ujdwz.png" alt="The AWS IAM page screenshot" width="688" height="357"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the left-hand corner, under the &lt;strong&gt;Access management&lt;/strong&gt; dropdown, click &lt;strong&gt;Role&lt;/strong&gt; to create a role.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2b66vkltqhpdpx46w22t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2b66vkltqhpdpx46w22t.png" alt="AWS IAM Access management dropdown screenshot" width="264" height="289"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once directed to the Roles page, click &lt;strong&gt;Create role&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3cyn6iuba2webwysfe3v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3cyn6iuba2webwysfe3v.png" alt="AWS IAM Role page screenshot" width="677" height="240"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To continue, keep the default &lt;strong&gt;Trusted entity type&lt;/strong&gt; option. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0wofz1wi6imhh2j6133f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0wofz1wi6imhh2j6133f.png" alt="AWS IAM ROLE Trust entity type option" width="683" height="479"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;Service or use case&lt;/strong&gt; field, select EC2 and click &lt;strong&gt;Next&lt;/strong&gt; to add permissions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0mghwrna936zqss32st8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0mghwrna936zqss32st8.png" alt="AWS IAM Role Service or use case option" width="610" height="366"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Step 2. &lt;strong&gt;Add permissions&lt;/strong&gt;: After creating a role, you need to assign permissions to define the actions that the EC2 instance launched by Elastic Beanstalk can perform on AWS resources.&lt;/p&gt;

&lt;p&gt;Search and select the following permissions listed below:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AWSElasticBeanstalkWebTier&lt;/li&gt;
&lt;li&gt;AWSElasticBeanstalkWorkerTier&lt;/li&gt;
&lt;li&gt;AWSElasticBeanstalkMulticontainerDocker&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw4e5gyw20xuoondtubcn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw4e5gyw20xuoondtubcn.png" alt="AWS Add Permission page screenshot" width="800" height="213"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once completed, click &lt;strong&gt;Next&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Step 3. &lt;strong&gt;Review your details:&lt;/strong&gt; Once directed to the review page, enter a role name.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcmmt0vxsa0nvbprejoll.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcmmt0vxsa0nvbprejoll.png" alt="AWS Review Role Details page screenshot" width="800" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Scroll down to add a tag name, although this is optional. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkdhv87v0ol9dsu2zkg63.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkdhv87v0ol9dsu2zkg63.png" alt="AWS Review Role page: Add tag screenshot" width="651" height="274"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you have filled out all the required information, carefully review your role details. If you are satisfied with them, click &lt;strong&gt;Create Role&lt;/strong&gt; to complete the process. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjwpofwk04bmmajrsil2f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjwpofwk04bmmajrsil2f.png" alt="AWS Instance profile" width="800" height="37"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You have successfully created an instance profile. Now, verify the solution by setting up an environment in Elastic Beanstalk.&lt;/p&gt;

&lt;p&gt;Step 4: &lt;strong&gt;Setting up an Elastic Beanstalk environment:&lt;/strong&gt; Now that you have created an instance profile for the EC2 service. Set up an Elastic Beanstalk environment. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;To ensure this guide stays focused on the intended subject matter, I will not cover all the steps required to set up an Elastic Beanstalk environment. I will proceed directly to the '&lt;em&gt;configure service access&lt;/em&gt;' page. If you need guidance on how to set up an Elastic Beanstalk environment, I recommend checking out this video — &lt;a href="https://www.youtube.com/watch?v=2BoVhej0QVI" rel="noopener noreferrer"&gt;Deploy a Web Application Using Elastic Beanstalk&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the "configure service access" page, select &lt;strong&gt;Create and use new service role&lt;/strong&gt;. In the &lt;strong&gt;EC2 instance profile&lt;/strong&gt;, field select the newly created instance profile. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Once you have filled out the other fields on the following pages, you can proceed to create your environment.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9ja3w2zrurephn1qlz5m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9ja3w2zrurephn1qlz5m.png" alt="AWS Elastic Beanstalk configure service access" width="800" height="636"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Viola! The solution worked! &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftjneti4af64zpafck72x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftjneti4af64zpafck72x.png" alt="AWS Elastic Beanstalk successfully instance launch screenshot" width="800" height="98"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;In this guide, you learned how to fix the "aws-elasticbeanstalk-ec2-role" error in AWS Elastic Beanstalk. By understanding the causes of this error, such as misconfigured IAM roles or insufficient permissions, you can take appropriate steps to rectify this issue anytime it comes up.  &lt;/p&gt;

&lt;p&gt;If you need any more help with debugging, don't hesitate to ask. Happy debugging 🛠️👩🏻‍💻, and have a fantastic day!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>debug</category>
      <category>elasticbeanstalk</category>
      <category>iam</category>
    </item>
    <item>
      <title>Boost your learning with Glasp: A Comprehensive Guide.</title>
      <dc:creator>Ukagha Nzubechukwu </dc:creator>
      <pubDate>Tue, 05 Mar 2024 12:43:05 +0000</pubDate>
      <link>https://forem.com/backendbro/boost-your-learning-with-glasp-a-comprehensive-guide-37c6</link>
      <guid>https://forem.com/backendbro/boost-your-learning-with-glasp-a-comprehensive-guide-37c6</guid>
      <description>&lt;p&gt;Reading content online has become an integral part of our daily routine, especially in today's digital world. Whether it's staying up-to-date with the latest news about our favorite celebrities or researching various topics of interest, the internet provides us with a vast range of written and visual content to consume. However, organizing, retaining, and assimilating all this information can be challenging. This is where Glasp comes in handy. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc5xxqu8j4v6khnqjlo79.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc5xxqu8j4v6khnqjlo79.png" alt="Glasp logo" width="225" height="225"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Glasp is an online tool that allows you to highlight and take note of important passages that you find meaningful while learning. With the ever-increasing amount of online content, Glasp aims to improve our online learning experience by providing an efficient way to organize and share important information.&lt;/p&gt;

&lt;p&gt;In this article, we will provide you with a step-by-step guide on how to use Glasp to boost your learning. So, let's get started!&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisite
&lt;/h2&gt;

&lt;p&gt;Make sure that you have the following to get the most out of this guide: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A desktop or laptop. &lt;/li&gt;
&lt;li&gt;A web browser. &lt;/li&gt;
&lt;li&gt;A cup of coffee. &lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  An Introduction to Glasp
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is Glasp
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://glasp.co/" rel="noopener noreferrer"&gt;Glasp&lt;/a&gt; stands for &lt;strong&gt;Greatest Legacy Accumulated as Shared Proof&lt;/strong&gt;. It's a free and open-source browser extension. &lt;/p&gt;

&lt;h3&gt;
  
  
  Glasp highlighting and note-taking feature
&lt;/h3&gt;

&lt;p&gt;Glasp allows users to highlight and note important passages from online content such as articles, PDFs, and more. Its user-friendly interface and customizable settings make it easy to use. Additionally, every highlight preserves essential metadata such as the headline, URL, excerpt, and tags. Glasp also provides users with transcripts of YouTube videos, which they can use to leave notes at important timestamps. This feature allows users to pick up where they left off easily.&lt;/p&gt;

&lt;p&gt;Glasp is a breath of fresh air on how users consume content online, allowing them to quickly find, highlight, and save important parts of lengthy articles, documents, and other publications. Glasp takes highlighting and note-taking a step further by giving users the option to keep their collections private or share them publicly with others via social media platforms. &lt;/p&gt;

&lt;h3&gt;
  
  
  Glasp community building
&lt;/h3&gt;

&lt;p&gt;Glasp fosters collaboration and community building by recommending online groups and collections based on your activity. Users can also search through and follow other public Glasp collections for research or leisure reading.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw27fvpi0b4v59gian2gp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw27fvpi0b4v59gian2gp.png" alt="Glasp for you recommendations" width="800" height="414"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Glasp tag system
&lt;/h3&gt;

&lt;p&gt;When there are many articles to keep track of, it can become overwhelming to manage them all. Glasp offers a tag system to help you stay organized. Once you highlight an article, you can add as many tags as you want to help categorize it. This makes it much simpler and more efficient to keep track of the information you need.&lt;/p&gt;

&lt;h3&gt;
  
  
  Glasp user profile
&lt;/h3&gt;

&lt;p&gt;Glasp offers its users an easy-to-navigate profile page that allows them to easily access their highlights, notes, highlighted articles, tags, views, and much more. &lt;br&gt;
The user's profile page features a green panel on the left-hand side, which enables them to keep track of their daily highlights. Some users find this feature motivating as it allows them to keep streaks, while others may use it to review the articles they have highlighted so far.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1v6v3v5l69otb1xmkdap.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1v6v3v5l69otb1xmkdap.png" alt="Glasp activity graph" width="284" height="263"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Glasp cross-platform compatibility
&lt;/h3&gt;

&lt;p&gt;Glasp allows users to easily import and export their highlights and notes. If you have any highlights or notes saved on your Kindle or any other e-reading platform, you can easily import them into Glasp. Additionally, you can download your activity on Glasp by exporting it as a file. You have the option to download your highlights and notes as a file in various formats such as Text, CSV, HTML, MD, and PNG (image). You can choose to download your highlights and notes by article or all at once.&lt;/p&gt;

&lt;p&gt;All in all, Glasp is the ultimate companion for anyone looking to boost their reading or research skills.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing Glasp.
&lt;/h2&gt;

&lt;p&gt;Let's move on to the installation of Glasp.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Visit the &lt;a href="https://glasp.co/" rel="noopener noreferrer"&gt;Glasp website&lt;/a&gt; to download the installer. &lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Choose your preferred web browser for installing Glasp.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbcrezhxx5ldt9jrg2hvx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbcrezhxx5ldt9jrg2hvx.png" alt="Glasp-browser-installation-options" width="746" height="492"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Since I use an HP laptop with Windows installed, I will select "Install on Chrome"&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once you click "&lt;strong&gt;Install on Chrome&lt;/strong&gt;" you will be directed to the Google Chrome extension store.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Moving on, click on the "&lt;strong&gt;Add to Chrome&lt;/strong&gt;" button to download the Glasp extension.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmpb1mphuelul3khrcrck.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmpb1mphuelul3khrcrck.png" alt="Add-glasp-from-google-extension-store" width="800" height="151"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To start the installation process, click on the “&lt;strong&gt;Add extension&lt;/strong&gt;” button.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fubkr49gvww5hn3h6xk9n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fubkr49gvww5hn3h6xk9n.png" alt="Install-glasp" width="447" height="200"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Wait patiently while Glasp is being downloaded. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Once the download process is finished, Glasp will automatically install itself.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Hurray! You have successfully installed Glasp. Now, let's move on to setting up a Glasp account.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnq5fshapam9fpda6mbu5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnq5fshapam9fpda6mbu5.png" alt="Glasp-successful-installation" width="705" height="236"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up Glasp
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;To sign up, visit the &lt;a href="https://glasp.co/" rel="noopener noreferrer"&gt;Glasp website&lt;/a&gt; and click the &lt;strong&gt;Sign-up&lt;/strong&gt; button in the top right corner, or log in if you already have an account.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To finish the registration process, click on the "&lt;strong&gt;Continue with Google&lt;/strong&gt;" button. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxww9mkwwp7n3m5xc1o5y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxww9mkwwp7n3m5xc1o5y.png" alt="Glasp-sign-up" width="594" height="474"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Make sure to enable pop-up functionality in your web browser to allow Glasp to complete the registration process.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Voila! You have successfully set up a Glasp account. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh354isbbbdzricjhwfdh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh354isbbbdzricjhwfdh.png" alt="Glasp-account" width="785" height="593"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Glasp in action
&lt;/h2&gt;

&lt;p&gt;In this section, we will go over the steps to use Glasp for highlighting, taking notes, and much more. &lt;/p&gt;

&lt;h3&gt;
  
  
  Highlighting
&lt;/h3&gt;

&lt;p&gt;We will use this &lt;a href="https://dev.to/backendbro/a-step-by-step-guide-how-to-create-and-publish-an-npm-package-2off"&gt;blog post&lt;/a&gt; to illustrate how to highlight using Glasp.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Make sure you are viewing this &lt;a href="https://dev.to/backendbro/a-step-by-step-guide-how-to-create-and-publish-an-npm-package-2off"&gt;blog&lt;/a&gt;. Although you can choose any online content you prefer. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnjy6hr1mx9h7pb0t2r10.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnjy6hr1mx9h7pb0t2r10.png" alt="Blog-example" width="679" height="370"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Before highlighting, open the Glasp sidebar by clicking the extension tab on Google Chrome. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw7j308m2tcrgkq1k66ce.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw7j308m2tcrgkq1k66ce.png" alt="Google-chrome-extension" width="472" height="215"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Proceed by selecting the Glasp extension. Ensure to click only once &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F11hakidd41g5rsxd05u8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F11hakidd41g5rsxd05u8.png" alt="Glasp-extension" width="322" height="247"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;I used this method to open the Glasp sidebar because the icon may not always appear on everyone's browser, and no, it's not a bug. It's most likely due to your browser.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To start highlighting, left-click on your mouse or mousepad and drag your cursor over the text that you want to highlight. A pop-up will appear with several options, including highlighting colors, adding notes, creating a Quoteshot, and sharing on Twitter.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F93yymddzbukw89vwqo75.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F93yymddzbukw89vwqo75.png" alt="Glasp-highligting" width="735" height="219"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To continue, highlight your selected passage by clicking a color option. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7plqj16u96boud9oldpd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7plqj16u96boud9oldpd.png" alt="Color options to highlight with using Glasp" width="735" height="219"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Head over to the Glasp sidebar to view your highlighted text.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Funvh25rw3hoz5ir3zxux.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Funvh25rw3hoz5ir3zxux.png" alt="Glasp-sidebar" width="304" height="383"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In addition to highlighting, Glasp offers a range of other features. If you hover your mouse over any highlighted text in the Glasp sidebar, an ellipsis menu will appear in the top right corner. This menu provides you with access to a variety of options that can help you to better manage your highlighted content.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcbxxvrbyv0dpif3zluka.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcbxxvrbyv0dpif3zluka.png" alt="Glasp-highliting-options" width="299" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To access the list of available actions on your highlighted text, click on the ellipsis.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgmasbd4e5ycf9jvgupit.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgmasbd4e5ycf9jvgupit.png" alt="Glasp-elipsis" width="292" height="371"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can use the "&lt;strong&gt;Create Highlight Image&lt;/strong&gt;" feature to generate an image from your highlighted text.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg4yjeb3y7ob4b50i7k9l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg4yjeb3y7ob4b50i7k9l.png" alt="Glasp-highlight-image" width="545" height="614"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Glasp offers several image customization options, including orientation, background color, font style, a download button, and the ability to share on social media platforms.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Note-taking
&lt;/h3&gt;

&lt;p&gt;This section will demonstrate the two ways to take notes using Glasp.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Using the Elipsis&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click the ellipsis in the top right corner of the highlighted text in the Glasp sidebar to reveal a list of options.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcwd8abx5ie055c751n45.png" alt="Glasp elipsis menu" width="292" height="371"&gt;
&lt;/li&gt;
&lt;li&gt;To add a note, click the "&lt;strong&gt;Add a Note&lt;/strong&gt;" button.&lt;/li&gt;
&lt;li&gt;Add a note that best describes the highlighted text.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff5k33aa7iw9wy288nxql.png" alt="Taking notes using Glasp" width="303" height="392"&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Using the Pop-up palette&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Left-click on your mouse or mousepad and drag your cursor over the selected passage to display the pop-up palette. &lt;/li&gt;
&lt;li&gt;To continue, click on the "&lt;strong&gt;Add a Note&lt;/strong&gt;" icon.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8fqmnvsvi05c3tu80k6g.png" alt="Glasp add a note" width="717" height="232"&gt;
&lt;/li&gt;
&lt;li&gt;When you click the "&lt;strong&gt;Add a Note&lt;/strong&gt;" icon, Glasp will automatically highlight the selected passage and provide an input field to enter your desired note.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Comment
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;To comment, use the designated input field. Refer to the screenshot below for guidance&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzsr8jbstrex9xpbytgnv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzsr8jbstrex9xpbytgnv.png" alt="Glasp-comment" width="299" height="395"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To save your comment, click the "&lt;strong&gt;Save&lt;/strong&gt;" button. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Tag
&lt;/h3&gt;

&lt;p&gt;Adding a tag to highlight collections makes them easier to search for and categorize.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;To add a tag, click the "&lt;strong&gt;tag icon&lt;/strong&gt;" in the top left corner of the Glasp sidebar.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frctk4s1qdhi4ads5l9ad.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frctk4s1qdhi4ads5l9ad.png" alt="Glasp-tag" width="302" height="459"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Input a tag name with a maximum of 25 characters, then press &lt;strong&gt;Enter&lt;/strong&gt;.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk8hyzsoclauk6lfptstk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk8hyzsoclauk6lfptstk.png" alt="Glap-tag-name" width="300" height="459"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Yay! A tag has been added successfully. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F56b6c8qmyiumoejh24m0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F56b6c8qmyiumoejh24m0.png" alt="Glasp-tag-added" width="302" height="42"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can also add a tag using the pop-up palette by left-clicking, and dragging your cursor over the highlighted text. Then click the "&lt;strong&gt;tag icon&lt;/strong&gt;".&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4yzbchxys3za7r2u33bi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4yzbchxys3za7r2u33bi.png" alt="Glasp-tag-alternative" width="718" height="211"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Using Glasp in PDFs
&lt;/h3&gt;

&lt;p&gt;Highlighting and taking notes in PDFs using Glasp is a simple process, just like doing it on websites. However, it's important to note that Glasp can only be used on online PDFs and not on locally downloaded PDFs. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;I will be using the &lt;a href="https://web.pdx.edu/~pmoeck/books/Tipler_Llewellyn.pdf" rel="noopener noreferrer"&gt;PDF&lt;/a&gt; below. I understand that it may seem brainy, but it's just for illustrative purposes. I couldn't find a simpler PDF, so feel free to use any PDF of your choice.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwme5666bwdohi9lihjo1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwme5666bwdohi9lihjo1.png" alt="Glasp-pdf" width="766" height="427"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Load Glasp on the PDF by clicking on the Glasp icon in the top-right corner.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs479fo58htvv4i4zrwly.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs479fo58htvv4i4zrwly.png" alt="Glasp PDF icon" width="257" height="124"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Wait a few seconds while Glasp prepares your PDF for use.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;After your page has finished reloading, you can begin highlighting by left-clicking and dragging your mouse over your selected passage. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsfi6de4yw5o9gxh466ea.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsfi6de4yw5o9gxh466ea.png" alt="Highlighting PDF text using Glasp" width="459" height="189"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To highlight, click on a color option.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk1200adyoffkpnbeccww.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk1200adyoffkpnbeccww.png" alt="Glasp PDF highlighted text options" width="299" height="448"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After highlighting, you can add notes, comments, tags, or create images from the text.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Using Glasp as a YouTube companion
&lt;/h3&gt;

&lt;p&gt;When it comes to learning on YouTube, Glasp makes the perfect companion. Here are some tips to help you boost your productivity and focus while learning.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;I will use the &lt;a href="https://www.youtube.com/watch?v=3F5IaPqj7ds" rel="noopener noreferrer"&gt;YouTube video&lt;/a&gt; below as a case study, but feel free to choose any video you prefer&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpqyxmzopjca8gg5urd1w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpqyxmzopjca8gg5urd1w.png" alt="Glasp-YouTube-use-case" width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;On the left-hand side, you will find a Glasp dropdown. The Glasp dropdown also provides buttons for actions such as generating an AI summary, jumping to the current time, and copying the transcript.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs5ia6w0enxnrw6jmuuht.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs5ia6w0enxnrw6jmuuht.png" alt="Glasp-YouTube-Dropdown" width="423" height="79"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the Glasp dropdown to review the transcript of the YouTube video. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpshmwqly30k8jevftn5k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpshmwqly30k8jevftn5k.png" alt="Glasp-YouTube-Transcript" width="369" height="443"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Proceed to highlight your selected passage or timestamp. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F47v7g6o8qj9h5y1z2uw6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F47v7g6o8qj9h5y1z2uw6.png" alt="Glasp YouTube Transcript" width="377" height="441"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To generate a summary of a YouTube video, click on the &lt;strong&gt;AI icon&lt;/strong&gt; in the Glasp dropdown. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Froqww3rilv1p58z0cnv6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Froqww3rilv1p58z0cnv6.png" alt="Glasp AI summary icon" width="372" height="447"&gt;&lt;/a&gt;&lt;br&gt;
You will be redirected to &lt;a href="https://chat.openai.com/" rel="noopener noreferrer"&gt;ChatGPT&lt;/a&gt; where you can find your summary.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4calxm5bbsz1y0s5dsi5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4calxm5bbsz1y0s5dsi5.png" alt="Glasp AI summary text" width="743" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With the Glasp AI Summary, you can now get the full gist of a YouTube video in seconds.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  A view of the Glasp profile
&lt;/h3&gt;

&lt;p&gt;In the previous sections, we covered the steps to use Glasp. Now, head to your profile and view your activity so far.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Login into your &lt;a href="https://glasp.co/" rel="noopener noreferrer"&gt;Glasp account&lt;/a&gt;. &lt;/li&gt;
&lt;li&gt;
&lt;p&gt;After logging in, your profile will be displayed where you can view your activity log, including highlighted articles, notes, tags, and comments.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Psst! While you weren't looking, I highlighted some more articles.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fefe618260mtl6q99nra0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fefe618260mtl6q99nra0.png" alt="Glasp profile" width="800" height="505"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the bottom left corner, you can see your activity graph. You can maintain streaks as a way to motivate yourself to learn daily.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3njgjiy8spgyc4llrktr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3njgjiy8spgyc4llrktr.png" alt="Glasp streak" width="284" height="263"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Below your activity graph, you can find your tags. Tags help categorize your highlights and notes.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk5tn5kmpo9o7o05tri0n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk5tn5kmpo9o7o05tri0n.png" alt="GLA" width="298" height="117"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Navigate to the &lt;a href="https://glasp.co/home" rel="noopener noreferrer"&gt;homepage&lt;/a&gt; to find exciting activities, such as viewing posts and highlights from your followed users, trending topics, and more.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff9gbukg36likvxvl81e4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff9gbukg36likvxvl81e4.png" alt="Glasp homepage" width="800" height="492"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can check out the &lt;a href="https://glasp.co/explore" rel="noopener noreferrer"&gt;explore page&lt;/a&gt; on Glasp to see what others are reading in the community.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Benefits of Glasp
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Easy recollection of what you learned&lt;/strong&gt;: Glasp helps you remember what you learned previously by allowing you to highlight important passages and take notes. The act of highlighting a passage helps your memory retain that specific text, while the notes you take can serve as an excellent reference for future use. Glasp is an incredibly effective tool for boosting your learning by providing an easy and intuitive way for you to highlight and keep track of important excerpts. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Collaboration and community building&lt;/strong&gt;: Glasp is designed to help you learn and grow by sharing and viewing other people's highlights and notes. With Glasp, you can easily broaden your horizon and catch up on what you might have missed out on. The platform offers a variety of features for sharing and viewing other users' thoughts and a comment section that enables different people to share their views on a particular piece of highlighted text or note. Using Glasp, you can collaborate with your peers, friends, and colleagues to create a learning community where everyone can contribute and learn from each other. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Increased productivity&lt;/strong&gt;: Glasp is a tool that helps users increase their productivity while learning. With Glasp, users can stay focused on their learning material without the need to switch to other apps to take notes, which can be distracting. Once they're done learning or need to check something important, they can easily visit their profile. Glasp also provides users who learn using &lt;a href="https://www.youtube.com/" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt; videos with transcripts, which allows them to easily follow along with the specific video they are watching and even highlight and take notes where necessary.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cross-platform compatibility&lt;/strong&gt;: Glasp is compatible with multiple browsers, enabling users to highlight, take notes, and access their profiles on any browser of their choice. Additionally, the Glasp platform is also compatible with other e-reader devices such as Kindle. Users have the option to import or export their activity on any platform they prefer, making Glasp a convenient and accessible option for users who frequently switch between devices or platforms.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;So far, we have learned about what Glasp is and how it can be used. We have also explored its use cases, highlighting how Glasp can boost learning and productivity. Using Glasp, you can easily highlight important passages and take notes directly on web pages. The tool makes note-taking and highlighting fun and engaging, with an easy-to-use pop-up palette and a variety of soothing colors to choose from. &lt;/p&gt;

&lt;p&gt;Glasp is the perfect companion for YouTube, providing a transcript of the video and an AI-powered summary. Additionally, the platform offers many other features. You can view your activity on the Glasp profile, explore other topics of interest, comment on other people's highlights and notes, and learn from them. &lt;/p&gt;

&lt;p&gt;Overall, Glasp is an excellent tool for boosting and improving how you consume, organize, and assimilate online content. I hope this guide has been helpful to you. Happy learning! 😊&lt;/p&gt;

&lt;h2&gt;
  
  
  Credits and Further reading
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://glasp.co/" rel="noopener noreferrer"&gt;Glasp website&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Glasp documentation: 

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://glasp.co/articles/how-to-highlight-text-on-pages" rel="noopener noreferrer"&gt;How to highlight using Glasp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://glasp.co/articles/best-online-highlighters" rel="noopener noreferrer"&gt;3 best online highlighter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>productivity</category>
      <category>glasp</category>
      <category>learning</category>
      <category>highlighting</category>
    </item>
    <item>
      <title>How To Boost Your Node.js Performance by Implementing Caching With Redis.</title>
      <dc:creator>Ukagha Nzubechukwu </dc:creator>
      <pubDate>Tue, 27 Feb 2024 00:09:27 +0000</pubDate>
      <link>https://forem.com/backendbro/boost-your-nodejs-performance-a-step-by-step-guide-to-implement-caching-in-your-application-using-redis-135c</link>
      <guid>https://forem.com/backendbro/boost-your-nodejs-performance-a-step-by-step-guide-to-implement-caching-in-your-application-using-redis-135c</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;As your application grows and attracts more traffic, it becomes increasingly important to ensure faster response times. This helps prevent users from experiencing delays and frustration while using your app, as slower response times can make you lose users and revenue. By implementing caching, you can optimize and scale your application, providing users with faster response times and a great user experience.&lt;/p&gt;

&lt;p&gt;Storing frequently accessed data in a location (cache) that is quicker to access is an effective way to improve the performance of your Node.js application. Caching reduces the time and resources required to query the main memory (database), which in turn reduces server load and speeds up content delivery to users.&lt;/p&gt;

&lt;p&gt;In this guide, you will learn the fundamentals of Caching and Redis. You will also learn how to implement caching in a Node.js application using Redis. This will be done with a simple blog example built with Node.js, MongoDB, Express, and Express Handlebars. &lt;/p&gt;

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

&lt;p&gt;To follow this guide, ensure you have the following: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A basic understanding of &lt;a href="https://nodejs.org/en/download/" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt;, &lt;a href="https://expressjs.com/" rel="noopener noreferrer"&gt;Express&lt;/a&gt;, and &lt;a href="https://ejs.co/" rel="noopener noreferrer"&gt;Express handlebars&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;An &lt;a href="https://console.upstash.com/login" rel="noopener noreferrer"&gt;Upstash&lt;/a&gt; account.&lt;/li&gt;
&lt;li&gt;A MongoDB Database (&lt;a href="https://www.mongodb.com/atlas" rel="noopener noreferrer"&gt;Atlas&lt;/a&gt;). If you're unsure how to retrieve your MongoDB Atlas connection string, check out the tutorial — &lt;a href="https://dev.to/backendbro/using-mongodb-with-nodejs-175l"&gt;A step-by-step guide: How to use MongoDB with Node.js to set up MongoDB Atlas&lt;/a&gt; for guidance.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;: you can find the entire code used in this guide on &lt;a href="https://github.com/backendbro/caching-in-action-complete" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  An Introduction to Caching.
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What is a Caching?&lt;/strong&gt;&lt;br&gt;
Caching is the process of storing data in a cache.  When we query for data from a source (main memory or a database), we have to wait for some time to get a response. But if data is stored in a fast access memory like &lt;a href="https://redis.io/" rel="noopener noreferrer"&gt;Redis&lt;/a&gt;, data retrieval time can be cut in half, and we get to prevent a bottleneck caused by a large number of users trying to access the same piece of data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use case&lt;/strong&gt;&lt;br&gt;
Have you ever noticed that when you visit your favorite website, it always seems to know what you're interested in? Social media platforms like &lt;a href="https://web.facebook.com/?_rdc=1&amp;amp;_rdr" rel="noopener noreferrer"&gt;Facebook&lt;/a&gt; also use your cached information to make friend suggestions and show you posts that are relevant to your interests. By using your cached data, these websites aim to improve your user experience and make your online activities more enjoyable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cache internals and mechanism&lt;/strong&gt;&lt;br&gt;
Caches are designed to be small, fast, and lightweight. However, this limits their capacity to hold large amounts of data for extended periods. To ensure that they always have up-to-date information, caches work in tandem with databases. Because caches are small, it is important to regularly remove old or outdated data and replace it with fresher information. One technique used to accomplish this is &lt;strong&gt;Time-To-Live&lt;/strong&gt; (TTL), which moves expired data out of the cache to make room for new data. Caching algorithms are also used to evaluate the data in the cache and determine which data has the lowest priority and should be removed. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setting up a Cache network&lt;/strong&gt;&lt;br&gt;
When setting up a cache network, it's essential to consider the data that users frequently access. This is because you don't want to cache unnecessary information that will occupy valuable space. To achieve a high cache hit rate, a cache policy that works best for your application must be carefully implemented. For instance, the "&lt;strong&gt;write-through cache&lt;/strong&gt;" policy ensures that the cache and database are updated simultaneously. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr0q2974rgz7q29k7mvq6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr0q2974rgz7q29k7mvq6.png" alt="write-through cache illustration" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, there is a cost associated with this policy as it may not be suitable for write-intensive applications. This is because your application will have to store data in two locations, leading to performance issues. &lt;/p&gt;

&lt;p&gt;On the other hand, if your application is write-intensive, the "&lt;strong&gt;write-back cache&lt;/strong&gt;" may be more suitable, as it only writes data to the cache at first and later updates the database. This way, data is not stored simultaneously in two locations, preventing performance issues.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj0yq9v3bp9sicvz1mih0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj0yq9v3bp9sicvz1mih0.png" alt="write-back cache" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's crucial to consider the type of application you're building before selecting a caching policy and algorithm to prevent further problems in your application.&lt;/p&gt;
&lt;h2&gt;
  
  
  An Introduction to Redis
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What is Redis&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://redis.io/" rel="noopener noreferrer"&gt;Redis&lt;/a&gt; is an open-source, in-memory data store that can be used as a database, cache, and message broker. Redis is well-known for its high performance, flexibility, and scalability, making it a popular choice for modern web applications.&lt;/p&gt;

&lt;p&gt;Redis's in-memory data model allows it to store and access data directly from the server's RAM, rather than being written to disk like traditional databases. As a result, Redis offers faster data access and retrieval times and lower latency since disk I/O operation is reduced. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Redis data storage&lt;/strong&gt;&lt;br&gt;
In addition, Redis stores data using a key-value pair, where each key is a string, and each value can be any of the supported data structures. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkl4nyeatbhwrrresgtn3.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkl4nyeatbhwrrresgtn3.jpg" alt="What is Key Value Pair? How can you automate key-value pair extraction?" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Redis is capable of supporting a variety of data structures, including strings, hashes, lists, sets, and sorted sets, making it well-suited for real-time analytics, caching, and message passing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use case&lt;/strong&gt;&lt;br&gt;
Redis is a powerful tool for caching data. Its high throughput and availability make it an excellent choice for implementing caching, as it ensures a high cache hit rate. This means that frequently accessed data are served up faster, reducing the time it takes to retrieve data from the main memory (database). Redis is also used for several use cases such as chat, messaging, queues, gaming leaderboards, session stores, and much more.&lt;/p&gt;

&lt;p&gt;Overall, Redis is a powerful and versatile tool that can help developers build faster, more scalable, and more reliable applications. &lt;/p&gt;
&lt;h2&gt;
  
  
  Setting up Redis.
&lt;/h2&gt;

&lt;p&gt;In this guide, we will use a Redis server service named &lt;a href="https://console.upstash.com/login" rel="noopener noreferrer"&gt;Upstash&lt;/a&gt;. Although other web services such as &lt;a href="https://aws.amazon.com/lambda/" rel="noopener noreferrer"&gt;AWS Lambda&lt;/a&gt;, &lt;a href="https://azure.microsoft.com/en-us/products/functions/" rel="noopener noreferrer"&gt;Azure Functions&lt;/a&gt;, and &lt;a href="https://cloud.google.com/functions/" rel="noopener noreferrer"&gt;Google Cloud Functions&lt;/a&gt; offer Redis cache, we will use Upstash to navigate this tutorial. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;To get started, visit &lt;a href="https://console.upstash.com/login" rel="noopener noreferrer"&gt;Upstash&lt;/a&gt; to create an account. If you already have one, you can log in.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After setting up your account, click the "&lt;strong&gt;Create database&lt;/strong&gt;" button to create a Redis database.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu9e69ionuv9i1qjl2m24.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu9e69ionuv9i1qjl2m24.png" alt="Upstash-create-database-image" width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fill out the form in the pop-up and click "&lt;strong&gt;Create&lt;/strong&gt;" to proceed. Refer to the screenshot below for help:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fusfwufmt95y37eh7klgp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fusfwufmt95y37eh7klgp.png" alt="Upstash-pop-up" width="526" height="513"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Viola! we have successfully set up a Redis cache. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frfysgek9qa0lqu5k3t5y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frfysgek9qa0lqu5k3t5y.png" alt="Upstash-dashboard" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To retrieve your connection string; scroll down, click on the “&lt;strong&gt;Node&lt;/strong&gt;” tab, and select "&lt;strong&gt;ioredis&lt;/strong&gt;". Refer to the screenshot below for help.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx6h5uznav99tubtfr6k2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx6h5uznav99tubtfr6k2.png" alt="Node-tab" width="800" height="502"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Hover over the password tab to copy your password. Then, replace the star symbols in your connection string with your actual password.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure to keep your Redis connection string safe and ready, as it will be needed in the next section when we implement application caching.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Caching in Action
&lt;/h2&gt;

&lt;p&gt;To illustrate how caching improves the performance of a Node.js application, we will use a basic blog as an example. This blog has three main functionalities: creating a post, listing all posts, and viewing a post. Let's begin! &lt;/p&gt;
&lt;h3&gt;
  
  
  Project setup
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;To proceed, go to &lt;a href="https://github.com/" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; and clone this &lt;a href="https://github.com/backendbro/caching-in-action-boilerplate" rel="noopener noreferrer"&gt;boilerplate&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;After cloning the boilerplate, run the following commands in your terminal one after the other to install all the dependencies required:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; 
&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="nx"&gt;ioredis&lt;/span&gt;   

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



&lt;h4&gt;
  
  
  Quick note:
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/backendbro/caching-in-action-boilerplate" rel="noopener noreferrer"&gt;ioredis&lt;/a&gt;&lt;/strong&gt; &lt;em&gt;is a popular Node.js client library with a simple and high-performance interface that helps developers to easily interact with Redis servers&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Create a &lt;strong&gt;&lt;code&gt;.env&lt;/code&gt;&lt;/strong&gt; file in the root directory.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh7-us.googleusercontent.com%2FtEPWI6C_OKohh2irH6rIrzkDg9c95rsrfHwqQn4PgaLlKuhO-hSoCd4XVkbTpGCov3Tl9RKlvPS5WGogycmbIc3o2AF_has8lqITYUOImcbX-m1lV0ZCFPHCOzCooccfaaYLo0EM71A3wtPFKUqPeyg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh7-us.googleusercontent.com%2FtEPWI6C_OKohh2irH6rIrzkDg9c95rsrfHwqQn4PgaLlKuhO-hSoCd4XVkbTpGCov3Tl9RKlvPS5WGogycmbIc3o2AF_has8lqITYUOImcbX-m1lV0ZCFPHCOzCooccfaaYLo0EM71A3wtPFKUqPeyg" alt="Process.env" width="622" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, enter the following environment variables into the newly created file.&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8000&lt;/span&gt; 
&lt;span class="nx"&gt;mongodb_uri&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;yourMongoDBConnectionString&lt;/span&gt;
&lt;span class="nx"&gt;redis_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;yourRedisConnectionString&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;.&lt;/p&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;To ensure that the application runs smoothly, execute the following command:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;run&lt;/span&gt; &lt;span class="nx"&gt;dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkq2r0wnldkxmgdy0h4ju.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkq2r0wnldkxmgdy0h4ju.png" alt="npm-run-dev" width="698" height="255"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;To access the application, open your web browser and type in the following URL — &lt;strong&gt;&lt;code&gt;localhost:8000/dashboard&lt;/code&gt;&lt;/strong&gt;. This will take you directly to the dashboard.&lt;br&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiqo26rvae9us7ctrgp2z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiqo26rvae9us7ctrgp2z.png" alt="boilerplate" width="775" height="337"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;/ol&gt;

&lt;h3&gt;
  
  
  Writing code
&lt;/h3&gt;

&lt;p&gt;In the section: "&lt;strong&gt;Introduction to Caching&lt;/strong&gt;", we discussed caching policies and how selecting the right one can boost an application's performance. In this example blog, we will implement the "&lt;strong&gt;write-through cache&lt;/strong&gt;" policy. This policy involves storing a post in both the cache and the database simultaneously. Since blogs are generally read-intensive, this policy will be the most appropriate. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create a folder named &lt;strong&gt;&lt;code&gt;redis-store&lt;/code&gt;&lt;/strong&gt; in the root directory. Inside the &lt;strong&gt;&lt;code&gt;redis-store&lt;/code&gt;&lt;/strong&gt; folder, create a file named &lt;strong&gt;&lt;code&gt;redis.js&lt;/code&gt;&lt;/strong&gt; for the redis connection.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw3ub3ag1xzjaik99ya1b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw3ub3ag1xzjaik99ya1b.png" alt="redis-store" width="648" height="416"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open the &lt;code&gt;redis.js&lt;/code&gt; file and add the following code to connect to Redis.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Redis&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ioredis&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dotenv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dotenv&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nx"&gt;dotenv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;redisClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;redis&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Redis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;redis_url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

     &lt;span class="nx"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Redis crashed: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
     &lt;span class="p"&gt;})&lt;/span&gt;

     &lt;span class="nx"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;connect&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Redis started on &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;host&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
     &lt;span class="p"&gt;})&lt;/span&gt;

     &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;redis&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;

     &lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;redisClient&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Navigate to the &lt;strong&gt;&lt;code&gt;controller/Post.js&lt;/code&gt;&lt;/strong&gt; file, and make the following changes to incorporate caching into the code.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;a.&lt;/strong&gt; First, import the Redis connection.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Redis&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../redis-store/redis&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;strong&gt;b.&lt;/strong&gt; To cache newly created post, update &lt;strong&gt;&lt;code&gt;addPost&lt;/code&gt;&lt;/strong&gt; function with provided code snippet:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;addPost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newPost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newPost&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="c1"&gt;// Caching newly created post&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;EX&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="mi"&gt;604800&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;del&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;allPosts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/dashboard&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;In the code snippet above: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We cached each post as soon as it was created.&lt;/li&gt;
&lt;li&gt;An expiration time of either 604800 seconds or 7 days was set to expire the post from the cache.&lt;/li&gt;
&lt;li&gt;We also deleted the "&lt;strong&gt;allPosts&lt;/strong&gt;" entry from the cache because it would be outdated once a new post is added to the database. &lt;/li&gt;
&lt;li&gt;Finally, we are redirected to the dashboard to view the newly created post.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;c.&lt;/strong&gt; Modify the &lt;strong&gt;&lt;code&gt;viewPost&lt;/code&gt;&lt;/strong&gt; function to enable the display of specific posts from either the database or cache:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;viewPost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;slug&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;redisData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;redisData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findById&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;slug&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;EX&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;604800&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;locals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Simple Blog created with NodeJs, Express &amp;amp; MongoDb.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;post&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
        &lt;span class="nx"&gt;locals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;currentRoute&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`/post/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;In the code snippet provided:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We first check the Redis cache to see if a post matching the provided ID exists.&lt;/li&gt;
&lt;li&gt;If it does, we return it. &lt;/li&gt;
&lt;li&gt;However, if there is no match in the cache, we check the database for the data, cache it, and then return the post to the user.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;d.&lt;/strong&gt;  Lastly, update the &lt;strong&gt;&lt;code&gt;getPosts&lt;/code&gt;&lt;/strong&gt; function to retrieve all posts from the database or cache:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getPosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;locals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Dashboard&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Simple Blog created with NodeJs, Express &amp;amp; MongoDb.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;redisData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;allPosts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;redisData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Post-crud/dashboard&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;locals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;mainLayout&lt;/span&gt;
          &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

          &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
          &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;allPosts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

          &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Post-crud/dashboard&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;locals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;mainLayout&lt;/span&gt;
          &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;In the given code snippet above. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We start by checking the Redis cache to see if there is an entry called “&lt;strong&gt;allPosts&lt;/strong&gt;”.&lt;/li&gt;
&lt;li&gt;If such an entry exists, we directly return “&lt;strong&gt;allPosts&lt;/strong&gt;” from the cache.&lt;/li&gt;
&lt;li&gt;If there is no cached data found, we retrieve “&lt;strong&gt;allPosts&lt;/strong&gt;” from the database, and then proceed to cache it.&lt;/li&gt;
&lt;li&gt;Finally, we display all the posts to the user.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Testing
&lt;/h2&gt;

&lt;p&gt;Let's test the cache implementation to ensure that it works as expected. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;To run your application, open your terminal and type the command&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;run&lt;/span&gt; &lt;span class="nx"&gt;dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open your browser and access &lt;strong&gt;&lt;code&gt;localhost:8000/dashboard&lt;/code&gt;&lt;/strong&gt; to begin testing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To create a post, click on the "&lt;strong&gt;Create Post&lt;/strong&gt;" button.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp9i56u6ivwzprazhwa7p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp9i56u6ivwzprazhwa7p.png" alt="Create-post" width="785" height="425"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Provide a title and content for your post, then click “&lt;strong&gt;Add&lt;/strong&gt;”.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftzzbwj1l913rv796020q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftzzbwj1l913rv796020q.png" alt="Title" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Upon reaching the dashboard, click on your newly created post to view it.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh7-us.googleusercontent.com%2F1coh6ao5cufkyAM5sMU6GVhNRa1OpZOqc_2CJfg1jE3HddcnhoiFqEXZnTSMG1yb6MsJ_wofqDA5utxE0UFNc2YcnXi7b7M4rTrMrQ9E8lRuXUpgeRPX0iu_QLC6xf5DOOnTpSU60D146Ej59c8dq6g" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh7-us.googleusercontent.com%2F1coh6ao5cufkyAM5sMU6GVhNRa1OpZOqc_2CJfg1jE3HddcnhoiFqEXZnTSMG1yb6MsJ_wofqDA5utxE0UFNc2YcnXi7b7M4rTrMrQ9E8lRuXUpgeRPX0iu_QLC6xf5DOOnTpSU60D146Ej59c8dq6g" alt="New-post" width="902" height="506"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Yay! The application is working as intended, and we have successfully created a new post. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp9thyjtgghpeqsb1u0cz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp9thyjtgghpeqsb1u0cz.png" alt="New-stuff" width="800" height="380"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To complete the testing phase, log in to your &lt;a href="https://console.upstash.com/login" rel="noopener noreferrer"&gt;Upstash&lt;/a&gt; account to check if both the newly created post and “&lt;strong&gt;allPosts&lt;/strong&gt;” are added to the cache.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After logging into your Upstash account, go to your dashboard and click on the "&lt;strong&gt;Data Browser&lt;/strong&gt;" tab to access the newly added data.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fup0llnc6idct4zbzkew9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fup0llnc6idct4zbzkew9.png" alt="New-stuff" width="780" height="411"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Click on each entry to confirm the contents of the newly added data.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Single post: 
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv3j2upjftmf0bhpbxl7r.png" alt="Single-post" width="800" height="214"&gt;
&lt;/li&gt;
&lt;li&gt;All posts:
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqb2rtsxzchfy9wkskh5g.png" alt="All-post" width="800" height="246"&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Benchmarking
&lt;/h2&gt;

&lt;p&gt;The moment of truth is here. Let's see if caching improves the performance of an application. We will use the browser dev tools to compare the data retrieval time from the database vs the cache.&lt;/p&gt;

&lt;h3&gt;
  
  
  Without Caching:
&lt;/h3&gt;

&lt;p&gt;In this section, we will comment out all the code blocks where caching was implemented. Then, we will proceed to create a post, retrieve all posts, and view a single post. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;All posts&lt;/strong&gt;: It took 635 milliseconds to retrieve all the posts from the database and return them to us.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4e88b7tfdlsh9748cpqq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4e88b7tfdlsh9748cpqq.png" alt="Allpost-benchmark" width="800" height="339"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Single post&lt;/strong&gt;: It took the database 267 milliseconds to return a single post. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F89jx2pk6ybx75nwb93td.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F89jx2pk6ybx75nwb93td.png" alt="Single-post-benchmark" width="800" height="331"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  With caching:
&lt;/h3&gt;

&lt;p&gt;Let's uncomment the caching logic to compare data retrieval time. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Make sure to delete your cached data&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxc6f1c50yvo2ezm9ddru.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxc6f1c50yvo2ezm9ddru.png" alt="How-to-delete-cached-data" width="800" height="246"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;All posts&lt;/strong&gt;: Redis returned all cached posts in 193 milliseconds.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F11yngtd320vjv90q959p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F11yngtd320vjv90q959p.png" alt="Allpost-with-caching" width="800" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Single post&lt;/strong&gt;: It took Redis 193 milliseconds to return a single cached post. 
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2qw4bbrcgmwcrw6swywu.png" alt="Single-post-with-caching" width="800" height="348"&gt;
&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;/ol&gt;

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

&lt;p&gt;In this guide, you have learned what caching is, its benefits, concepts and how to integrate Redis as a caching solution in a Node.js application. However, we used a small-sized application to illustrate how caching works, so the data retrieval time was not too significant. In larger applications, caching can make a considerable difference in performance. &lt;/p&gt;

&lt;p&gt;This guide also discussed the significance of selecting the right caching policy that fits into your application to minimize the load on your backend systems. It also stressed the importance of integrating cache expiration and invalidation mechanisms to ensure data accuracy and freshness.&lt;/p&gt;

&lt;p&gt;By leveraging Redis, developers can significantly reduce response times and minimize database loads. Caching not only improves the speed of data retrieval but also reduces the workload on the server, leading to enhanced scalability and efficient resource utilization. &lt;/p&gt;

&lt;p&gt;As your application grows, understanding and implementing caching with Redis in Node.js becomes a valuable skill. By following the steps outlined in this guide, you can optimize your application, deliver faster response times, and ultimately provide a more satisfying and seamless user experience. &lt;/p&gt;

&lt;p&gt;I hope this guide was easy for you to follow. Happy Caching! 😊&lt;/p&gt;

&lt;h2&gt;
  
  
  Further Reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://redis.io/docs/" rel="noopener noreferrer"&gt;Redis Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The complete code can be found &lt;a href="https://github.com/backendbro/caching-in-action-complete" rel="noopener noreferrer"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>node</category>
      <category>caching</category>
      <category>redis</category>
      <category>webdev</category>
    </item>
    <item>
      <title>A step-by-step guide: How to create and publish an NPM package.</title>
      <dc:creator>Ukagha Nzubechukwu </dc:creator>
      <pubDate>Fri, 02 Feb 2024 07:08:00 +0000</pubDate>
      <link>https://forem.com/backendbro/a-step-by-step-guide-how-to-create-and-publish-an-npm-package-2off</link>
      <guid>https://forem.com/backendbro/a-step-by-step-guide-how-to-create-and-publish-an-npm-package-2off</guid>
      <description>&lt;p&gt;&lt;strong&gt;NPM&lt;/strong&gt; (Node Package Manager) packages are an essential component of Node.js. They allow developers to share their solutions with the wider Node.js community. NPM packages consist of reusable blocks of code that can be easily integrated into a project with a single command. By utilizing NPM packages, developers can avoid reinventing the wheel and focus on building. &lt;/p&gt;

&lt;p&gt;Each NPM package is identified by a unique name and version number, allowing developers to specify and install specific versions of packages in their projects. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl4ow99t56z8zq16dt9y4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl4ow99t56z8zq16dt9y4.png" alt="NPM-PACKAGE" width="800" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;NPM packages include a wide range of tools such as frameworks like &lt;a href="https://expressjs.com/" rel="noopener noreferrer"&gt;Express&lt;/a&gt; or &lt;a href="https://react.dev/" rel="noopener noreferrer"&gt;React&lt;/a&gt;, libraries like &lt;a href="https://jquery.com/" rel="noopener noreferrer"&gt;jQuery&lt;/a&gt;, and task runners such as &lt;a href="https://gulpjs.com/" rel="noopener noreferrer"&gt;Gulp&lt;/a&gt;, and &lt;a href="https://webpack.js.org/" rel="noopener noreferrer"&gt;Webpack&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;In this guide, you will learn how to create and publish an NPM package. Let’s get to it. &lt;/p&gt;

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

&lt;p&gt;To follow the steps detailed in this article, you must have the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Basic understanding of Node.js &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://nodejs.org/en" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt; installed&lt;/li&gt;
&lt;li&gt;An &lt;a href="https://www.npmjs.com/" rel="noopener noreferrer"&gt;NPM registry&lt;/a&gt; account &lt;/li&gt;
&lt;li&gt;A code editor, preferably &lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;Visual Studio Code&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;NPM stands for Node Package Manager. It is the default package manager of Node.js. NPM provides two main functionalities: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;NPM CLI&lt;/strong&gt;: The NPM CLI, also known as 'npm', is a command-line utility that enables developers to install, manage, and publish packages.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NPM Registry&lt;/strong&gt;: is a &lt;a href="https://www.npmjs.com/" rel="noopener noreferrer"&gt;repository&lt;/a&gt; where developers can publish both public and private packages, making them accessible to others.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Packages are simply JavaScript projects.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;NPM is the biggest JavaScript package manager. As of the time of writing this article, there are over &lt;strong&gt;2.6 million&lt;/strong&gt; packages available on the official NPM registry, which range from small utility packages to large-scale frameworks. These packages have been downloaded over &lt;strong&gt;216 billion&lt;/strong&gt; times.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxdzuuddti0g83k319l6m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxdzuuddti0g83k319l6m.png" alt="statistics on the number of npm packages" width="800" height="340"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This success can be attributed to Node.js' active and thriving ecosystem. &lt;/p&gt;

&lt;p&gt;In Node.js, every project contains a metadata file named &lt;strong&gt;&lt;code&gt;package.json&lt;/code&gt;&lt;/strong&gt; at its root, which is created and maintained by NPM. This file contains vital information about a project, including its name, version, description, author, license, dependencies, and scripts. The &lt;strong&gt;&lt;code&gt;package.json&lt;/code&gt;&lt;/strong&gt; file serves as a central configuration file for Node.js projects and is crucial in managing dependencies.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Dependencies are packages installed in a Node.js project.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Additionally, NPM also provides some quintessential commands to do several tasks such as initializing a project, installing a package, and publishing a package. The most common commands include &lt;strong&gt;&lt;code&gt;npm init&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;npm publish&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;npm install&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;NPM is critical in the Node.js ecosystem, as it promotes collaboration, solution sharing, faster development, and better software quality. It has become a must-have tool for Node.js developers and is widely used in open-source and enterprise projects. &lt;/p&gt;

&lt;h2&gt;
  
  
  How to create an NPM package
&lt;/h2&gt;

&lt;p&gt;Before following the steps in creating an NPM package, it is recommended to decide on a name for your NPM package first. Do well to visit the &lt;a href="https://www.npmjs.com/" rel="noopener noreferrer"&gt;NPM registry&lt;/a&gt; to confirm the availability of your desired name. &lt;/p&gt;

&lt;p&gt;If your desired name is taken, consider choosing a different name. Attempting to use a name that is already taken (or something similar) will cause Node.js to throw an error. &lt;/p&gt;

&lt;p&gt;For example: If a package named &lt;strong&gt;&lt;code&gt;rgbcolorpicker&lt;/code&gt;&lt;/strong&gt; already exists, you won't be able to publish a package with the name &lt;strong&gt;&lt;code&gt;rgb-color-picker&lt;/code&gt;&lt;/strong&gt;. Make sure to choose a unique and available name for your package.&lt;/p&gt;

&lt;p&gt;However, if you're still keen on using the taken name, you can publish the package as a scope package. More information on how to do this will be provided later.&lt;/p&gt;

&lt;p&gt;Now that you have your package name. Let’s continue:&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting up an account
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt; First, create an account on the &lt;a href="https://www.npmjs.com/" rel="noopener noreferrer"&gt;NPM registry website&lt;/a&gt;. If you already have an account, log in. &lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Keep your credentials safe as they will be required to publish your package.&lt;/em&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Project structure
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Create the following files and folders required for this project:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;My-First-Package  
└─ main.js        
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Below is a &lt;strong&gt;visual illustration&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhmswjdebw96tcxy0jflp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhmswjdebw96tcxy0jflp.png" alt="Project-structure" width="602" height="445"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Project initialization
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Open your terminal, navigate to the root of your working directory, and initialize your project by running this command:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;You will prompted by npm to provide certain information to generate a &lt;strong&gt;&lt;code&gt;package.json&lt;/code&gt;&lt;/strong&gt; file. &lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The importance of a &lt;strong&gt;&lt;code&gt;package.json&lt;/code&gt;&lt;/strong&gt; file in an NPM package cannot be overstated.&lt;/em&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;To assist you in creating the &lt;strong&gt;&lt;code&gt;package.json&lt;/code&gt;&lt;/strong&gt; file, here is a guide on how to enter the necessary information: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;package-name&lt;/strong&gt;: Here, enter your selected package name. Ensure it is in lowercase and make sure to remove any trailing spaces.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;version&lt;/strong&gt;: It's recommended to keep the initial value and update the version of the package as you make changes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;description&lt;/strong&gt;: Describe your package. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;entry point&lt;/strong&gt;: This is the entry point of your package. Keep the initial value unless you plan on using a different file as your entry point.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;test command&lt;/strong&gt;: If you have any test commands for your package, enter them here. Leave this field blank if you have none.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;git repository&lt;/strong&gt;: Enter the link to the Git repository where this package is located. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;keywords&lt;/strong&gt;: Provide relevant keywords such as "library", "framework", or "task-runner" to help others easily find your package.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;author&lt;/strong&gt;: Enter your name or alias. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;license&lt;/strong&gt;: Here, enter a license if you have one. If not, leave this field blank.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Here is a visual representation that shows how to correctly enter your information:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcvjsddq8kqoqqeha2uys.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcvjsddq8kqoqqeha2uys.png" alt="Package.json" width="763" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Writing your code
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Open your &lt;strong&gt;&lt;code&gt;main.js&lt;/code&gt;&lt;/strong&gt; file and insert the provided code snippet:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function generatePassword(length, includeUppercase, includeNumbers, includeSpecialChars) {

    if (!length || typeof length === "string"){
     return new Error ("Please provide password length")     
    }

    const lowercaseChars = 'abcdefghijklmnopqrstuvwxyz';
    const uppercaseChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    const numberChars = '0123456789';
    const specialChars = '!@#$%^&amp;amp;*()_-+=&amp;lt;&amp;gt;?/{}[]';

    let validChars = lowercaseChars;
    let password = '';

    if (includeUppercase) validChars += uppercaseChars;
    if (includeNumbers) validChars += numberChars;
    if (includeSpecialChars) validChars += specialChars;

    for (let i = 0; i &amp;lt; length; i++) {
      const randomIndex = Math.floor(Math.random() * validChars.length);
      password += validChars[randomIndex];
    }

    return password;
  }

module.exports = generatePassword
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;In the code snippet above: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;&lt;code&gt;generatePassword&lt;/code&gt;&lt;/strong&gt; function is designed to create a password and requires four arguments to run. The first argument is the desired length of the password. The remaining arguments are optional and are used to determine if the password should include uppercase letters, numbers, or special characters.&lt;/li&gt;
&lt;li&gt;The function is then exported so others can access it. &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Test your package
&lt;/h3&gt;

&lt;p&gt;The next step is to test the password-generator package to ensure it works as intended. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Navigate to your terminal and enter the command:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm link 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The npm link command allows you to create a symbolic link between a package and the global npm registry, making it accessible to other projects on your machine without needing to install it. This is particularly useful during development, as it allows you to quickly test changes without having to publish and update the package each time you modify.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flmxk63xah9f2ey6ag99u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flmxk63xah9f2ey6ag99u.png" alt="npm init" width="688" height="146"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new folder and file to require the password-generator package
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Test-Folder
└─ test.js   
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Make sure to navigate to the &lt;strong&gt;&lt;code&gt;Test-Folder&lt;/code&gt;&lt;/strong&gt; working directory in your terminal and run the commands sequentially
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm init -y 
npm link &amp;lt;packagename&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;To initialize a directory or folder, you can use the &lt;strong&gt;&lt;code&gt;npm init&lt;/code&gt;&lt;/strong&gt; command. By adding the &lt;strong&gt;&lt;code&gt;-y&lt;/code&gt;&lt;/strong&gt; flag, you can skip the prompts and save time. The &lt;strong&gt;&lt;code&gt;test-folder&lt;/code&gt;&lt;/strong&gt; is specifically used for testing, so there is no need to spend time providing any necessary information.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The &lt;strong&gt;&lt;code&gt;npm link &amp;lt;packagename&amp;gt;&lt;/code&gt;&lt;/strong&gt; command will add the specified package to your project&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0867up0gjl0895xs1dry.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0867up0gjl0895xs1dry.png" alt="npm link package" width="736" height="154"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;&lt;code&gt;npm link &amp;lt;packagename&amp;gt;&lt;/code&gt;&lt;/strong&gt; command created a &lt;strong&gt;&lt;code&gt;node_modules&lt;/code&gt;&lt;/strong&gt; folder. This folder holds packages installed by npm. To find your package, navigate to the corresponding folder inside &lt;strong&gt;&lt;code&gt;node_modules&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F91ax6rfh1l6z9bqdbpa8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F91ax6rfh1l6z9bqdbpa8.png" alt="Node modules" width="672" height="208"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open the &lt;strong&gt;&lt;code&gt;test.js&lt;/code&gt;&lt;/strong&gt; file and require the package.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const passwordGen = require('backendbro-password-generator') 

const password = passwordGen(10, true, false, true) 
console.log(password)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;To complete the testing process, execute the command
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node test.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft7wv9skpcvodcwtq921q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft7wv9skpcvodcwtq921q.png" alt="npm test" width="687" height="98"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Voila! The package works as suppose. Let’s continue by publishing to the NPM registry.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Publishing to the NPM Registry
&lt;/h2&gt;

&lt;p&gt;After testing your NPM package, you can publish it to the NPM registry. Here's a simple guide to follow:&lt;/p&gt;

&lt;h3&gt;
  
  
  Login to the NPM registry:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;To get started, you need to create an &lt;a href="https://www.npmjs.com/" rel="noopener noreferrer"&gt;account&lt;/a&gt;. If you already have one, log in.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Publish:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Open your terminal, navigate to your package directory, and run the command:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  npm login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqz490q5sz4xy5bey2ykh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqz490q5sz4xy5bey2ykh.png" alt="npm login" width="733" height="178"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You will be redirected to the NPM registry. Enter the One-Time Password (OTP) sent to your email address to complete the authentication process.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flv5cjhmlipvz8kwo7c25.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flv5cjhmlipvz8kwo7c25.png" alt="otp" width="800" height="698"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To publish your package, enter the command provided below:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm publish 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8wqofmypo89bku4n6928.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8wqofmypo89bku4n6928.png" alt="npm publish" width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yay! Your package has been successfully published to the NPM registry. You can now search for it on the registry.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxtev5oclma90q2df1r1x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxtev5oclma90q2df1r1x.png" alt="registry" width="800" height="308"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Publishing Scoped Packages
&lt;/h2&gt;

&lt;p&gt;In previous sections, we talked about how to publish packages as scoped packages to work around using an already-taken package name. Scoped packages allow you to create a namespace for your package to avoid naming conflicts. &lt;/p&gt;

&lt;p&gt;Scoped packages are private by default. However, you can choose to grant access to specific individuals who are allowed to use your package. Private packages require a paid subscription plan, but there is no need to worry about that. You can publish your scoped package as public to avoid any fees.&lt;/p&gt;

&lt;p&gt;If you decide to make your scoped package public after publishing it, you can easily change its visibility by updating the access field in your package.json file from &lt;strong&gt;restricted&lt;/strong&gt; to &lt;strong&gt;public&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Creating and publishing scope packages is a simple process. To do so, follow the steps below:&lt;/p&gt;

&lt;h3&gt;
  
  
  Project structure
&lt;/h3&gt;

&lt;p&gt;Create a new project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Scoped-package  
└─ main.js      
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Project initialization
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;To begin, you need to initialize your directory by running the following command:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  npm init --scope=@username
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;When entering the package name in the npm prompt, follow this format: &lt;strong&gt;@username/package-name&lt;/strong&gt;. See the example image below.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdw81397xerreoz2mgzco.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdw81397xerreoz2mgzco.png" alt="init-scope-package" width="800" height="573"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Writing your code:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Copy the &lt;strong&gt;&lt;code&gt;generatePassword&lt;/code&gt;&lt;/strong&gt; function from the previous section and paste it into the &lt;strong&gt;&lt;code&gt;main.js&lt;/code&gt;&lt;/strong&gt; file&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Testing the package:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Follow the same procedure as described in the previous section to test your package.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Publishing:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;To publish your scope package, open your terminal and run the command given below:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    npm publish --access public
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Remember: By default, scoped packages are private. Another way to make a package public is by setting the &lt;strong&gt;&lt;code&gt;access&lt;/code&gt;&lt;/strong&gt; flag to public.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fogieynexydaxu2kv2evc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fogieynexydaxu2kv2evc.png" alt="npm publish scope package" width="800" height="326"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ta-da! You have successfully published your first scope package. Visit the NPM registry to view it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9zf4s2xqm9kkqaajy3yr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9zf4s2xqm9kkqaajy3yr.png" alt="scoped-package" width="800" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing the NPM package
&lt;/h2&gt;

&lt;p&gt;After publishing a package to the NPM registry, it is best practice to install and use it to ensure it works as a regular package. &lt;/p&gt;

&lt;h3&gt;
  
  
  Project structure
&lt;/h3&gt;

&lt;p&gt;Create a new project and initialize it using &lt;strong&gt;&lt;code&gt;npm init&lt;/code&gt;&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Package     
└─ main.js  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Installation
&lt;/h3&gt;

&lt;p&gt;Use the following command to install the newly published package.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install packagname 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;You can use &lt;strong&gt;&lt;code&gt;i&lt;/code&gt;&lt;/strong&gt; instead of &lt;strong&gt;&lt;code&gt;install&lt;/code&gt;&lt;/strong&gt; in the npm command. For example, instead of typing &lt;strong&gt;&lt;code&gt;npm install&lt;/code&gt;&lt;/strong&gt;, you can type &lt;strong&gt;&lt;code&gt;npm i&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fltjrpkckai5maob47a2a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fltjrpkckai5maob47a2a.png" alt="install-package" width="712" height="144"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Usage
&lt;/h3&gt;

&lt;p&gt;Open your &lt;strong&gt;&lt;code&gt;main.js&lt;/code&gt;&lt;/strong&gt; file and require the newly installed package.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const passwordGen = require("backendbro-password-generator")

const password = passwordGen(10, true, true, true) 
console.log(password) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Run your app
&lt;/h3&gt;

&lt;p&gt;Simply run your application using:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzjuhjiprhsz14jzcbkxo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzjuhjiprhsz14jzcbkxo.png" alt="node run" width="664" height="89"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Knowing how to create NPM packages is a vital skill for Node.js developers. It enables them to contribute to the open-source community and simplify their workflows by avoiding the need to reinvent the wheel. &lt;/p&gt;

&lt;p&gt;In this guide, you have learned what NPM and NPM packages are and their importance to software development. You have also learned how to create and publish packages on the NPM registry. &lt;/p&gt;

&lt;p&gt;You too can become a part of the ever-evolving Node.js landscape by sharing your package. Join in on this journey, share your solutions, and let's shape the future of software development together, one package at a time.&lt;/p&gt;

&lt;p&gt;Thank you for staying with me and have a great time coding! 😊&lt;/p&gt;

&lt;h2&gt;
  
  
  Useful Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.npmjs.com/" rel="noopener noreferrer"&gt;NPM Official Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>node</category>
      <category>npm</category>
      <category>package</category>
      <category>javascript</category>
    </item>
    <item>
      <title>What is Node.js and why should you use it in 2024</title>
      <dc:creator>Ukagha Nzubechukwu </dc:creator>
      <pubDate>Thu, 18 Jan 2024 05:28:51 +0000</pubDate>
      <link>https://forem.com/backendbro/what-is-nodejs-and-why-should-you-use-it-in-2024-4383</link>
      <guid>https://forem.com/backendbro/what-is-nodejs-and-why-should-you-use-it-in-2024-4383</guid>
      <description>&lt;p&gt;In the rapidly changing world of web development, Node.js emerged and solidified itself as an integral part of the modern-day web. Node.js has gained immense popularity in recent years as a powerful tool for developing scalable and high-performance applications. However, you may be wondering — what is the hype about Node.js and why should you consider using it in 2024? This article will delve deeper into Node.js, exploring its features, benefits, and use cases.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Node.js?
&lt;/h2&gt;

&lt;p&gt;Node.js is a cross-platform runtime environment that runs JavaScript code outside a web browser. Node.js uses the powerful V8 JavaScript engine from Google Chrome for swift execution of JavaScript code. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Ryan_Dahl" rel="noopener noreferrer"&gt;Ryan Dahl&lt;/a&gt; introduced Node.js in 2009, and since then, it has gained widespread adoption in the web development ecosystem. At its initial release, Node.js was only supported on Linux and Mac OS X. It wasn't until July 2011 that the first Node.js build supporting Windows was released. &lt;/p&gt;

&lt;p&gt;Dahl criticized the sequential programming approach, which could not effectively manage a significant number of simultaneous connections. This frequently resulted in a delay that blocked the execution of a program, thereby reducing the overall performance of the application.&lt;/p&gt;

&lt;p&gt;With Node.js, developers can use JavaScript for server-side scripting. Notable organizations including &lt;a href="https://www.netflix.com/ng/" rel="noopener noreferrer"&gt;Netflix&lt;/a&gt;, &lt;a href="https://www.linkedin.com/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;, &lt;a href="https://www.uber.com/" rel="noopener noreferrer"&gt;Uber&lt;/a&gt;, and &lt;a href="https://twitter.com/" rel="noopener noreferrer"&gt;Twitter &lt;/a&gt; implement Node.js. In the latest &lt;a href="https://survey.stackoverflow.co/2022/#most-popular-technologies-language" rel="noopener noreferrer"&gt;StackOverflow survey&lt;/a&gt;, Node.js was ranked as the most popular &lt;strong&gt;Web Framework and Technology&lt;/strong&gt; with a &lt;strong&gt;47.12%&lt;/strong&gt; adoption rate. With over &lt;strong&gt;6.3 million&lt;/strong&gt; websites using Node.js, it remains a top choice for building scalable and high-performance applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problems Node.js aims to solve.
&lt;/h2&gt;

&lt;p&gt;Ryan Dahl created Node.js based on a simple principle — &lt;strong&gt;operations must never block&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Node.js aims to solve various problems that developers have always struggled with. Some of these problems include: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Processing a large volume of requests simultaneously &lt;/li&gt;
&lt;li&gt;Preventing I/O bottlenecks &lt;/li&gt;
&lt;li&gt;Implementing concurrency safely and more predictably. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To address these challenges, Node.js implements the following: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Node.js applications run on a single thread, which helps it achieve its non-blocking and event-driven goal. This means an application can process many requests simultaneously without blocking the main thread. &lt;/li&gt;
&lt;li&gt;Program flow in Node.js is directed through asynchronous callbacks, which eliminates any bottlenecks caused by waiting for an operation to finish. &lt;/li&gt;
&lt;li&gt;Concurrency is implemented in Node.js by use of events. Events are emitted to notify the completion of an operation. With Node.js developers can implement concurrency and parallelism safely and predictably in their applications without worrying about race conditions or other issues.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Understanding Nodejs Architecture
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh7-us.googleusercontent.com%2F3ClrNC7iAfUOTa_9xL4SZtVjCK0BAW66rkBVyuzPgrDVlmeS0nu_ZBtZbARko-Bvp4CKmDozVV_5DvzOKfEmyLjSlI53NOUaJpVbFih-RcH1jqmzfCNYMTsmDPb1B-IU0FmuTDSyYraTBFKDllHo0I0" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh7-us.googleusercontent.com%2F3ClrNC7iAfUOTa_9xL4SZtVjCK0BAW66rkBVyuzPgrDVlmeS0nu_ZBtZbARko-Bvp4CKmDozVV_5DvzOKfEmyLjSlI53NOUaJpVbFih-RcH1jqmzfCNYMTsmDPb1B-IU0FmuTDSyYraTBFKDllHo0I0" alt="Source: https://litslink.com/blog/node-js-architecture-from-a-to-z" width="1600" height="914"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Node.js has a unique architecture that sets it apart from traditional server-side technologies. Its non-blocking and event-driven design allows it to handle multiple requests simultaneously without blocking other operations. This makes Node.js highly scalable and particularly suited for high-traffic and real-time data processing applications.&lt;/p&gt;

&lt;p&gt;The Node.js architecture is made possible by its single-threaded event loop, which listens for events such as incoming requests and calls the corresponding callback functions. &lt;br&gt;
The event loop allows Node.js to avoid waiting for an operation to complete before moving on to the next one. When the skipped operation eventually completes, an event is emitted to notify the event loop to call its callback function. This feature allows Node.js to maintain a high level of performance when handling a large number of connections at once.&lt;/p&gt;

&lt;p&gt;Node.js uses a support library called &lt;a href="https://libuv.org/" rel="noopener noreferrer"&gt;Libuv&lt;/a&gt;, which provides the event loop and manages asynchronous I/O operations. The Libuv handles most of the operating system tasks, such as file system operations, networking, and threading. The Libuv is crucial to Node.js's ability to handle concurrent tasks effectively.&lt;/p&gt;

&lt;p&gt;Another core component of the Node.js architecture is the &lt;a href="https://v8.dev/" rel="noopener noreferrer"&gt;V8 JavaScript engine&lt;/a&gt;. The V8 is a high-performance runtime engine that executes JavaScript code at lightning-fast speeds. &lt;br&gt;
The V8 engine uses the Just-In-Time (JIT) compilation technique to translate JavaScript code into machine code at runtime, which allows for faster and more efficient execution. &lt;/p&gt;

&lt;p&gt;The V8 engine performs various optimizations, such as:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Inlining functions &lt;/li&gt;
&lt;li&gt;Eliminating dead code &lt;/li&gt;
&lt;li&gt;Optimizing memory usage — which helps to prevent memory leaks. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These optimizations ensure that the JavaScript code runs as efficiently as possible.&lt;/p&gt;

&lt;p&gt;Node.js owes much of its speed and efficiency to the V8 Google Chrome engine. The V8, when combined with the Libuv, makes Node.js a top choice for building high-performance web applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Features of Node.js
&lt;/h2&gt;

&lt;p&gt;Node.js is known for its non-blocking and event-driven mechanisms, but it also offers various other features that make it stand out. They are: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Operating System Operations&lt;/strong&gt;: Node.js adds a vast range of new features to JavaScript, allowing developers to perform several operating system related tasks such as file system operations, running external commands, and gathering information about the system environment. These functionalities aid developers in communicating with the underlying operating system that is not available to browser-based JavaScript. Node.js provides some core modules to make these interactions possible.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Modules&lt;/strong&gt;: In Node.js, modules are essential for organizing code into reusable and maintainable units. They are independent units of code that are self-contained and can be shared, imported, and reused in different parts of an application. This allows complex applications to be built out of smaller, simpler components. Node.js follows the CommonJS module system, which provides a simple and efficient way to create, import, and reuse code across different files. To make functions and variables accessible to other files, Node.js provides the &lt;code&gt;module.exports&lt;/code&gt; interface.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;NPM&lt;/strong&gt;: Node.js comes with a powerful package manager called Node Package Manager (NPM), it simplifies the installation, sharing, and version control of Node.js modules, making it easier to share and reuse code in projects. NPM has become one of the largest open-source JavaScript module repositories.&lt;br&gt;
To keep track of project-related metadata, NPM maintains a &lt;code&gt;package.json&lt;/code&gt; file in your project. This file lists all the dependencies and their respective versions. Additionally, NPM allows developers to define and run scripts in their &lt;code&gt;package.json&lt;/code&gt; file. These scripts can be used for several tasks like testing, building, or running the application. The most common scripts include &lt;strong&gt;start&lt;/strong&gt;, &lt;strong&gt;test&lt;/strong&gt;, and &lt;strong&gt;build&lt;/strong&gt;. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Seamless frontend integration&lt;/strong&gt;: Node.js is a popular choice for full-stack projects because it allows developers to use JavaScript for both frontend and backend. &lt;br&gt;
Developers can use popular frontend frameworks like React and Angular to create dynamic and real-time interactions while serving static assets and rendering dynamic content on the server side. This combination simplifies development, fosters code consistency and reduces the need to switch between languages.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Large Community and Ecosystem&lt;/strong&gt;: Node.js has gained immense popularity due to its thriving community of developers who contribute to its growth and improvement. This community makes it easy for developers to find solutions to common problems and share best practices.&lt;br&gt;
This collaborative approach ensures that Node.js stays up-to-date with the latest trends and technologies. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Use Cases of Node.js
&lt;/h2&gt;

&lt;p&gt;Node.js has a wide range of applications, including: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Web applications&lt;/strong&gt;: Node.js is often used for building scalable and high-performance web applications. Its non-blocking and event-driven design makes it well-suited for I/O intensive applications. Node.js has popular frameworks like &lt;a href="https://expressjs.com/" rel="noopener noreferrer"&gt;Express&lt;/a&gt; to provide a boilerplate for building robust web applications.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;REST APIs&lt;/strong&gt;: Node.js is a popular choice for developing RESTful APIs because of its lightweight and event-driven architecture. This architecture enables it to scale effortlessly and handle a large volume of requests. RESTful APIs often employ &lt;strong&gt;JSON&lt;/strong&gt; (JavaScript Object Notation) for exchanging data. As JSON is native to JavaScript, working with JSON in Node.js is straightforward and seamless.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Real-time applications&lt;/strong&gt;:  Node.js is well-suited for building applications that require two-way communication and real-time updates. &lt;br&gt;
Node.js provides libraries such as &lt;a href="https://socket.io/" rel="noopener noreferrer"&gt;Socket.io&lt;/a&gt; to simplify the integration of real-time features in web applications such as chat platforms, collaborative tools, multiplayer games, and streaming services. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Microservices&lt;/strong&gt;: Node.js is widely used in microservices applications, where services are divided into smaller, independent units, making it easier to scale, maintain, and deploy complex applications. Node.js's non-blocking model allows these services to handle a high volume of simultaneous requests without interfering with the execution of other tasks. Additionally, the lightweight and scalable nature of Node.js makes it a perfect fit for microservices that need to scale horizontally to handle increased traffic.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Single-Page Applications&lt;/strong&gt;: Node.js is also used for developing single-page applications because it can render content on the server side. Node.js uses template engines like &lt;a href="https://ejs.co/" rel="noopener noreferrer"&gt;EJS&lt;/a&gt; and &lt;a href="https://handlebarsjs.com/" rel="noopener noreferrer"&gt;Handlebars&lt;/a&gt; to render HTML content and send it to the client, resulting in faster page loading times. This approach improves search engine optimization (SEO) and accessibility for users with slow or unreliable internet connections.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Challenges and Solutions
&lt;/h2&gt;

&lt;p&gt;Node.js has many advantages due to its architecture, however, there are certain challenges associated with this approach. &lt;br&gt;
Here are a few challenges that affect the single-threaded nature of Node.js and how to mitigate them.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;h3&gt;
  
  
  CPU-Intensive Tasks:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Challenges&lt;/strong&gt;: Since Node.js is single-threaded, it can only perform one task at a time. This can pose a problem when dealing with expensive CPU operations that can block Node.js' event loop, causing performance issues.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Solution&lt;/strong&gt;: To mitigate this issue, it is recommended to distribute CPU-intensive tasks among different processes or threads using techniques such as asynchronous programming, clustering, and worker threads. This can significantly improve the application's performance by ensuring that one operation does not block the other.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;h3&gt;
  
  
  Limited Multithreading:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Challenges&lt;/strong&gt;: Due to the lack of native support, implementing multi-threading in Node.js can be challenging. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Solution&lt;/strong&gt;:  Node.js provides the &lt;strong&gt;worker_threads&lt;/strong&gt; module for thread management. In addition to the &lt;strong&gt;worker_threads&lt;/strong&gt; module, several NPM dependencies have been created to simplify the process of multi-threading in Node.js. &lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;h3&gt;
  
  
  Callback Hell:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Challenges&lt;/strong&gt;: Node.js heavily relies on callbacks to achieve its non-blocking, event-driven model. However, this approach often leads to a callback hell. This is when deeply nested callbacks can become difficult to read, maintain, and debug.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Solution&lt;/strong&gt;: Developers can mitigate the callback hell by using async/await, Promises, and event emitters, which allows for clearer and more readable code.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;h3&gt;
  
  
  Garbage Collection:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Challenges&lt;/strong&gt;: Node.js optimizes memory management through garbage collection, which allocates and deallocates memory spaces. However, this can block other operations and reduce application performance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Solution&lt;/strong&gt;: Proper configuration of garbage collection can prevent performance issues and ensure smooth program execution. Developers should also consider application memory needs and avoid unnecessary memory-intensive operations.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;/ol&gt;

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

&lt;p&gt;Node.js continues to be a quintessential and versatile technology. Its non-blocking, event-driven architecture, built on the V8 JavaScript engine, has proven to be instrumental in developing scalable and high-performance applications. &lt;/p&gt;

&lt;p&gt;Node.js's active and thriving community ensures that there will always be a solution to any problem. Developers can benefit from its rich ecosystem of libraries and tools for development.&lt;/p&gt;

&lt;p&gt;Whether you are a beginner or an experienced developer, the broad range of features offered by Node.js makes it a compelling choice for software development in 2024.&lt;/p&gt;

&lt;h2&gt;
  
  
  Further Reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://nodejs.org/docs/latest/api/" rel="noopener noreferrer"&gt;Node.js Official Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.digitalbreakdown.net/sandbox/Ebooks/Mastering-Node.js.pdf" rel="noopener noreferrer"&gt;Mastering Node.js&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>node</category>
    </item>
    <item>
      <title>Building a REST API using NodeJS, ExpressJS, and CockroachDB</title>
      <dc:creator>Ukagha Nzubechukwu </dc:creator>
      <pubDate>Fri, 15 Sep 2023 11:56:14 +0000</pubDate>
      <link>https://forem.com/backendbro/building-a-rest-api-using-nodejs-expressjs-and-cockroachdb-1155</link>
      <guid>https://forem.com/backendbro/building-a-rest-api-using-nodejs-expressjs-and-cockroachdb-1155</guid>
      <description>&lt;p&gt;In today's technology-driven world, there is a high demand for scalable and high-performance web applications. As a result, developers are constantly exploring new technologies and frameworks to simplify building robust and user-friendly applications.&lt;/p&gt;

&lt;p&gt;With &lt;a href="https://nodejs.org/en" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt;, &lt;a href="https://expressjs.com/" rel="noopener noreferrer"&gt;Express&lt;/a&gt;, and &lt;a href="https://www.cockroachlabs.com/" rel="noopener noreferrer"&gt;CockroachDB&lt;/a&gt;, developers have a powerful combination for backend development, offering a seamless and adaptable environment for creating high-performing REST APIs.&lt;/p&gt;

&lt;p&gt;In this tutorial, we will build a robust REST API to store and manage a book's essential details, such as the title, author, ISBN, and page count.&lt;/p&gt;

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

&lt;p&gt;This article assumes that you have a basic knowledge of the following: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://nodejs.org/en" rel="noopener noreferrer"&gt;NodeJS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://expressjs.com/" rel="noopener noreferrer"&gt;Express&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.oracle.com/cd/E12151_01/index.html" rel="noopener noreferrer"&gt;SQL&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;: The code for this tutorial is on &lt;a href="https://github.com/backendbro/node-express-cockroachdb-api" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Project Setup
&lt;/h2&gt;

&lt;p&gt;First, create the following files and folders: &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;book-api
 ┣ controller
 ┃ ┗ Book.js
 ┣ database
 ┃ ┗ DB.js
 ┣ routes
 ┃ ┗ Book.js
 ┣ schema
 ┃ ┗ BookSchema.js
 ┣ config.env
 ┗ server.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Below is a visual illustration of the files and folders needed for this project. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpnujf7w00blzv23kdliv.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpnujf7w00blzv23kdliv.PNG" alt="project-file-and-folders" width="800" height="591"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To continue, run the following command in the terminal to initialize the working directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fill in the necessary information when prompted by this command, as shown below, then press ENTER.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwzy6tijehjjdl9uoam6e.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwzy6tijehjjdl9uoam6e.PNG" alt="The_initilization_of_a_node_directory" width="800" height="605"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once completed, a &lt;code&gt;package.json&lt;/code&gt; file will be generated. This file contains vital information and scripts that run and tests the application. &lt;br&gt;
Update the &lt;code&gt;package.json&lt;/code&gt; file with the following script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
"scripts": {
    "start": "nodemon server.js"
}

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Visual illustration below:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8reodlvl1nhbgmo1nvcd.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8reodlvl1nhbgmo1nvcd.PNG" alt="package-json" width="800" height="650"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Installing Dependencies
&lt;/h2&gt;

&lt;p&gt;Run the following command to install the necessary dependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install  express sequelize sequelize-cockroachdb dotenv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Quick note:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://expressjs.com/" rel="noopener noreferrer"&gt;Express&lt;/a&gt;&lt;/strong&gt;:  Express is a NodeJS framework used to create web applications and REST APIs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://sequelize.org/" rel="noopener noreferrer"&gt;Sequelize&lt;/a&gt;&lt;/strong&gt;: Sequelize is an ORM widely used by NodeJS developers to manage relational databases. This eliminates the need for writing raw SQL. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.npmjs.com/package/sequelize-cockroachdb" rel="noopener noreferrer"&gt;Sequelize-cockroachdb&lt;/a&gt;&lt;/strong&gt;: This ORM is specific to CockroachDB. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.npmjs.com/package/dotenv" rel="noopener noreferrer"&gt;Dotenv&lt;/a&gt;&lt;/strong&gt;: Dotenv loads data from the &lt;code&gt;config.env&lt;/code&gt;  file into the NodeJS environment. By so doing, one can access those data using &lt;code&gt;process.env&lt;/code&gt;. Dotenv makes an application more maintainable and more secure.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Lastly, install the &lt;code&gt;nodemon&lt;/code&gt; dependency.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install nodemon -g
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.npmjs.com/package/nodemon" rel="noopener noreferrer"&gt;Nodemon&lt;/a&gt;&lt;/strong&gt;: Nodemon automatically restarts a server whenever one saves a file. I omitted Nodemon in the first command because of the &lt;code&gt;-g&lt;/code&gt; flag. The flag instructs NodeJS to install Nodemon as a global dependency. By so doing, one does not have to install nodemon ever again. &lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;If you only need to use Nodemon once, you can omit the &lt;code&gt;-g&lt;/code&gt; flag.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Creating a CockroachDB Cluster.
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What is CockroachDB?&lt;/strong&gt;&lt;br&gt;
CockroachDB is a distributed SQL database management system. CockroachDB is designed to handle transactional workloads with low latency and high throughput. CockroachDB's high availability and fault tolerance ensures it can operate even if a node, zone, or region fails. &lt;/p&gt;

&lt;p&gt;CockroachDB offers the scalability of NoSQL databases and the relational model of SQL databases, making it ideal for web applications that require flexibility and reliability. Its high compatibility makes it easy to port PostgreSQL applications to CockroachDB with minimal code changes.&lt;/p&gt;

&lt;p&gt;Additionally, CockroachDB offers a high level of data consistency. CockroachDB is used by companies like — &lt;a href="https://corporate.comcast.com/" rel="noopener noreferrer"&gt;Comcast&lt;/a&gt;, &lt;a href="https://www.digitalocean.com/" rel="noopener noreferrer"&gt;Digital Ocean&lt;/a&gt;, and &lt;a href="https://www.bose.com/home" rel="noopener noreferrer"&gt;Bose&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Moving on, Follow these simple steps to set up a CockroachDB cluster.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create a &lt;a href="//cockroachlabs.cloud"&gt;CockroachDB &lt;/a&gt;account or sign in if you already have one.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After signing in, click Create Cluster.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0oaj32v1lys1k109lvd5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0oaj32v1lys1k109lvd5.png" alt="cockroachdb-signin-page" width="800" height="411"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select a preferred plan and click Create Cluster.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1f9f5zyaaw8m0swdvsdc.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1f9f5zyaaw8m0swdvsdc.PNG" alt="cockroachdb-price-plan" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The CockroachDB cluster is currently being processed. Wait patiently while it completes.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqvplgntktlgqhfxpenw7.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqvplgntktlgqhfxpenw7.PNG" alt="cockroachdb-loading-screen" width="800" height="414"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create an SQL user and password. These credentials will be necessary to connect to the newly created cluster from the application. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F98xt28uogdgo29e4dsux.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F98xt28uogdgo29e4dsux.png" alt="cockroachdb-sql-user" width="800" height="403"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Safely store the credentials and click Next.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F61pck9lmzmtvk58r512y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F61pck9lmzmtvk58r512y.png" alt="cockroachdb-credentials" width="800" height="398"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Voila! We have successfully created a CockroachDB cluster.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1pzh8195s1mjn3tgvwi1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1pzh8195s1mjn3tgvwi1.png" alt="cockroachdb-cluster" width="800" height="403"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Retrieving the CockroachDB Connection String.
&lt;/h3&gt;

&lt;p&gt;This section will demonstrate the steps to retrieve the connection string.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Log in to your &lt;a href="https://cockroachlabs.cloud/" rel="noopener noreferrer"&gt;CockroachDB &lt;/a&gt; account. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click the Connect button in the top right corner. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7uzt350h3e94hldf3vg8.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7uzt350h3e94hldf3vg8.PNG" alt="cockroachdb-cluster" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Scroll down and copy the connection string. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc5k8jv7ph2ihpjkgpztq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc5k8jv7ph2ihpjkgpztq.png" alt="cockroachdb-connection-string" width="800" height="405"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Building the app components
&lt;/h2&gt;

&lt;p&gt;Open the &lt;code&gt;config.env&lt;/code&gt; file and set the following environment variables.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PORT = 8000
connectionString = postgresql://backendbro:&amp;lt;ENTER-SQL-USER-PASSWORD&amp;gt;@stone-muskox-9285.8nj.cockroachlabs.cloud:26257/backendbro?sslmode=verify-full
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Make sure to paste your connection string. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Copy and paste the code below into the &lt;code&gt;server.js&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require('express')
const dotenv = require('dotenv')

dotenv.config({path:"./config.env"})
const app = express()

app.use(express.json())
app.use(express.urlencoded({extended:false}))

const PORT = process.env.PORT 
const server = app.listen(PORT, () =&amp;gt; {
    console.log(`Server started on 127.0.0.1:${PORT}`)
})

process.on("unhandledRejection", (err) =&amp;gt; {
    console.log(err.message)
    server.close(() =&amp;gt; process.exit())
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code snippet above: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We imported some of the dependencies installed earlier.&lt;/li&gt;
&lt;li&gt;We loaded the environment variables stored in &lt;code&gt;config.env&lt;/code&gt; into &lt;code&gt;process.env&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Next, we instantiated the Express app. &lt;/li&gt;
&lt;li&gt;The following two lines of code are Express middlewares that enable us to retrieve the body of an HTTP request.&lt;/li&gt;
&lt;li&gt;Afterward, we set our server to listen for connections on &lt;code&gt;127.0.0.1&lt;/code&gt; and the designated port number.&lt;/li&gt;
&lt;li&gt;Finally, we requested Node to shut down the server if a promise rejection is not handled.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To ensure everything is set up correctly, use the following command to run the application.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Create a CockroachDB Connection&lt;/strong&gt;&lt;br&gt;
Next, open the &lt;code&gt;DB.js&lt;/code&gt; file to establish a connection with the CockroachDB cluster.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const Sequelize = require('sequelize-cockroachdb')
const dotenv = require('dotenv')

dotenv.config({path:"./config.env"})
const sequelize = new Sequelize(process.env.connectionString, {logging:false})

module.exports = sequelize
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code snippet above:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We imported the required dependencies and loaded the environment variables into the &lt;code&gt;process.env&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;Next, we established a connection to our database. &lt;/li&gt;
&lt;li&gt;Finally, we exported the database connection.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Creating the Book Inventory Schema.&lt;/strong&gt; &lt;br&gt;
Navigate to the &lt;code&gt;BookSchema.js&lt;/code&gt; file and make the necessary updates with the code provided below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const Sequelize = require('sequelize-cockroachdb')
const sequelize = require('../database/DB.js')

    const BookInventory = sequelize.define("BookInventory", {
        id:{
            type:Sequelize.DataTypes.INTEGER,
            autoIncrement:true,
            primaryKey:true
        },
        name:{
            type:Sequelize.DataTypes.TEXT,
            allowNull: false,
            unique: true
        },
        author:{
            type:Sequelize.DataTypes.TEXT,
            allowNull: false,
        },
        isbn:{
            type:Sequelize.DataTypes.INTEGER,
            allowNull: false,
            unique: true
        },
        pageCount:{
            type:Sequelize.DataTypes.INTEGER,
            allowNull:false
        }
   })

module.exports = BookInventory;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code snippet above: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We used the &lt;code&gt;define&lt;/code&gt; method to create a Schema, which enables us to store the specified information of a book.&lt;/li&gt;
&lt;li&gt;Lastly, we exported the newly created Schema for later use.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Sequelize automatically manages timestamps. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Creating the Controllers.&lt;/strong&gt;&lt;br&gt;
In this subsection, we'll write code to handle the requests and responses of the application. Navigate to the &lt;code&gt;controller&lt;/code&gt; folder and update the &lt;code&gt;Book.js&lt;/code&gt; file with the code below:&lt;/p&gt;

&lt;p&gt;To begin, import the Schema we created in the previous subsection.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const BookInventory = require('../schema/BookSchema.js')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;CREATE BOOK:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    const createBook = async (req,res) =&amp;gt; {    
        let book = await BookInventory.sync({force: false})
        book = await BookInventory.create(req.body)
                    .catch(err =&amp;gt; res.status(500).json({message: err.message}))

        res.status(201).json({data: book})
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code snippet above: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;BookInventory.sync&lt;/code&gt; method creates a new table based on the model's schema. By setting &lt;code&gt;force:false&lt;/code&gt;, sequelize avoids deleting the table and only update it.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;BookInventory.create&lt;/code&gt; method allows us to insert our book data into the database.&lt;/li&gt;
&lt;li&gt;Finally, we return the response. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;TO GET ALL BOOKS&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    const getAllBooks = async (req,res) =&amp;gt; {
        const books = await BookInventory.findAll()
                     .catch(err =&amp;gt; res.status(500).json({message: err.message}))

        res.status(200).json({length:books.length, data:books})
     }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code snippet above: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We retrieve and return all the books that are stored in the database.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;TO GET SINGLE BOOK&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; const getSingleBook = async (req,res) =&amp;gt; {
        const {id} = req.params 

        const book = await BookInventory.findOne({ where: {id} })
                    .catch(err =&amp;gt; res.status(500).json({response: err.message})) 

        res.status(200).json({data:book})
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code snippet above: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We destructured the &lt;code&gt;id&lt;/code&gt; passed into the request parameter.&lt;/li&gt;
&lt;li&gt; We queried the database for any entry that match the specified ID and returned the response.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;TO UPDATE A BOOK&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    const updateBook = async (req,res) =&amp;gt; {
        const {id} = req.params
        let book = await BookInventory.findOne({ where: {id} })
        .catch(err =&amp;gt; res.status(500).json({message: err.message}))     

        if(!book) {
            return res.status(404).json({message:`No book found with ID: ${id}`})
        }

        book = await book.update(req.body)
        res.status(200).json({data:book})
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code snippet above: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We updated the details of a book that matches the specified ID.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;TO DELETE A SINGLE BOOK&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    const deleteSingleBook = async (req,res) =&amp;gt; {
        const {id} = req.params 
        await BookInventory.destroy({ where: {id}})
                    .catch(err =&amp;gt; res.status(500).json({message: err.message}))

        res.status(202).json({data:"Book deleted"})
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code snippet above: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We deleted the book that matches the specified ID.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;TO DELETE ALL BOOKS&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    const deleteAllBooks = async (req,res) =&amp;gt; {
        await BookInventory.destroy({ where: {} })
                .catch(err =&amp;gt; res.status(500).json({message: err.message}))

        res.status(202).json({data:"Books deleted"})
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code snippet above:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We deleted all books stored in the database. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finally, export the controllers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    module.exports = {
        createBook, 
        getAllBooks,
        getSingleBook,
        updateBook,
        deleteSingleBook,
        deleteAllBooks
    } 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Creating the Routes&lt;/strong&gt;&lt;br&gt;
Let’s create the endpoints to send requests and receive a response. Navigate to the routes folder and open the &lt;code&gt;Book.js&lt;/code&gt; file. Update the file with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    const router = require('express').Router()
    const {
        createBook, 
        getAllBooks,
        getSingleBook,
        updateBook,
        deleteSingleBook,
        deleteAllBooks
    } = require('../controller/Book.js')

    router.post('/create', createBook)
    router.get('/getAllBooks', getAllBooks)
    router.get("/getSingleBook/:id", getSingleBook)
    router.put('/updateBook/:id', updateBook)
    router.delete('/deleteSingleBook/:id', deleteSingleBook)
    router.delete('/deleteAllBooks', deleteAllBooks)

    module.exports = router 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code snippet above: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We created a new router object to handle requests. &lt;/li&gt;
&lt;li&gt;Next, we imported the controllers and associated them with a specified method and URL.&lt;/li&gt;
&lt;li&gt;Lastly, we exported the router object. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Rounding up&lt;/strong&gt;&lt;br&gt;
Return to the &lt;code&gt;server.js&lt;/code&gt; file and import the router object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require('express')
 const dotenv = require('dotenv')

    dotenv.config({path:"./config.env"})
    const app = express()

    app.use(express.json())
    app.use(express.urlencoded({extended:false}))

    // router object
    const bookRoute = require('./routes/Book.js')
    app.use('/api/v1', bookRoute)

    const PORT = process.env.PORT 
    const server = app.listen(PORT, () =&amp;gt; {
        console.log(`Server started on 127.0.0.1:${PORT}`)
    })

    process.on("unhandledRejection", (err) =&amp;gt; {
        console.log(err.message)
        server.close(() =&amp;gt; process.exit())
    })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;In conclusion,  building a REST API with Node.js, Express, and CockroachDB provides developers with an effective solution for developing robust and scalable web applications. &lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.cockroachlabs.com/docs/stable" rel="noopener noreferrer"&gt;CockroachDB Documentation &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.oreilly.com/library/view/cockroachdb-the-definitive/9781098100230/" rel="noopener noreferrer"&gt;CockroachDB: The Definitive Guide by Guy Harrison, Jesse Seldess, Ben Darnell&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://sequelize.org/docs/v6/getting-started/" rel="noopener noreferrer"&gt;Sequelize Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>restapi</category>
      <category>node</category>
      <category>cockroachdb</category>
      <category>express</category>
    </item>
    <item>
      <title>What is a Cache?</title>
      <dc:creator>Ukagha Nzubechukwu </dc:creator>
      <pubDate>Sat, 15 Jul 2023 05:48:13 +0000</pubDate>
      <link>https://forem.com/backendbro/what-is-a-cache-3527</link>
      <guid>https://forem.com/backendbro/what-is-a-cache-3527</guid>
      <description>&lt;p&gt;A cache pronounced "cash" is a temporary high-speed storage layer that stores data in a location that is quicker to access. They allow a user to reuse previously computed data. Caches are essential for high-performance computers and applications because they provide faster access to frequently computed data.&lt;/p&gt;

&lt;p&gt;If frequently accessed data is stored in a cache, the average data memory access time can be reduced, thus reducing the total execution time of an application. A cache can be found in computers, web browsers, etc. Here are some of the most common ones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CPU (Central Processing Unit) cache&lt;/li&gt;
&lt;li&gt;Disk cache&lt;/li&gt;
&lt;li&gt;Web cache&lt;/li&gt;
&lt;li&gt;Application cache&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Memory access time refers to the time it takes to retrieve data from memory.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Caching in hardware and software
&lt;/h2&gt;

&lt;p&gt;Caching is a process of storing frequently accessed data in temporary storage (cache) to speed up future requests for that data.&lt;/p&gt;

&lt;p&gt;Most computers now have another level of memory referred to as the cache. The CPU cache is a compact memory layer that is positioned logically between the CPU register and the main memory, which stores computer instructions that are frequently accessed. A cache's storage capacity is less than the main memory but has a high data retrieval performance.&lt;/p&gt;

&lt;p&gt;When the CPU needs to access data, it first checks the cache. If the data is found in the cache, it can be accessed much more quickly than if it had to be retrieved from the main memory. This results in faster processing times; which is important in high-performance computing environments where speed is crucial. &lt;/p&gt;

&lt;p&gt;Additionally, caches can improve the overall system performance by reducing how often the CPU has to access main memory, which is slower and more resource-intensive.&lt;/p&gt;

&lt;p&gt;Your favorite online browser has a cache. A browser will always give you the choice to remove cached files and images whenever you attempt to clear your browsing history.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpaper-attachments.dropboxusercontent.com%2Fs_6EDB4FFBCFFD9AF98CF72535133BA0EB220B22E534088D3C42759ABA4F420548_1687595533905_broswer.avif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpaper-attachments.dropboxusercontent.com%2Fs_6EDB4FFBCFFD9AF98CF72535133BA0EB220B22E534088D3C42759ABA4F420548_1687595533905_broswer.avif" width="480" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The browser's cache improves your web experience by enhancing the performance of frequently visited websites.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do caches work?
&lt;/h2&gt;

&lt;p&gt;When a CPU attempts to fetch data in the cache, and it is available, this is called a cache hit. The percent of trials that result in a cache hit or miss is termed the cache hit ratio or rate.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A cache's data is typically stored in a fast-access memory.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A cache miss will occur when the data fetched is not present. When this happens, the data is taken from the main memory and copied into the cache. Copying new data into a Cache depends on the caching algorithm, cache protocol, and system policies implemented.&lt;/p&gt;

&lt;h2&gt;
  
  
  Caching algorithms
&lt;/h2&gt;

&lt;p&gt;Caching algorithms are implemented by giving each item in the cache a strength rating and removing the ones with the lowest ratings when new data is stored. The following are some examples of caching algorithms:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Least recently used&lt;/strong&gt;: When there is not enough room in the cache, It removes an item that was least used recently.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Least frequently used&lt;/strong&gt;: This algorithm removes the items with the lowest usage rates.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Most recently used&lt;/strong&gt;: This evicts recently used items first.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;First in, first out (FIFO)&lt;/strong&gt;: In a FIFO caching algorithm, any item added first to the cache will be the first one removed when there is no space left.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Last in, first out (LIFO)&lt;/strong&gt;: This caching algorithm will remove any item added last.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Cache policies
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cache read policies&lt;/strong&gt;: This policy illustrates how a cache responds to data requests. A read request may succeed or fail in fetching data from a cache.&lt;br&gt;
Should we get a cache miss, the main memory has to serve the request. We would want to reduce the chances of this happening, especially if it is a read-intensive application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cache write policies&lt;/strong&gt;: This policy depicts how data changes in the cache. They are:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Write-through cache&lt;/strong&gt;: This policy stores data directly into the cache and database. It ensures that data is consistent.
The cache can serve as a backup since the data will always be consistent with the one in the database.
&lt;p&gt; This policy is appropriate for applications that do not have high write requests. A high write volume will slow down the application's performance because it stores data in two locations. &lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9xt1spn48m5zhkr9wzi0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9xt1spn48m5zhkr9wzi0.png" alt="Write-through cache illustration" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Write-back cache&lt;/strong&gt;: In this policy, data is written only to the cache. The data is copied and stored in the underlying database. This policy promotes low latency.
    &lt;p&gt;The write-back cache policy is utilized in write-intensive applications since writing data to the cache is quicker than writing to the main memory.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvo866v39gbxyl5deacrn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvo866v39gbxyl5deacrn.png" alt="Write-back cache illustration" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Write-around cache&lt;/strong&gt;: It directly stores data in the database. When the write operation concludes, the cache is then updated. When there are a lot of write I/O operations, the write-around policy protects the cache from being flooded.
    &lt;p&gt;Data is not cached in this method unless it is read from the storage, which is a drawback. This policy is not suited for read-heavy applications.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fztrld43bwrr05o3cut6a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fztrld43bwrr05o3cut6a.png" alt="Write-around cache illustation" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to implement a cache network.
&lt;/h2&gt;

&lt;p&gt;Keeping the most frequently used data in the fast cache memory is the basic idea of a cache network. The average memory access time to retrieve data will thus be reduced.&lt;/p&gt;

&lt;p&gt;When implementing a cache layer, one should consider the validity of the data and its importance on the scale of preference. A well-implemented cache network will lead to a high cache hit rate.&lt;/p&gt;

&lt;p&gt;Filters such as TTL (time to live) should be used to expire out the data present in the cache as at when due.&lt;/p&gt;

&lt;p&gt;Another consideration may be whether or not the cache network requires a much higher availability. In-memory engines such as &lt;a href="https://www.nginx.com/" rel="noopener noreferrer"&gt;Redis&lt;/a&gt; and &lt;a href="https://redis.io/" rel="noopener noreferrer"&gt;NGINX&lt;/a&gt; provide high availability.&lt;/p&gt;

&lt;p&gt;A well-implemented cache network can function as an independent storage layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Types of cache.
&lt;/h2&gt;

&lt;p&gt;There are four types of cache:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;CPU cache&lt;/strong&gt;: This cache is located on the processor chip and stores frequently accessed data and instructions. CPU Cache makes up three groups:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;L1 cache memory -  It tends to be small. It holds only a limited amount of data.&lt;/li&gt;
&lt;li&gt;L2 cache memory - The secondary cache is an intermediary between your device's processor and the main memory. When a cache miss occurs, the CPU immediately checks the L2 for the missing data.&lt;/li&gt;
&lt;li&gt;L3 cache memory - The L3 is the slowest among CPU cache units. It is a specialized memory designed to boost L1 and L2 performance.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Web cache&lt;/strong&gt;: Web caches keep track of information from servers, browsers, and websites so they can be easily retrieved when fetched to shorten loading times. There are four types of web cache:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Site cache: The first time you visit a website, the site cache stores information about your activity. When you access the web page offline, it retrieves the previously saved data from the site cache.&lt;/li&gt;
&lt;li&gt;Browser cache: It also acts like the site cache. It stores the details of the frequently visited websites to serve them up faster whenever requested.&lt;/li&gt;
&lt;li&gt;Micro cache: It stores the static components of a dynamic website.&lt;/li&gt;
&lt;li&gt;Server cache: It helps reduce server load.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Application/Software cache&lt;/strong&gt;: This cache is used by software applications to store frequently accessed data, such as configuration files, templates, and other resources. It helps improve data retrieval performance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Distributed cache&lt;/strong&gt;: Big corporations store data across multiple database servers using a distributed cache.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Disk cache&lt;/strong&gt;: This cache is used by operating systems to speed up disk operations. It stores frequently accessed data in memory so it can be read or written to disk more quickly.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Importance of a cache.
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Offline data access&lt;/strong&gt;: Internet browsers use cache to store data temporarily. By caching regularly accessed data, browsers can serve previously visited web pages from their disk instead of from the internet.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reduced database cost&lt;/strong&gt;: Highly available cache such as &lt;a href="https://redis.io/" rel="noopener noreferrer"&gt;Redis&lt;/a&gt; and &lt;a href="https://www.nginx.com/" rel="noopener noreferrer"&gt;Nginx&lt;/a&gt; can serve as a standalone storage layer. A cache helps to reduce the number of databases needed, thus reducing the cost of operation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Data integrity and consistency&lt;/strong&gt;: Data can remain in a static database where they are durable and thorough. Caches help to maintain data integrity and consistency by taking a copy or snapshot of what is in the database — ensuring that data is consistent across all users.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Increase application efficiency&lt;/strong&gt;: Redirecting a chunk of the read requests to a cache helps reduce the load on an application and improves the application's performance.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Drawbacks of a cache.
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Data validity&lt;/strong&gt;: The main drawback of a cache is the possibility of displaying outdated data to a user due to improper cache maintenance, which can lead to evictions and low cache hit rates.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Bottleneck&lt;/strong&gt;: Caches can cause a bottleneck if they are not properly managed. When a cache is too small, it can quickly become overwhelmed; this might lead to cache misses and slower processing times. In some cases, caches can also cause contention for shared resources, thus slowing down processing times.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;High cost&lt;/strong&gt;: Caches are built using high-speed memory chips, which are more expensive. Additionally, caches require complex hardware and software design to ensure that they are effective in improving performance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Volatile&lt;/strong&gt;: The cache memory is volatile since it stores data temporarily. Caches are not meant to store data permanently, but rather to provide quick access to data needed frequently. As a result, caches are volatile and require constant refreshing to keep the data up-to-date and accurate.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;So far, we have learned what cache and caching are, how to implement a cache network, its types, and its merits and demerits. Without a cache, we would have to start afresh anytime we close a website or a computer.&lt;br&gt;
I know this article is a long read. I am happy you made it to the end. 😊&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.techtarget.com/whatis/definition/caching" rel="noopener noreferrer"&gt;What is caching, and how does it work?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.sciencedirect.com/topics/engineering/cache-policy" rel="noopener noreferrer"&gt;Caching policy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/caching/best-practices/" rel="noopener noreferrer"&gt;Caching Best Practices&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cache</category>
      <category>memory</category>
      <category>caching</category>
    </item>
    <item>
      <title>A step-by-step guide: How to use MongoDB with Node.js.</title>
      <dc:creator>Ukagha Nzubechukwu </dc:creator>
      <pubDate>Fri, 26 Aug 2022 20:08:47 +0000</pubDate>
      <link>https://forem.com/backendbro/using-mongodb-with-nodejs-175l</link>
      <guid>https://forem.com/backendbro/using-mongodb-with-nodejs-175l</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;When working with a server, one will always have to save and retrieve data using a database. There are many server-side languages and databases available. In this article, you will learn how to use MongoDB with Node.js. &lt;/p&gt;

&lt;p&gt;MongoDB is a non-relational database. It is a document-oriented storage system. It stores and retrieves data in JSON format, instead of the traditional table and row format used in relational databases ( MYSQL, PostgreSQL ). &lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;A supported version of Node.js installed&lt;/li&gt;
&lt;li&gt;A MongoDB Atlas &lt;a href="https://www.mongodb.com/atlas/database" rel="noopener noreferrer"&gt;account&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Basic knowledge of Node.js and Express.js&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Getting started
&lt;/h3&gt;

&lt;p&gt;To demonstrate how to use &lt;a href="https://www.mongodb.com/" rel="noopener noreferrer"&gt;MongoDB&lt;/a&gt; with &lt;a href="https://nodejs.org/en" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt;, we will build a simple book inventory. You will learn how to add, get, edit, and remove books from your inventory. &lt;/p&gt;

&lt;p&gt;Make sure that your code editor has the following folders and files ready.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8zkvpojjrp1x4ctf8iv6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8zkvpojjrp1x4ctf8iv6.png" alt="vs.png" width="800" height="613"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Installing dependencies
&lt;/h3&gt;

&lt;p&gt;Quick note:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://mongoosejs.com/" rel="noopener noreferrer"&gt;Mongoose&lt;/a&gt; is a library that creates a connection between MongoDB and an Express-based application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.dotenv.org/" rel="noopener noreferrer"&gt;Dotenv&lt;/a&gt; is used to load data from a &lt;code&gt;.env&lt;/code&gt; file into a Node.js environment so it can access it using &lt;code&gt;process.env&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Moving on, run the commands below in your terminal to install the dependencies needed for this project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install express 
npm install mongoose
npm install  dotenv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Retrieving the MongoDB connection string
&lt;/h3&gt;

&lt;p&gt;Login into your MongoDB Atlas &lt;a href="https://account.mongodb.com/account/login" rel="noopener noreferrer"&gt;account&lt;/a&gt; to connect to the database from your Node.js application  &lt;/p&gt;

&lt;p&gt;Follow these easy steps to retrieve the connection string:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click on &lt;code&gt;connect&lt;/code&gt; on your Database Deployment dashboard.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyx5bu8t0hg3vifs11s7a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyx5bu8t0hg3vifs11s7a.png" alt="new_connect.png" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Choose the &lt;code&gt;Connect to your application&lt;/code&gt; option.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4dkog8hre7cvwg4lzy86.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4dkog8hre7cvwg4lzy86.png" alt="connection.png" width="800" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Copy the connection string&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6m4yxpu2tygavh978fjq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6m4yxpu2tygavh978fjq.png" alt="cluster.png" width="800" height="397"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Writing code
&lt;/h3&gt;

&lt;p&gt;At this point, the dependencies and connection string should be ready for use. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;server.js&lt;/code&gt; file should look like this for the time being&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require('express')
const dotenv = require('dotenv')
const path = require('path')
const app = express()

dotenv.config({path: './config/config.env'})
app.use(express.json())

const port = process.env.port
app.listen(port, () =&amp;gt; {
    console.log(`port ${port} connected...`)
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;config.env&lt;/code&gt; file will hold the following environment variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;port = 8080
mongo_uri = mongodb+srv://mongodb-template:&amp;lt;password&amp;gt;@cluster0.8lmmv.mongodb.net/myFirstDatabase?retryWrites=true&amp;amp;w=majority
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart your server after copying the code snippet above into your &lt;code&gt;config.env&lt;/code&gt; file&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Replace &lt;code&gt;&amp;lt;password&amp;gt;&lt;/code&gt; with the actual password of the database&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Next step, let's create a MongoDB connection, in the &lt;code&gt;db.js&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const mongoose = require('mongoose')

const connectDb = async () =&amp;gt; {
const conn = await mongoose.connect(process.env.mongo_uri,  {
useNewUrlParser: true,
useUnifiedTopology: true
})
console.log(`mongodb connected: ${conn.connection.host}`)
}

module.exports = connectDb

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

&lt;/div&gt;



&lt;p&gt;Now that the database connection is ready, update the &lt;code&gt;server.js&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require('express')
const dotenv = require('dotenv')
const connectDb = require('./database/db')
const app = express()

dotenv.config({path:'./config/config.env'})
app.use(express.json())

//database connection
connectDb()

const port = process.env.port
app.listen(port, () =&amp;gt; {
    console.log(`port ${port} connected...`)
})

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Creating the schema
&lt;/h3&gt;

&lt;p&gt;MongoDB schema is a JSON object that decides what the database is allowed to be stored.&lt;/p&gt;

&lt;p&gt;Setting up &lt;code&gt;BookSchema.js&lt;/code&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const mongoose = require('mongoose')

const BookSchema = new mongoose.Schema({
    title:{
        type:String,
        required:true,
        unique:true
    },
    author:{
        type:String,
        required:true,
        unique:true
    },
    isbn:{
        type:String,
        unique:true
    }
})

module.exports = mongoose.model('BookSchema', BookSchema)

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Routes
&lt;/h3&gt;

&lt;p&gt;Starting on the &lt;code&gt;book.js&lt;/code&gt; file, bring in the &lt;code&gt;router&lt;/code&gt; and &lt;code&gt;BookSchema&lt;/code&gt; model.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const router = require('express').Router()
const Book = require('../model/BookSchema')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;book.js&lt;/code&gt; file will contain the following requests:&lt;/p&gt;

&lt;h5&gt;
  
  
  POST request
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;router.post('/', async (req,res) =&amp;gt; {
    const { title, author, isbn } = req.body
    const newBook = await Book.create({ title, author, isbn })
    res.status(201).json({ 
        success:true, 
        data:newBook 
    })
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code snippet above will store the &lt;code&gt;name, author, and isbn&lt;/code&gt; of a book.&lt;/p&gt;

&lt;h5&gt;
  
  
  GET request
&lt;/h5&gt;

&lt;blockquote&gt;
&lt;p&gt;There will be two variants of the &lt;code&gt;GET&lt;/code&gt; request. One will &lt;code&gt;GET&lt;/code&gt; all books while the other will &lt;code&gt;GET&lt;/code&gt; just a particular book.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;router.get('/',  async (req,res) =&amp;gt; {
    const books = await Book.find()
    res.status(200).json({ 
        success:true, 
        data: books, 
        num: books.length
    })
})

router.get('/:id',  async (req,res) =&amp;gt; {
  const book = await Book.findById(req.params.id)  
  res.status(200).json({ 
      success:true, 
      data: book 
    })
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  PUT request
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;router.put('/:id', async (req,res) =&amp;gt; {
    let book = await Book.findById(req.params.id)
    book = await Book.findByIdAndUpdate(req.params.id, {$set:req.body}, {
        new:true,
        runValidator:false
    })  
    res.status(200).json({ 
        success:true, 
        data: book 
    })
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code snippet above updates the book details that match the specified ID.&lt;/p&gt;

&lt;h5&gt;
  
  
  DELETE request
&lt;/h5&gt;

&lt;blockquote&gt;
&lt;p&gt;This operation will also have two variants in case we want to DELETE one or all entries from the database.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;router.delete('/:id', async (req,res) =&amp;gt; {
    await Book.findByIdAndRemove(req.params.id)
    res.status(200).json({ 
        success:true, 
        data: 'book deleted' 
    })
})

router.delete('/', async (req,res) =&amp;gt; {
    await Book.deleteMany()
   res.status(200).json({ 
       success:true, 
       data: 'All books deleted' 
    })
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lastly, export the router.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = router
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Take a deep breath. At this point, we are almost done.&lt;/p&gt;

&lt;p&gt;Update the &lt;code&gt;server.js&lt;/code&gt; file one last time with the &lt;code&gt;router&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require('express')
const dotenv = require('dotenv')
const connectDb = require('./database/db')
const app = express()

dotenv.config({path:'./config/config.env'})
app.use(express.json())

//database connection
connectDb()

//mount the route
const bookRoute = require('./routes/book')
app.use('/api/v1/book', bookRoute)

const port = process.env.port
app.listen(port, () =&amp;gt; {
    console.log(`port ${port} connected...`)
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;In this article, you learned how to use MongoDB with Node.js by creating a simple project. I hope you found this tutorial easy to follow. &lt;/p&gt;

&lt;p&gt;Happy coding! 😀&lt;/p&gt;

&lt;h3&gt;
  
  
  Credits
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt; &lt;a href="https://www.mongodb.com/docs/" rel="noopener noreferrer"&gt;MongoDB docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/backendbro/mongodb_template" rel="noopener noreferrer"&gt;Project GitHub Link&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>node</category>
      <category>mongodb</category>
      <category>database</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How to Push to Github from VScode - For Windows</title>
      <dc:creator>Ukagha Nzubechukwu </dc:creator>
      <pubDate>Thu, 05 May 2022 20:51:00 +0000</pubDate>
      <link>https://forem.com/backendbro/how-to-push-to-github-from-vscode-for-windows-54l0</link>
      <guid>https://forem.com/backendbro/how-to-push-to-github-from-vscode-for-windows-54l0</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt; is a cloud hosting platform for software development and version control. GitHub facilitates collaborative programming by making repositories accessible online.&lt;/p&gt;

&lt;p&gt;To begin, it's important to distinguish between &lt;strong&gt;Git&lt;/strong&gt; and &lt;strong&gt;Github&lt;/strong&gt;.&lt;br&gt;
&lt;strong&gt;Git&lt;/strong&gt; is a powerful version control system that allows developers to track and save changes in their codebase locally. Git allows for offline work and provides a backup in case of server failure. &lt;br&gt;
With Git, developers can push their changes to a remote repository, such as GitHub, enabling them to collaborate and work together seamlessly.&lt;br&gt;
Git provides features like commit history, diffing, and reverting changes, which make it easy to manage and maintain code over time. &lt;/p&gt;

&lt;p&gt;On the other hand, &lt;strong&gt;GitHub&lt;/strong&gt; is an cloud-based Git repository that allows users to store, manage, track, and collaborate on software projects. &lt;br&gt;
GitHub makes it easier for individuals and teams to use Git for version control. GitHub offers a range of features and tools to support software development. &lt;/p&gt;

&lt;p&gt;This article will guide you on how to set up your coding environment to push your code from VScode to GitHub. You will use the GitHub SSH keys to establish a connection, making the process more secure. This article provides a comprehensive guide that is easy to follow.&lt;/p&gt;
&lt;h2&gt;
  
  
  Goals
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt; Setting up the SSH keys&lt;/li&gt;
&lt;li&gt; Pushing to Github &lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt; &lt;a href="https://git-scm.com/download/win" rel="noopener noreferrer"&gt;Git Bash - Standalone Installer&lt;/a&gt; &lt;/li&gt;
&lt;li&gt; &lt;a href="https://github.com/login" rel="noopener noreferrer"&gt;Github account&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt; &lt;a href="https://code.visualstudio.com/download" rel="noopener noreferrer"&gt;Visual Studio Code&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;Open Git bash and configure the credentials to match your Github account details.&lt;/p&gt;

&lt;p&gt;Run the following commands one after the other:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git config  --global  user.name  "username" 
git config  --global  user.email  "your_email@email.com" 

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

&lt;/div&gt;



&lt;p&gt;To confirm that you have entered the correct details, run this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git config -l 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Getting the SSH Keys
&lt;/h3&gt;

&lt;p&gt;SSH stands for Secure Shell. The SSH protocol allows you to connect and authenticate to remote servers and services securely. By using SSH keys, you can easily connect to your GitHub account without providing your credentials each time you visit. GitHub SSH enables you to securely access and write data to specific repositories.&lt;/p&gt;

&lt;p&gt;Moving on, to obtain the SSH keys, you will need a Key Fingerprint first. Follow these simple steps to generate one:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; Open Git bash&lt;/li&gt;
&lt;li&gt; Run the command below:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; ssh-keygen -t ed25519 -C "your_email@email.com"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Press &lt;strong&gt;Enter&lt;/strong&gt; when asked: "Enter a file in which to save the key". It will store the key in the default location. Although you can specify a file if you wish to.&lt;/li&gt;
&lt;li&gt;When prompted to enter a &lt;strong&gt;passphrase&lt;/strong&gt;, type in your chosen passphrase and then press &lt;strong&gt;Enter&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Don't worry if your inputs are not visible. It's a security feature to prevent shoulder surfing. Carefully enter a passphrase and store it safely for future use. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;To proceed, re-enter your passphrase and click the &lt;strong&gt;Enter&lt;/strong&gt; button to complete the process.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At this point, you should have a Key fingerprint.&lt;/p&gt;

&lt;h4&gt;
  
  
  Generating the SSH Key
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Run the following commands one after the other:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; eval "$(ssh-agent -s)"
 ssh-add ~/.ssh/id_ed25519
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Enter the passphrase you created in the last sub-section.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Navigate to the location where the identity was added on your PC.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foxdrer6tzsn5ehk3sxeq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foxdrer6tzsn5ehk3sxeq.png" alt="Identity-location" width="800" height="526"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Drag and drop the &lt;strong&gt;&lt;code&gt;id_ed25519.pub&lt;/code&gt;&lt;/strong&gt; file into your VScode to reveal the SSH Key.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs4kuwqepj0nv5z2sztxz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs4kuwqepj0nv5z2sztxz.png" alt="SSH-KEY" width="785" height="653"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding the new SSH Key
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Navigate to the &lt;a href="https://github.com/settings/ssh/new" rel="noopener noreferrer"&gt;Add new SSH Key&lt;/a&gt; page on your GitHub account and paste your new SSH key in the &lt;strong&gt;&lt;code&gt;key&lt;/code&gt;&lt;/strong&gt; field.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pushing to Github
&lt;/h3&gt;

&lt;p&gt;After successfully setting up SSH, follow these simple steps to push a mock project to Github.&lt;/p&gt;

&lt;p&gt;Below is a visual illustration of the mock project.&lt;br&gt;
It is bland html file and a js file that logs &lt;strong&gt;&lt;code&gt;('I just pushed to GitHub')&lt;/code&gt;&lt;/strong&gt; to the console.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi3594srsbwpjw3ztuxpq.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi3594srsbwpjw3ztuxpq.PNG" alt="project-illustration" width="800" height="583"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First, open your terminal and select &lt;strong&gt;&lt;code&gt;bash&lt;/code&gt;&lt;/strong&gt; as your default profile by clicking on the dropdown icon.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb9civ2rzojit0ob2b2iy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb9civ2rzojit0ob2b2iy.png" alt="Toggle-terminal" width="800" height="584"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Return to your Github account, and navigate to the create repository &lt;a href="https://github.com/new" rel="noopener noreferrer"&gt;section&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Enter a repository name of your choice&lt;/li&gt;
&lt;li&gt;You can skip the description &lt;/li&gt;
&lt;li&gt;Ignore the other checkboxes and click create repository &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxngwgu7k78sqc77tj10o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxngwgu7k78sqc77tj10o.png" alt="create_repo" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Return to your VScode terminal and enter the following commands:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;git init&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp5n18qo681mkzl0r5s0u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp5n18qo681mkzl0r5s0u.png" alt="git-init" width="800" height="128"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;git add .&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fveygfr7idzams9narkdo.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fveygfr7idzams9narkdo.PNG" alt="git-add" width="800" height="106"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;git commit -m [Enter your message of choice here]&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzrfny2wtti2i32lwksqn.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzrfny2wtti2i32lwksqn.PNG" alt=" " width="800" height="171"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;git remote add origin https://github.com/backendbro/mock_project.git&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Copy the line above from your repository dashboard, as yours will be different&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo799o5tbfyno32h9sppr.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo799o5tbfyno32h9sppr.PNG" alt="git-remote-origin" width="800" height="113"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;git branch -M main&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6pcm6oin7gyos97vbz17.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6pcm6oin7gyos97vbz17.PNG" alt="git-branch" width="800" height="121"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;git push -u origin main&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Select the "Sign in with your browser" option when prompted by the Git Credential Manager. Then, wait patiently for a browser window to open so you can complete the process.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjauu576sinzu9dip1j3l.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjauu576sinzu9dip1j3l.PNG" alt="Git-credential-manager-pop-up" width="422" height="365"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the authentication and authorization process was completed, the mock project was pushed to GitHub.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhrkbvj5iww99jhe1xf63.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhrkbvj5iww99jhe1xf63.PNG" alt="git-push" width="800" height="248"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Voila! We successfully pushed our project from VScode to GitHub. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyfrr6rgyt0bcy68h932i.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyfrr6rgyt0bcy68h932i.PNG" alt="deployed-project" width="800" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Conclusion
&lt;/h4&gt;

&lt;p&gt;You have successfully set up your SSH Keys, and pushed a mock project to GitHub from VScode. Now, pushing your projects to GitHub will be a breeze as you have been authenticated and authorized.&lt;br&gt;
I hope that with this newfound knowledge, you can showcase your incredible project to the world.&lt;br&gt;
Happy coding!&lt;/p&gt;

&lt;h3&gt;
  
  
  Resources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/backendbro/mock_project/" rel="noopener noreferrer"&gt;Mock Project&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/authentication/connecting-to-github-with-ssh" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;VScode&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>opensource</category>
      <category>github</category>
      <category>vscode</category>
      <category>git</category>
    </item>
  </channel>
</rss>
