<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Prankur Pandey - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Prankur Pandey - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Fri, 22 May 2026 17:39:04 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/author/prankurpandeyy/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Build a Portfolio Website Using Figma and AI Tools – A Guide for Developers ]]>
                </title>
                <description>
                    <![CDATA[ Ever since my article on How to Become a Full Stack Developer and Get a Job in 2025 went viral, I’ve received countless DMs, emails, and even WhatsApp messages from readers. People have been asking about everything from learning to code and mastering... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-a-portfolio-website-using-figma-and-ai-tools/</link>
                <guid isPermaLink="false">691b93910ca13a7c59ae7a34</guid>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ figma ]]>
                    </category>
                
                    <category>
                        <![CDATA[ AI ]]>
                    </category>
                
                    <category>
                        <![CDATA[ portfolio ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Prankur Pandey ]]>
                </dc:creator>
                <pubDate>Mon, 17 Nov 2025 21:28:49 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1763156337448/4d944077-b800-4bfd-bb70-645777eb00a2.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Ever since my article on <a target="_blank" href="https://www.freecodecamp.org/news/become-a-full-stack-developer-and-get-a-job/">How to Become a Full Stack Developer and Get a Job in 2025</a> went viral, I’ve received countless DMs, emails, and even WhatsApp messages from readers. People have been asking about everything from learning to code and mastering system design to web design and how AI fits into modern development.</p>
<p>I’ve been taking it one topic at a time. My last piece on system design principles received great feedback, and that encouragement has kept me going.</p>
<p>Lately, I’ve developed a deep interest in UI/UX design – not just out of curiosity, but because so many readers have been requesting a detailed guide. They want one that explains how to learn web design, how to apply it to real-world projects, and how AI is reshaping the field.</p>
<p>Looking back, my journey started six years ago as a software tester. From there, I transitioned into full-stack development, then DevOps. I also explored data analysis, and today I manage a full-time freelancing career alongside my farming work.</p>
<p>One thing I’ve learned along the way is that a strong portfolio can take you to places you’d never imagined.</p>
<p>I’ve had a portfolio for years, but now I’m completely rebuilding it from scratch to make it cleaner, smarter, and more reflective of who I’ve become as a developer.</p>
<p>In this tutorial, I’ll walk you through how I created my new portfolio and show you how you can build yours too – with the right structure, design, and a touch of copywriting magic to make it stand out.</p>
<h3 id="heading-what-well-cover">What We’ll Cover:</h3>
<ul>
<li><p><a class="post-section-overview" href="#heading-what-is-a-portfolio-website-and-why-do-you-need-one">What is a Portfolio Website and Why Do You Need One?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-important-portfolio-website-components">Important Portfolio Website Components</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-make-your-portfolio-website-stand-out">How to Make Your Portfolio Website Stand Out</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-use-figma-to-design-your-own-portfolio">How to use Figma to Design Your Own Portfolio</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-tools-for-figma-to-code-generation">Tools for Figma to Code Generation</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-copywriting-for-your-portfolio">Copywriting for Your Portfolio</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-testing-benchmarks-for-a-portfolio-website">Testing Benchmarks for a Portfolio Website</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-hosting-your-portfolio">Hosting Your Portfolio</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-use-your-portfolio-effectively">How to Use Your Portfolio Effectively</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-qampa">Q&amp;A</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-final-notes">Final Notes</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-what-is-a-portfolio-website-and-why-do-you-need-one">What is a Portfolio Website and Why Do You Need One?</h2>
<p>A portfolio website is your own space on the internet where you can proudly show your best work, projects, and achievements. Think of it as your digital résumé, but far more visual and personal. Instead of just listing your skills or job titles, it lets people actually see what you’ve built, designed, or created, and this tells your story better than any document can.</p>
<p>It helps employers, clients, or collaborators understand your skills, experience, and creativity at a glance. While it’s beneficial for designers, developers, writers, and photographers, anyone who wants to share their work online can create one, from students and freelancers to business professionals.</p>
<p>Here’s why having a portfolio website matters:</p>
<ul>
<li><p><strong>A collection of your best work:</strong> like a gallery where you keep your most impressive projects, artwork, or achievements all in one place.</p>
</li>
<li><p><strong>Your online identity:</strong> It’s your personal brand, showing who you are, what you do, and what makes your work stand out.</p>
</li>
<li><p><strong>A way to showcase your skills:</strong> Through images, videos, and live demos, it give people a clear picture of your talent and creativity.</p>
</li>
<li><p><strong>An open door for opportunities:</strong> People can visit your site, explore your work, and contact you directly for jobs, collaborations, or freelance work.</p>
</li>
<li><p><strong>A tool for career growth:</strong> A well-built portfolio helps you attract clients, get noticed by employers, and open doors to new partnerships.</p>
</li>
</ul>
<p>In simple words, your portfolio website is your professional story told visually – a mix of your work, passion, and personality that helps the world see what you’re capable of.</p>
<h2 id="heading-important-portfolio-website-components">Important Portfolio Website Components</h2>
<p>Now that we know why a portfolio website matters, let’s look at the key components that make it stand out. Each part plays a role in showing who you are, what you can do, and how you can help others.</p>
<p>Since I’m a developer, and the people who have reached out to me are mostly tech enthusiasts, here I’ll give a technical portfolio example. But you can apply the learnings from this guide to build any type of portfolio for any niche/business.</p>
<h3 id="heading-1-home-page-the-first-impression">1. Home Page: The First Impression</h3>
<p>Your homepage is like the front door to your digital world. It should quickly tell visitors who you are, what you do, and why you’re worth hiring or collaborating with. Keep it clean, simple, and welcoming: just a few strong lines about your skills and what kind of projects you work on.</p>
<p>Tip: Use a short headline like “Hi, I’m Prankur – I build fast, user-friendly web apps.”</p>
<h3 id="heading-2-about-section-your-story">2. About Section: Your Story</h3>
<p>This is where you make your connection with the audience. Share your journey: how you started, what drives you, and what kind of problems you love solving. Keep it conversational and honest. People love working with real humans, not buzzwords.</p>
<p>Tip: Add a professional but friendly photo (optional) here to make it more personal.</p>
<h3 id="heading-3-projects-work-section-show-dont-just-tell">3. Projects / Work Section: Show, Don’t Just Tell</h3>
<p>This is the heart of your portfolio. List your best projects – the ones that represent your strongest skills and the kind of work you want to keep doing. Each project should include:</p>
<ul>
<li><p>A short description of what it is.</p>
</li>
<li><p>The tools or technologies you used.</p>
</li>
<li><p>The challenge you solved.</p>
</li>
<li><p>A screenshot or live demo link.</p>
</li>
<li><p>GitHub link so that people can see how you code</p>
</li>
</ul>
<p>Tip: 3–6 strong projects are better than 15 average ones. If you’re actively contributing to open source, you should add that to your portfolio, too.</p>
<h3 id="heading-4-case-studies-tell-the-story-behind-the-work">4. Case Studies: Tell the Story Behind the Work</h3>
<p>Case studies take your projects one step further. They explain your thinking process and how you understood the client’s problem, what steps you took, and what results you achieved. This helps potential employers or clients see your problem-solving skills, not just your designs or code.</p>
<p>Tip: Keep it short and focus on the “before → after” transformation.</p>
<h3 id="heading-5-skills-amp-tools-section">5. Skills &amp; Tools Section</h3>
<p>List your key technical and creative skills, like HTML, CSS, JavaScript, React, Figma, or AI.<br>You can group them as:</p>
<ul>
<li><p>Frontend Tools</p>
</li>
<li><p>Backend Tools</p>
</li>
<li><p>Design Tools</p>
</li>
<li><p>AI or Productivity Tools</p>
</li>
</ul>
<p>Tip: Keep the list focused and highlight the tools you actually use, not every tool you’ve ever tried.</p>
<h3 id="heading-6-testimonials-social-proof-optional">6. Testimonials: Social Proof (Optional)</h3>
<p>People trust people. Include a few quotes or short testimonials from clients, teammates, or mentors who can vouch for your skills and professionalism. It instantly builds trust and credibility.</p>
<p>If you are just starting, you can add this section later on, as initially you won’t have testimonials. Once you start working, you can politely ask your clients to give their feedback on your work. Just make sure to get their permission to add it to your site.</p>
<p>Tip: Ask for a 2–3 sentence testimonial right after finishing a project.</p>
<h3 id="heading-7-blog-or-articles-section-optional">7. Blog or Articles Section (Optional)</h3>
<p>If you write tutorials or share knowledge, add a blog section. It helps you stand out as someone who not only builds but also teaches and communicates ideas clearly. It also boosts SEO and keeps your site fresh.</p>
<p>Tip: Even 2–3 strong, educational articles can make a huge difference.</p>
<h3 id="heading-8-contact-section-make-it-easy-to-reach-you">8. Contact Section: Make It Easy to Reach You</h3>
<p>Your contact page should be simple, visible, and welcoming. Include your email, social links (LinkedIn, GitHub, X/Twitter), and maybe a contact form. You can also add a small call to action like:</p>
<blockquote>
<p>“Have a project in mind? Let’s connect.”</p>
</blockquote>
<p>Tip: Place your contact link in the main menu. Don’t hide it.</p>
<h3 id="heading-9-resume-downloadable-cv-optional">9. Résumé / Downloadable CV (Optional)</h3>
<p>If you’re job-hunting, include a link to download your latest résumé. You can also add a “quick summary” of your experience, education, and certifications directly on the website.</p>
<h3 id="heading-10-call-to-action-cta">10. Call to Action (CTA)</h3>
<p>Every great portfolio ends with a nudge – a simple next step for your visitor. It could be:</p>
<ul>
<li><p>“Let’s build something amazing together.”</p>
</li>
<li><p>“Hire me for your next project.”</p>
</li>
<li><p>“Check out my latest work.”</p>
</li>
</ul>
<p>A clear CTA can help turn a visitor into a lead or follower.</p>
<p>Your portfolio is not just a gallery. It’s a storytelling tool. It tells the world what you can do, how you think, and what makes you unique. Make sure every section serves a purpose, looks clean, and reflects your real personality.</p>
<h2 id="heading-how-to-make-your-portfolio-website-stand-out">How to Make Your Portfolio Website Stand Out</h2>
<p><strong>1. Showcase Your Best Work</strong><br>Only include your strongest and most relevant projects. Quality matters more than quantity. A few great examples of your work will create a much better impression than a long list of average ones.</p>
<p><strong>2. Use High-Quality Images and Videos</strong><br>Make sure your work looks clear and professional. Good visuals instantly catch attention and show that you care about presentation. Use clean screenshots, mockups, or short demo videos.</p>
<p><strong>3. Write Clearly and Keep It Short</strong><br>Explain your work and skills in simple, easy-to-read language. Avoid long paragraphs — most visitors just skim. A few lines that get straight to the point are enough.</p>
<p><strong>4. Tell Your Story</strong><br>Use your “About Me” section to share your journey — how you started, what you love building, and what kind of work you enjoy most. People connect more with stories than with just titles or resumes.</p>
<p><strong>5. Keep Navigation Simple</strong><br>Make sure visitors can easily find your projects, contact info, and other key details. A clean menu and clear layout help people focus on your work instead of figuring out where to click.</p>
<p><strong>6. Keep It Updated</strong><br>Whenever you finish a new project or learn a new skill, add it to your portfolio. An up-to-date portfolio shows that you’re active, learning, and growing in your field.</p>
<p><strong>7. Optimise for SEO</strong><br>Use the right keywords — the ones people might type when searching for your kind of work (like “frontend developer” or “Figma to code expert”). This helps your site appear in search results. Many AI-powered website builders can assist with basic SEO setup.</p>
<h2 id="heading-how-to-use-figma-to-design-your-own-portfolio">How to Use Figma to Design Your Own Portfolio</h2>
<p>Designing your own portfolio might sound intimidating at first, but tools like <strong>Figma</strong> make the process surprisingly intuitive – even if you’re not a professional designer. With Figma, you can visually plan every section of your portfolio before turning it into a live website.</p>
<p>I’ve been learning web design and using Figma for a long time for my client projects. But here, I didn’t build the entire portfolio from scratch. I used Figma’s design inspiration library to get some ideas, and I built the portfolio based on that.</p>
<p>Let’s walk through how you can do that, step by step, using the layout shown below as an example:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1763135985349/8cb05eb4-7562-4845-992e-9829ebadf6a4.png" alt="example-portfolio" class="image--center mx-auto" width="1366" height="3226" loading="lazy"></p>
<h3 id="heading-1-start-with-a-wireframe">1. Start With a Wireframe</h3>
<p>Before adding colours or fancy visuals, begin with a simple wireframe. It’s basically a rough sketch of your portfolio layout.</p>
<p>In Figma, you can create frames for each section you want on your site:</p>
<ul>
<li><p>Hero section (your name, title, and call-to-action buttons)</p>
</li>
<li><p>“What I Do Best” or skills</p>
</li>
<li><p>Tech stack</p>
</li>
<li><p>Featured projects</p>
</li>
<li><p>Blog or article previews</p>
</li>
<li><p>Services and pricing</p>
</li>
<li><p>Contact form</p>
</li>
</ul>
<p>This helps you get the structure right before focusing on design. Don’t worry about fonts or images yet – just boxes and text placeholders are enough.</p>
<p>Here’s a sample wireframe I created to visualise how everything should look before moving into Figma. It’s always a good idea to sketch or plan your design on paper first, as it helps you get a clear picture of the layout and refine details like colours, fonts, and spacing early on.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1762753167965/584a137e-6414-4ce6-ad1e-0408d040003f.png" alt="wireframe-figma" class="image--center mx-auto" width="1024" height="1024" loading="lazy"></p>
<p>Once the wireframe is ready, you can start adding your preferred colours, typography, and images to bring the design to life. If you want to go a step further and understand how to choose the right colour palettes and fonts, it’s worth exploring <strong>design psychology</strong> — it plays a huge role in how people perceive your work.</p>
<h3 id="heading-2-add-visual-hierarchy-and-colour">2. Add Visual Hierarchy and Colour</h3>
<p>Once your structure feels solid, start adding typography and colour to create a visual hierarchy. This helps the viewer’s eyes know where to focus first.</p>
<p>For example, in the sample design above, the <strong>hero section</strong> (at the top) instantly grabs attention with bold typography (“I build things for the web”) and a subtle background/hero image.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1763135295720/87dfa444-1e80-45b2-8e57-7f88971a4742.png" alt="visual-hierachy-and-color-figma" class="image--center mx-auto" width="1366" height="768" loading="lazy"></p>
<p>Use Figma’s colour styles to define a consistent palette. Try using about 3 to 4 shades that complement each other. Keep it minimal and professional. For text, you can choose neutral fonts like Poppins, Inter, or Roboto, which look great on both dark and light themes.</p>
<h3 id="heading-3-create-components-for-reuse">3. Create Components for Reuse</h3>
<p>Figma allows you to turn recurring UI elements like buttons, cards, and tags into components. In the portfolio example here, notice how every project card, article preview, and pricing box follows the same layout. By creating a single card component and reusing it, you can easily maintain consistency and update everything in one go later.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1763135361258/41a8fdfe-d384-4039-8ab1-1a2499e58363.png" alt="components-reuse-figma" class="image--center mx-auto" width="1366" height="768" loading="lazy"></p>
<p>In this design, I will be using a blog featuring component multiple times, so instead of designing it again and again, I have made it once, and I am now using it multiple times.</p>
<h3 id="heading-4-add-your-content-and-images">4. Add Your Content and Images</h3>
<p>Now that your base design is ready, it’s time to make it personal. You can go ahead and replace placeholders with:</p>
<ul>
<li><p>Your best project screenshots (use mockups if needed),</p>
</li>
<li><p>Professional headshot or relevant visuals,</p>
</li>
<li><p>Real content, like your bio, skills, and service details.</p>
</li>
</ul>
<p>Make sure you keep the spacing clean. It ensures all sections stay neatly aligned, even when you adjust or add new elements later.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1763135295720/87dfa444-1e80-45b2-8e57-7f88971a4742.png" alt="add-your-content-figma" class="image--center mx-auto" width="1366" height="768" loading="lazy"></p>
<p>In this hero section, I have used my name and colour and font of my choice on the left, and you can see the <strong>Styles</strong> showing all the colours I have used across the project.</p>
<h3 id="heading-5-create-interactive-prototypes">5. Create Interactive Prototypes</h3>
<p>Before exporting your design, use Figma’s <strong>Prototype Mode</strong> to link different pages together – for example, make “Projects” in the top navigation scroll smoothly to your project section. This gives you a working demo to test how users will experience your portfolio before you even write a single line of code.</p>
<p>You can also share this prototype with friends or mentors for quick feedback.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1763135522546/1ef82103-13b6-4e9e-b102-b1c8cc20d03f.png" alt="create-interactive-prototype-figma" class="image--center mx-auto" width="1366" height="768" loading="lazy"></p>
<h3 id="heading-6-export-or-hand-off-for-development">6. Export or Hand Off for Development</h3>
<p>After testing your design in Prototype Mode when you’re satisfied, the final step is the <strong>handoff</strong>. Use the Export panel to download all required assets (icons, logos, images) in their correct formats. Then share the Figma file and go to <strong>Dev Mode</strong>, where you can inspect typography, spacing, sizes, and colour values. These exported assets and inspected specs are what developers use to create the live HTML/CSS code.</p>
<p>Note: The Dev Mode in Figma allows you to inspect CSS and export your stuff easily. Since I don’t have a paid Figma plan, I can’t show inspecting and exporting.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1763134948092/1f98417c-5120-48ac-b302-84d5234a7b95.png" alt="figma-handoff" class="image--center mx-auto" width="1366" height="768" loading="lazy"></p>
<p>Designing your portfolio in Figma gives you full freedom over layout, colour choices, and how you present your personality. Keep it simple, prioritise usability, and design with clarity. Once the layout is complete and tested, converting it into a functional site becomes straightforward.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1763138419092/978156ba-dbb3-4a6e-bcb8-3a0c7ff66e0d.png" alt="figma-auto-layout" class="image--center mx-auto" width="1366" height="768" loading="lazy"></p>
<p>You can also use auto layout just by right-clicking on the design section components.</p>
<p>Auto Layout allows designers to define rules for spacing, direction, padding, and alignment of elements. This ensures layouts like buttons, lists, and cards instantly adapt (scale/shrink) to content changes or different screen sizes without manual adjustments.</p>
<p>Once you’ve built and tested your Figma layout, converting it into code becomes the easy part.</p>
<h2 id="heading-tools-for-figma-to-code-generation">Tools for Figma to Code Generation</h2>
<p>By the time you’re done with the wireframe and colours, and your portfolio is live on Figma, it’s time to convert that Figma design into code. There are two ways to do so:</p>
<ul>
<li><p>Manual Method</p>
</li>
<li><p>AI Method</p>
</li>
</ul>
<h3 id="heading-how-to-manually-convert-figma-designs-to-code">How to Manually Convert Figma Designs to Code</h3>
<p>When you design a website or app in Figma, the next big step is turning that design into working code. Traditionally, developers have done this manually: inspecting each element, writing HTML, CSS, and then refining the layout in frameworks like React or Tailwind CSS.</p>
<p>It’s important to understand <strong>how this process is normally done by hand</strong>. This is the foundation that every frontend developer relies on — and it’s also what helps you evaluate and improve AI-generated code later.</p>
<p>When you design a website or app in Figma, the next step is to translate that visual layout into real HTML, CSS, and JavaScript. Developers usually start by examining each element in the design – its size, spacing, typography, colour, and layout rules – and manually rebuilding it in code.</p>
<h3 id="heading-exporting-visual-assets">Exporting Visual Assets</h3>
<p>Using Figma’s <em>Export</em> panel, you download only what needs to be recreated visually in code:</p>
<ul>
<li><p>icons</p>
</li>
<li><p>illustrations</p>
</li>
<li><p>logos</p>
</li>
<li><p>images or thumbnails</p>
</li>
</ul>
<p>Most structural elements (buttons, cards, sections, containers) are <strong>not</strong> exported – you’ll need to build them using HTML and CSS.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1763127453427/38bbbdef-270c-4157-8a2d-8fd8591426ea.png" alt="figma-export-panel" class="image--center mx-auto" width="1366" height="768" loading="lazy"></p>
<h3 id="heading-rebuilding-the-layout-with-html-and-css">Rebuilding the Layout with HTML and CSS</h3>
<p>You’ll recreate the page section by section:</p>
<ul>
<li><p>Setting up the HTML structure</p>
</li>
<li><p>Adding Flexbox or CSS Grid for layouts</p>
</li>
<li><p>Applying typography exactly as specified in Figma</p>
</li>
<li><p>Matching spacing using padding, margins, and gaps</p>
</li>
<li><p>Defining colours using the hex codes from the Figma Inspector</p>
</li>
</ul>
<p>If you’re using Tailwind CSS, this becomes a matter of applying the right utility classes, but the logic remains the same: <em>everything is recreated manually</em>.</p>
<p>Once you have your Figma layout ready, the real work happens inside your code editor (which for me is VS Code). Here’s how developers traditionally rebuild the UI one section at a time.</p>
<h3 id="heading-set-up-your-project-structure">Set Up Your Project Structure</h3>
<p>In VS Code, create your project structure. It’ll look something like this:</p>
<pre><code class="lang-plaintext">project/
 ├─ index.html
 ├─ styles.css
 ├─ /assets
 │    ├─ logo.svg
 │    ├─ hero-image.png
 │    └─ icons/
</code></pre>
<p>If you’re using React, this becomes the structure:</p>
<pre><code class="lang-bash">src/
 ├─ App.jsx
 ├─ components/
 ├─ index.css
 ├─ assets/
</code></pre>
<p>This structure mirrors what you saw in Figma: each major design section becomes a container or component.</p>
<h3 id="heading-write-the-html-structure-section-by-section">Write the HTML Structure Section-by-Section</h3>
<p>Now, you’ll look at the Figma frame and convert it to raw markup.</p>
<p>As an example, let’s look at the Hero Section.</p>
<p>Figma frame shows:</p>
<ul>
<li><p>a headline</p>
</li>
<li><p>subtext</p>
</li>
<li><p>a button</p>
</li>
<li><p>an illustration</p>
</li>
</ul>
<p>So your HTML becomes this:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">section</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hero"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hero-content"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Modern UI for Everyone<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Beautiful designs built for speed and accessibility.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"cta-btn"</span>&gt;</span>Get Started<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"assets/hero-image.png"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"Hero illustration"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"hero-img"</span> /&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">section</span>&gt;</span>
</code></pre>
<p>You're essentially mapping each Figma layer onto an HTML element.</p>
<h3 id="heading-build-layouts-using-flexbox-or-grid">Build Layouts Using Flexbox or Grid</h3>
<p>In Figma, layouts are visual. In HTML/CSS, you must <strong>translate</strong> the layout rules.</p>
<p>If Figma shows two columns (text + image), you’ll use Flexbox:</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.hero</span> {
  <span class="hljs-attribute">display</span>: flex;
  <span class="hljs-attribute">align-items</span>: center;
  <span class="hljs-attribute">justify-content</span>: space-between;
}
</code></pre>
<p>If Figma has a 3-card layout, you’ll use Grid:</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.features</span> {
  <span class="hljs-attribute">display</span>: grid;
  <span class="hljs-attribute">grid-template-columns</span>: <span class="hljs-built_in">repeat</span>(<span class="hljs-number">3</span>, <span class="hljs-number">1</span>fr);
  <span class="hljs-attribute">gap</span>: <span class="hljs-number">2rem</span>;
}
</code></pre>
<p>You literally reconstruct the layout <em>from scratch</em> by interpreting the Figma frame’s structure.</p>
<h3 id="heading-apply-typography-exactly-as-in-figma">Apply Typography Exactly as in Figma</h3>
<p>Next, you’ll go to Figma, select a text layer, and check the <strong>Inspector</strong>:</p>
<ul>
<li><p>Font family: Inter</p>
</li>
<li><p>Font size: 36px</p>
</li>
<li><p>Line height: 44px</p>
</li>
<li><p>Font weight: 700</p>
</li>
<li><p>Letter spacing: -1%</p>
</li>
</ul>
<p>Then recreate it like this:</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.hero</span> <span class="hljs-selector-tag">h1</span> {
  <span class="hljs-attribute">font-family</span>: <span class="hljs-string">'Inter'</span>, sans-serif;
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">36px</span>;
  <span class="hljs-attribute">line-height</span>: <span class="hljs-number">44px</span>;
  <span class="hljs-attribute">font-weight</span>: <span class="hljs-number">700</span>;
  <span class="hljs-attribute">letter-spacing</span>: -<span class="hljs-number">0.01em</span>;
}
</code></pre>
<p>This is why developers need to know their fundamentals: AI tools often miss these fine details.</p>
<h3 id="heading-recreate-spacing-with-padding-margins-gaps">Recreate Spacing With Padding, Margins, Gaps</h3>
<p>In Figma, spacing is visual. But in code, you must <em>calculate and apply</em> it.</p>
<p>Example Figma spacing:</p>
<ul>
<li><p>Padding inside a button: 16px vertical / 32px horizontal</p>
</li>
<li><p>Margin below a heading: 24px</p>
</li>
<li><p>Gap between elements: 32px</p>
</li>
</ul>
<p>So you write this code:</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.cta-btn</span> {
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">16px</span> <span class="hljs-number">32px</span>;
}

<span class="hljs-selector-class">.hero</span> <span class="hljs-selector-tag">h1</span> {
  <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">24px</span>;
}

<span class="hljs-selector-class">.hero-content</span> {
  <span class="hljs-attribute">display</span>: flex;
  <span class="hljs-attribute">flex-direction</span>: column;
  <span class="hljs-attribute">gap</span>: <span class="hljs-number">32px</span>;
}
</code></pre>
<p>Everything must match the design. And in this case, spacing is what makes UI look polished.</p>
<h3 id="heading-apply-colours-using-figma-hex-codes">Apply Colours Using Figma Hex Codes</h3>
<p>In Figma Inspector:</p>
<ul>
<li><p>Primary Blue → <code>#4A78FF</code></p>
</li>
<li><p>Background → <code>#F8FAFC</code></p>
</li>
<li><p>Text → <code>#1A1A1A</code></p>
</li>
</ul>
<p>In your CSS:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">body</span> {
  <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#F8FAFC</span>;
  <span class="hljs-attribute">color</span>: <span class="hljs-number">#1A1A1A</span>;
}

<span class="hljs-selector-class">.cta-btn</span> {
  <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#4A78FF</span>;
  <span class="hljs-attribute">color</span>: white;
}
</code></pre>
<p>You’ll need to manually copy each hex code into CSS, as this is where accuracy matters.</p>
<h3 id="heading-if-using-tailwind-apply-utility-classes-instead-of-writing-css">(If Using Tailwind) Apply Utility Classes Instead of Writing CSS</h3>
<p>Switching back and forth between your Figma design and a separate CSS file can slow down your whole workflow. Tailwind CSS solves this by letting you write styles right inside your HTML using small, reusable utility classes.</p>
<p>In this section, you’ll learn how to take the exact pixel values you see in the <strong>Figma Inspector</strong> and turn them into Tailwind utilities.</p>
<h4 id="heading-step-1-understand-tailwinds-spacing-scale">Step 1: Understand Tailwind’s Spacing Scale</h4>
<p>Tailwind doesn’t use raw pixel values. Instead, it uses a consistent spacing scale, usually based on a 4px grid.</p>
<p>Here’s the simple rule: Take the pixel value from Figma, divide by 4, and that number becomes your Tailwind utility.</p>
<p>Example:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Figma</td><td>Tailwind</td><td>Meaning</td></tr>
</thead>
<tbody>
<tr>
<td><code>margin-top: 32px</code></td><td><code>mt-8</code></td><td>32 ÷ 4 = 8 → so the class is <code>mt-8</code></td></tr>
</tbody>
</table>
</div><p>Prefixes you should know:</p>
<ul>
<li><p><code>m</code> = margin</p>
</li>
<li><p><code>p</code> = padding</p>
</li>
<li><p><code>t</code>, <code>b</code>, <code>l</code>, <code>r</code> = top, bottom, left, right</p>
</li>
<li><p><code>x</code> = horizontal (left + right)</p>
</li>
<li><p><code>y</code> = vertical (top + bottom)</p>
</li>
</ul>
<h4 id="heading-step-2-converting-complex-padding">Step 2: Converting Complex Padding</h4>
<p>If your Figma element uses different padding for X and Y, convert each side separately.</p>
<p>Example:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Figma</td><td>Tailwind</td><td>Meaning</td></tr>
</thead>
<tbody>
<tr>
<td><code>padding: 16px 32px</code></td><td><code>py-4 px-8</code></td><td>16 ÷ 4 = 4 → <code>py-4</code></td></tr>
<tr>
<td>32 ÷ 4 = 8 → <code>px-8</code></td><td></td></tr>
</tbody>
</table>
</div><h4 id="heading-step-3-converting-font-sizes">Step 3: Converting Font Sizes</h4>
<p>Tailwind doesn’t use pixel sizes for fonts. Instead, it uses semantic names – almost like T-shirt sizes.</p>
<p>Example:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Figma Font Size</td><td>Tailwind Class</td><td>Meaning</td></tr>
</thead>
<tbody>
<tr>
<td><code>36px</code></td><td><code>text-4xl</code></td><td>Tailwind’s <code>4xl</code> matches 36px in the default scale</td></tr>
</tbody>
</table>
</div><p>This encourages typography consistency, instead of manually choosing random font sizes.</p>
<h4 id="heading-why-this-method-is-so-fast">Why This Method Is So Fast</h4>
<p>Once you get used to it, the workflow becomes second nature:</p>
<pre><code class="lang-powershell">Figma value → divide by <span class="hljs-number">4</span> → apply Tailwind <span class="hljs-class"><span class="hljs-keyword">class</span></span>
</code></pre>
<p>No switching files. No naming CSS classes. No extra stylesheet bloat.</p>
<p>Just fast, direct, design-to-code translation.</p>
<h4 id="heading-try-it-yourself">Try It Yourself</h4>
<p>Open a Figma component (like a button or a card) and check its spacing, padding, and font size in the Inspector. Then convert everything using the simple rules above.</p>
<p>Before long, you’ll be turning Figma designs into clean Tailwind code in seconds.</p>
<p>You still translate Figma to code manually.</p>
<p>Alright, back to our workflow:</p>
<h3 id="heading-making-it-responsive">Making It Responsive</h3>
<p>You check how the design should behave on different screen sizes:</p>
<ul>
<li><p>stacking vs. side-by-side layouts</p>
</li>
<li><p>font scaling</p>
</li>
<li><p>spacing adjustments</p>
</li>
<li><p>collapsing navigation or rearranging grids</p>
</li>
</ul>
<p>This requires writing responsive styles and breakpoints, which AI tools can attempt but rarely perfect.</p>
<h3 id="heading-why-the-manual-way-is-important">Why the Manual Way Is Important</h3>
<p>Even though it takes more time, this approach teaches fundamentals that AI tools simply can’t replace:</p>
<ul>
<li><p>How spacing systems work</p>
</li>
<li><p>How components behave in real browsers</p>
</li>
<li><p>How layout changes across devices</p>
</li>
<li><p>How to optimise for performance and accessibility</p>
</li>
</ul>
<p>These skills allow you to <strong>inspect code intelligently</strong> and improve it wherever needed, which is <em>almost always necessary</em>, no matter which tool you use.</p>
<h3 id="heading-how-to-use-ai-tools-to-convert-figma-designs-to-code-optional">How to Use AI Tools to Convert Figma Designs to Code (Optional)</h3>
<p>To speed up this process, you can now use AI-powered and automated Figma-to-code tools. These tools analyse the Figma file and instantly generate code that you can integrate into your tech stack.</p>
<p>There are multiple tools available in the market, like V0, Builder.io, and Kombai.</p>
<ul>
<li><p><a target="_blank" href="https://v0.dev">V0</a> is A Vercel project focused on fast UI generation, integrated with Next.js workflows.</p>
</li>
<li><p><a target="_blank" href="https://Builder.io">Builder.io</a> is visual CMS with Figma integration and a visual editor that can export components for web apps.</p>
</li>
<li><p><a target="_blank" href="https://kombai.com">Kombai</a> is an IDE extension that converts selected Figma frames into React/NextJS/React Native code and offers repo-aware features.</p>
</li>
</ul>
<h4 id="heading-building-live">Building Live</h4>
<p>For demonstration purposes, I’ll be using Kombai, a VS Code extension. And since most of us developers spend a lot of time inside VS Code, it’s the perfect place to test it out.</p>
<p>To install it in VS Code, simply open the Extensions Marketplace, search for 'kombai', click 'Install' and open the extension.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1761314891808/1e28092b-9011-476d-869d-08ce6b675766.png" alt="Kombai agent vs code install " class="image--center mx-auto" width="1366" height="768" loading="lazy"></p>
<p>Now, at the agent panel, click on the “Let’s get started” button and sign up or log in with your credentials.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1762085091479/abb9f832-b66a-42f5-990c-0a070dc33fd9.png" alt="Kombai agent vs code " class="image--center mx-auto" width="1366" height="768" loading="lazy"></p>
<p>Now it’s time to test the agent for real work. To do so, I’ll be using the Figma file attached to build this portfolio.</p>
<p>A few things to keep in mind as you get going:</p>
<ul>
<li><p>You’ll need to enable WebGL if Figma is not working on your browser.</p>
</li>
<li><p>You need to know how to copy the Figma file link and how to export the design from Figma.</p>
</li>
</ul>
<p>To copy the Figma design file link, open your Figma design file and simply select your desired design, select copy/paste, and then select copy link to selection. It will copy the complete design file URL.</p>
<p>You can also copy the link of any Figma component and follow the same approach to get the desired outcome.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1762935992593/08f6443d-4a62-42fc-8294-0c8f8000bef0.png" alt="figma-design-portfolio" class="image--center mx-auto" width="1366" height="768" loading="lazy"></p>
<p>Open the agent extension in VSCode and select the Figma (icon) agent at the bottom of the agent toolbar. It will open a new pop-up. In it, paste the link you copied to the design file (check the screenshot below). Then you can prompt the agent with what you want it to do with this Figma file.</p>
<p>In my case, I wanted to replicate the same design, so I gave this prompt along with my Figma design link:</p>
<blockquote>
<p>“You are an expert UI/UX designer and your task is to build and replicate the entire Figma design in the HTML/CSS/JS code from the attached URL.“</p>
</blockquote>
<p>After confirming this, the agent will start working to replicate the same design as you’ve seen in the Figma file.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1761456000444/a34b5abe-cb75-4634-b090-a53d1f4df026.png" alt="figma-to-code-kombai-agent" class="image--center mx-auto" width="1366" height="768" loading="lazy"></p>
<p>And here are the results:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1763136179145/eb51a1ca-7d63-4a16-ba80-80854d715066.png" alt="figma-to-code-kombai-output" class="image--center mx-auto" width="1366" height="3226" loading="lazy"></p>
<p>Now you have the full picture of both approaches and when to use each one.</p>
<p>Here is the live Project link - <a target="_blank" href="https://fcc-demo.netlify.app/">FCC FIGMA TO CODE</a></p>
<p>Here is the GitHub link for the project code - <a target="_blank" href="https://github.com/prankurpandeyy/fcc-demo-portfolio">Github Code</a></p>
<h3 id="heading-challenges-in-ai-generated-code-and-why-developer-oversight-is-essential">Challenges in AI-Generated Code (and Why Developer Oversight Is Essential)</h3>
<p>AI tools can speed up the design-to-code process, but the output is rarely production-ready. Most tools struggle with layout precision, accessibility, and responsiveness, especially in real-world designs. You should expect to review and improve various parts of the generated code, such as:</p>
<ul>
<li><p><strong>Spacing and alignment issues:</strong> AI may misinterpret padding, margins, or grid spacing, so layouts often need manual adjustment.</p>
</li>
<li><p><strong>Responsive breakpoints:</strong> Most tools generate layouts for a single screen size. You still need to add tablet/mobile breakpoints and test them across devices.</p>
</li>
<li><p><strong>Semantic HTML:</strong> AI tends to use too many <code>&lt;div&gt;</code> elements instead of meaningful tags like <code>&lt;header&gt;</code>, <code>&lt;nav&gt;</code>, <code>&lt;section&gt;</code>, or <code>&lt;button&gt;</code>.</p>
</li>
<li><p><strong>Accessibility gaps:</strong> Missing alt text, improper labels, weak colour contrast choices, and a lack of ARIA(HTML Tags) attributes are common issues.</p>
</li>
<li><p><strong>Utility class overload (in Tailwind-based code):</strong> AI outputs long, repetitive class lists that need cleanup for maintainability.</p>
</li>
<li><p><strong>Inconsistent component structure:</strong> AI may generate components that aren’t reusable or follow naming conventions, so refactoring is often required.</p>
</li>
<li><p><strong>Tokens and theming:</strong> Colours, font sizes, and spacing may not map to design tokens unless manually corrected.</p>
</li>
</ul>
<p>Because of these limitations, AI-generated code should be treated as a <strong>starting point</strong>, not a final product. You’ll still need to validate the logic, refine the structure, and ensure the final result meets real-world quality standards. AI reduces repetitive work, but you, as the developer, need to ensure the code’s correctness, accessibility, and long-term maintainability.</p>
<h3 id="heading-what-i-prefer">What I Prefer</h3>
<p>The manual method gives you complete control and teaches you the fundamentals, which are essential for understanding how layouts, spacing, and components actually translate into real code.</p>
<p>When you write the HTML, CSS, and component structure yourself, you build a deeper understanding of how layouts, spacing, responsiveness, typography, and accessibility truly work under the hood. These fundamentals are what make you a strong frontend developer, and no automated tool can replace that learning.</p>
<p>AI-assisted design-to-code tools can help with speed – especially in the early stages when you just want a quick starting point. They remove some of the repetitive setup work, but the output almost always needs refinement.</p>
<p>In real projects, the most dependable workflow is a combination of both approaches: Use automation only for the boilerplate, then rely on your own frontend knowledge to clean up, reorganise, and fine-tune the interface so it meets real-world standards.</p>
<p><strong>Personally, I still prefer coding my designs manually because it keeps me connected to the craft and helps me build muscle memory.</strong> It’s the only way to fully understand how the design translates into a live, responsive interface and how each decision affects performance and user experience.</p>
<p>AI tools don’t replace frontend developers. They simply support them. They handle repetitive tasks so you can focus on the skills that truly matter: clarity of structure, accessibility, responsive behaviour, and crafting an experience that feels polished and intentional.</p>
<h2 id="heading-copywriting-for-your-portfolio">Copywriting for Your Portfolio</h2>
<p>Now that your portfolio is designed and coded, let’s turn our attention back to what it actually says.</p>
<p>Copywriting is the art of using words to convince people to take a specific action, like buying a product, signing up for a service, or visiting a website. It’s a mix of creativity and marketing, where words are used to sell ideas or products smartly and emotionally.</p>
<p>A copywriter writes many types of content, from sales pages, website text, and social media posts to ad scripts and emails. The goal is simple: to make people take action.</p>
<p>So what makes copywriting effective?</p>
<ul>
<li><p><strong>Knowing your audience:</strong> A good copywriter understands what people need, what problems they face, and what motivates them.</p>
</li>
<li><p><strong>Using persuasive words:</strong> Words that spark emotions and make readers want to act.</p>
</li>
<li><p><strong>Clarity and impact:</strong> Keeping the message short, clear, and easy to understand.</p>
</li>
<li><p><strong>Consistent brand voice:</strong> Writing in a tone that matches the brand’s personality — whether it’s fun, professional, or inspiring.</p>
</li>
</ul>
<h3 id="heading-how-to-use-copywriting-in-your-portfolio">How to Use Copywriting in Your Portfolio</h3>
<p>Your portfolio isn’t just about showing your work – it’s about telling your story in a way that connects with people. That’s where copywriting comes in. Good copy turns your portfolio from a plain showcase into something that feels personal, clear, and convincing.</p>
<p>Here’s how you can use copywriting effectively while building your portfolio:</p>
<h3 id="heading-1-start-with-a-strong-headline">1. Start With a Strong Headline</h3>
<p>The first line people see should instantly tell them <em>who you are</em> and <em>what you do</em>. For example:</p>
<blockquote>
<p>“I build modern, responsive web apps that turn ideas into digital reality.”</p>
</blockquote>
<p>Your headline is like your elevator pitch: short, powerful, and clear.</p>
<h3 id="heading-2-tell-your-story">2. Tell Your Story</h3>
<p>In the About Me section, don’t just list your skills. You should also tell visitors about your journey. Write about how you got started programming, what you’ve learned along the way, and what drives you. Keep it conversational and real, like you’re talking to a friend.</p>
<blockquote>
<p>“I started coding six years ago with simple HTML pages. Today, I design full-stack apps and help startups bring their ideas to life.”</p>
</blockquote>
<h3 id="heading-3-write-benefit-focused-descriptions">3. Write Benefit-Focused Descriptions</h3>
<p>When you show your projects, don’t just describe <em>what</em> you built. Explain <em>why</em> it matters.</p>
<blockquote>
<p>Instead of: “I built a task manager app.”<br>Try: “A simple, clutter-free task manager that helps users stay productive without distractions.”</p>
</blockquote>
<p>This small change turns your project into a <em>problem-solving story</em>, not just a tech demo.</p>
<h3 id="heading-4-add-a-call-to-action-cta">4. Add a Call-to-Action (CTA)</h3>
<p>Every portfolio should guide visitors toward an action, like contacting you, checking your GitHub, or reading your blog.</p>
<p>Here are some examples:</p>
<blockquote>
<p>“Want to collaborate? Let’s build something amazing together.”<br>“Looking for a developer who writes clean and efficient code? Reach out!”</p>
</blockquote>
<p>A clear CTA shows confidence and gives people a direction.</p>
<h3 id="heading-5-keep-it-simple-and-authentic">5. Keep It Simple and Authentic</h3>
<p>Avoid fancy words or buzzwords. Write like a human, not a brochure. Use simple, clear sentences that sound like your real voice.</p>
<p>Good copywriting is not about being clever – it’s about being <em>clear and honest</em>.</p>
<h3 id="heading-6-maintain-a-consistent-tone">6. Maintain a Consistent Tone</h3>
<p>Whether your style is formal or friendly, keep it the same across all pages – home, about, projects, and contact. A consistent tone helps build your personal brand and makes your portfolio feel professional.</p>
<p>Copywriting is the invisible thread that ties your portfolio together. It helps people not just <em>see</em> your work, but <em>feel</em> your story.</p>
<h2 id="heading-testing-benchmarks-for-a-portfolio-website">Testing Benchmarks for a Portfolio Website</h2>
<p>Before your portfolio goes live, it’s important to test it so that you know it looks and works as it’s supposed to. A fast, responsive, and accessible site leaves a strong first impression, and benchmarks help you measure whether it’s up to your standards. And a well-tested site loads faster, ranks better, and gives users (and recruiters) a seamless experience.</p>
<p>Below are the key benchmarks you should always check, along with why they matter.</p>
<h3 id="heading-1-page-load-time">1. Page Load Time</h3>
<p>This is the time it takes for your page to fully load after someone visits it. A fast-loading site feels smooth and professional, while a slow one instantly turns people away.</p>
<p>This matters because most visitors leave if a site takes more than 3 seconds to load. Tools like <a target="_blank" href="https://gtmetrix.com">GTmetrix</a> or Pingdom can help you track and improve page load speed by optimising images and reducing unnecessary scripts.</p>
<h3 id="heading-2-core-web-vitals-lcp-inp-cls">2. Core Web Vitals (LCP, INP, CLS)</h3>
<p>Google uses <strong>Core Web Vitals</strong> to measure real-world user experience.</p>
<ul>
<li><p><strong>LCP (Largest Contentful Paint):</strong> How quickly your main content becomes visible.</p>
</li>
<li><p><strong>INP (Interaction to Next Paint):</strong> How fast your site responds when users interact.</p>
</li>
<li><p><strong>CLS (Cumulative Layout Shift):</strong> How stable your layout is while loading.</p>
</li>
</ul>
<p>These metrics directly affect how users perceive your site and also impact SEO ranking. You can test them on <a target="_blank" href="https://pagespeed.web.dev">PageSpeed Insights.</a></p>
<h3 id="heading-3-mobile-friendliness">3. Mobile Friendliness</h3>
<p>Most people will view your portfolio on their phones, so it needs to look and work perfectly on smaller screens.</p>
<p>A mobile-optimised site not only improves user experience but also ranks better on Google’s mobile search results. Use responsive layouts and flexible grids to ensure smooth viewing on all devices.</p>
<h3 id="heading-4-accessibility-compliance-wcag">4. Accessibility Compliance (WCAG)</h3>
<p>Accessibility means making your portfolio usable for everyone, including people with disabilities.</p>
<p>This is important because following WCAG standards (like proper colour contrast, keyboard navigation, and alt text for images) shows professionalism and inclusivity. Tools like Lighthouse or WAVE can help you check how your portfolio ranks for key accessibility metrics.</p>
<h3 id="heading-5-seo-best-practices">5. SEO Best Practices</h3>
<p>SEO isn’t just for businesses. It can also help your personal site appear when someone searches your name or skills.</p>
<p>If you add proper meta tags, structured headings (H1, H2, H3), and descriptive URLs, these features can help recruiters or clients find you more easily. A well-optimised portfolio often performs better on job searches and tech blogs.</p>
<h3 id="heading-6-responsiveness-interaction-delay">6. Responsiveness (Interaction Delay)</h3>
<p>Responsiveness measures how quickly your website reacts when users click or scroll. And a laggy interface feels unprofessional and hurts user engagement. By minimising heavy scripts and optimising animations, you ensure smooth, immediate feedback for every action.</p>
<h3 id="heading-7-security-checks-https">7. Security Checks (HTTPS)</h3>
<p>Even a simple portfolio needs <strong>HTTPS</strong>. It builds trust and protects both you and your visitors from data breaches. Browsers like Chrome now flag non-secure sites, so enabling SSL is a must.</p>
<h3 id="heading-8-resource-size-html-css-js-images">8. Resource Size (HTML, CSS, JS, Images)</h3>
<p>Heavy resources can slow everything down. Compressing files, minifying CSS/JS, and using next-gen image formats (like WebP) can dramatically improve speed and performance.</p>
<h3 id="heading-9-browser-and-device-compatibilityhttpspagespeedwebdev">9. Browser and Device Compatibilit<a target="_blank" href="https://pagespeed.web.dev">y</a></h3>
<p>Not everyone uses Chrome on a laptop. So make sure you test your portfolio across major browsers (Chrome, Firefox, Safari, Edge) and devices (desktop, tablet, mobile). Simulated testing tools like DebugBear or Basemark Web help catch layout issues early.</p>
<h3 id="heading-10-real-user-monitoring-rum">10. Real User Monitoring (RUM)</h3>
<p>Instead of just testing in a lab, RUM captures how real visitors experience your site. This helps you understand performance in real-world scenarios – on different devices, networks, and locations – and adjust your design based on real data.</p>
<h2 id="heading-hosting-your-portfolio">Hosting Your Portfolio</h2>
<p>Now it’s time to push your changes to GitHub and deploy them on a hosting provider of your choice. Hosting services play a crucial role in showcasing your work. Depending on the type of projects you build, here are some of the best free hosting options that I have used so far for my personal and professional projects.</p>
<ul>
<li><p><strong>Vercel</strong> – Best for Next.js/React projects, offering seamless deployment inside the Vercel ecosystem.</p>
</li>
<li><p><strong>GitHub Pages</strong> – Great for hosting static websites and personal portfolios.</p>
</li>
<li><p><strong>Netlify</strong> – Ideal for frontend-heavy projects with easy deployment and CI/CD integration.</p>
</li>
</ul>
<p>Your portfolio is ready, and you can share it anywhere with just a link.</p>
<h2 id="heading-how-to-use-your-portfolio-effectively">How to Use Your Portfolio Effectively</h2>
<p>Now that your portfolio is ready, it’s time to use it the right way. Whether you’re applying for a job, pitching to a freelance client, or simply networking with like-minded people, your portfolio is your strongest asset.</p>
<p>Think of it as your digital introduction. It not only shows what you’ve built but also how you think and work. The key is to use it smartly in the right context.</p>
<p>Let’s say you come across a job post or want to reach out directly to a recruiter or a company founder. Instead of just sending a plain résumé, you can make your message stand out by attaching your portfolio link. Here’s an example of how you can do it:</p>
<p>Example email/direct message:</p>
<blockquote>
<p><strong><em>Hi [Hiring Manager/CEO Name],</em></strong></p>
<p><strong><em>I’m Prankur, a Full Stack Developer from India with over 6 years of experience building mobile and web applications.</em></strong></p>
<p><strong><em>I came across the opening for [Job Title/Role] at your company and believe my skills align perfectly with what you’re looking for.</em></strong></p>
<p><strong><em>You can explore my work here: [Portfolio URL]</em></strong></p>
<p><strong><em>I’m available to start immediately and excited about the opportunity to contribute to your team and codebase.</em></strong></p>
<p><strong><em>Best regards,</em></strong></p>
<p><strong><em>Prankur Pandey</em></strong></p>
</blockquote>
<p>This small but professional touch – including your portfolio link in every email, proposal, or LinkedIn message – increases your chances of being noticed. A well-presented portfolio speaks louder than a résumé, and it helps recruiters or clients quickly understand your skills, design sense, and coding depth.</p>
<p>So, don’t just build your portfolio. <strong>Use it actively</strong>. Share it on job boards, LinkedIn posts, your GitHub bio, or even in casual conversations with potential collaborators. Every share is a new opportunity waiting to unfold.</p>
<h2 id="heading-qampa">Q&amp;A</h2>
<p><strong>1. Is building a portfolio really important?</strong><br>Absolutely. Instead of sending out a dozen links to your GitHub, Behance, and LinkedIn, it’s much more effective to combine all your work into one clean, accessible portfolio site. It makes you look organised, professional, and easy to evaluate.</p>
<p><strong>2. Is it worth buying a domain name?</strong><br>Yes, it is, if you’re serious about your career. Having your own domain (like <a target="_blank" href="http://yourname.dev"><em>yourname.dev</em></a> or <a target="_blank" href="http://yourname.com"><em>yourname.com</em></a>) gives a personal and professional touch,</p>
<p>But if you’re still learning or just experimenting, it’s fine to start with a free domain. Once you have solid projects to show, investing in your own domain is totally worth it.</p>
<p><strong>3. Can I use AI or no-code tools to build my portfolio?</strong><br>You can, but if you’re a developer, you should try coding it yourself first. It’s a great way to showcase your creativity and technical control over design and logic. Here’s a <a target="_blank" href="https://www.freecodecamp.org/news/build-a-simple-portfolio-website-with-html-and-css/">simple and straightforward guide</a> to help you get started with that.</p>
<p>Once your design is ready, you can always use AI or no-code tools to speed up the process or automate parts of it. Think of AI as a helper, not a replacement.</p>
<p><strong>4. How can I get AI tools for testing?</strong><br>It’s easy: visit the official websites of the tools you’re interested in and sign up. Most AI tools offer free trials or limited credits that you can use to explore and test their features based on your workflow and needs.</p>
<p><strong>5. I am just starting. What should I use: AI tools or the Manual Method?</strong><br>I strongly recommend using the Manual Method as it will help you to understand your craft well, and you will also build muscle memory about a technology and how it works.</p>
<p><strong>6. Which Platform should I use for hosting?</strong><br>Most of the hosting providers offer a free plan, so you can start with that. Then, when you feel the need to expand your portfolio, switch to a paid plan.</p>
<h2 id="heading-final-notes">Final Notes</h2>
<p>Building a strong portfolio requires time, effort, and attention to detail. But it’s one of the smartest investments you can make in your tech career.</p>
<p>Tools and templates can help speed up the process, but your creativity, skills, and storytelling are what truly make a portfolio stand out. A well-crafted portfolio not only shows what you can build, it reveals how you think and why your work matters.</p>
<p>While you can use design tools, frameworks, or even AI assistance to save time, make sure you understand the basics of design, structure, and usability. The goal isn’t to create something flashy; it’s to produce something clear, professional, and authentic.</p>
<p>Your portfolio is your digital identity, so treat it like your personal brand. Keep refining it as your skills grow and let it evolve alongside your career.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>A portfolio isn’t just a website. It’s your story told through your work. It helps employers, clients, and collaborators understand what you do best and why you stand out.</p>
<p>In this article, I’ve shared everything that helped me build and refine my own portfolio, from understanding design structure and copywriting to testing and optimisation benchmarks. My goal is to help you create a portfolio that not only looks great but also opens real opportunities for you.</p>
<p>In my next tutorial, I’ll explore something new for sure.</p>
<p><strong>Design + Creativity+Development + Execution = The Ultimate Developer Stack 🔥</strong></p>
<p>Keep learning, keep building, and most importantly — keep sharing your work.</p>
<p>If you found this article useful, feel free to let me know. I’m always open to learning, collaboration, and new opportunities.</p>
<p>Now it's your turn: what are you building next? Let me know by sending me a DM!</p>
<ul>
<li><p>Follow me on <strong>𝕏</strong>: <a target="_blank" href="https://x.com/prankurpandeyy">Prankur's</a> <strong>𝕏</strong></p>
</li>
<li><p>Connect with me on LinkedIn: <a target="_blank" href="https://linkedin.com/in/prankurpandeyy">Prankur's LinkedIn</a></p>
</li>
<li><p>Follow me on GitHub: <a target="_blank" href="https://github.com/prankurpandeyy">Prankur’s GitHub</a></p>
</li>
<li><p>View my Portfolio: <a target="_blank" href="https://prankurpandeyy.is-a.dev/">Prankur's Portfolio</a></p>
</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Learn Key System Design Principles Behind High-Traffic Platforms Like Gaming and Job Discovery ]]>
                </title>
                <description>
                    <![CDATA[ Over the last three months, life has had me juggling a lot – managing my marriage, taking care of family health issues, and overseeing new construction work at home. Somehow, I got through it all. But looking back, I realised something important: I c... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-key-system-design-principles-behind-high-traffic-platforms-like-gaming-and-job-discovery/</link>
                <guid isPermaLink="false">68a5f915c3b51ce78e8f92b3</guid>
                
                    <category>
                        <![CDATA[ System Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ System Architecture ]]>
                    </category>
                
                    <category>
                        <![CDATA[ full stack ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Prankur Pandey ]]>
                </dc:creator>
                <pubDate>Wed, 20 Aug 2025 16:34:29 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1755707525928/f4a02c14-fe62-4d6f-9afc-d887d45a98d4.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Over the last three months, life has had me juggling a lot – managing my marriage, taking care of family health issues, and overseeing new construction work at home. Somehow, I got through it all. But looking back, I realised something important: I could’ve handled it much better if I had a <em>system</em> in place.</p>
<p>For me, a <strong>system</strong> means a set of rules, processes, and triggers that guide the entire workflow. This helps you conserve energy and not have to figure things out in the moment. It keeps things productive, efficient, and consistent.</p>
<p>Now that the chaos has settled, I’ve been thinking a lot about systems – not just in life, but in tech. I wish I had applied the same principles of <strong>system design</strong> earlier.</p>
<p>In this article, we’re going to explore real-world system design examples from domains like gaming and job platforms. These industries don’t just scale massively – they also demand high availability, low latency, and seamless customer experiences. Understanding how they’re built is a powerful way to level up your thinking as a developer or architect.</p>
<h3 id="heading-what-well-cover">What We’ll Cover</h3>
<ol>
<li><p><a class="post-section-overview" href="#heading-introduction-what-is-system-design-and-why-scale-matters">Introduction: What is System Design and Why Scale Matters</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-approaches-to-system-design">Approaches to System Design</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-1-bottom-up-approach">1. Bottom-Up Approach</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-2-top-down-approach">2. Top-Down Approach</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-3-hybrid-design">3. Hybrid Design</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-important-concepts-in-system-design">Important Concepts in System Design</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-full-stack-web-application-components">Full Stack Web Application Components</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-computers-talk-to-each-other-the-internet">How Computers Talk to Each Other (The Internet)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-problem-of-growth">The Problem of Growth</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-speeding-up-your-website-with-caching-and-cdns">Speeding Up Your Website with Caching and CDNs</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-building-your-application-monolith-vs-microservices">Building Your Application: Monolith vs. Microservices</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-apis">The APIs</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-handling-real-time-data">Handling Real-Time Data</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-databases">Databases</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-understanding-the-cap-theorem">Understanding the CAP Theorem</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-rate-limiting-and-monitoring">Rate Limiting and Monitoring</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-case-studies-scaling-in-the-real-world">Case Studies: Scaling in the Real World</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-case-study-1-scaling-a-job-search-application">Case Study 1: Scaling a Job Search Application</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-case-study-2-scaling-an-online-gaming-application">Case Study 2: Scaling an Online Gaming Application</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-qampa">Q&amp;A</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-final-notes">Final Notes</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ol>
<h2 id="heading-introduction-what-is-system-design-and-why-scale-matters">Introduction: What is System Design and Why Scale Matters</h2>
<p><strong>System design</strong> is the process of defining the architecture, modules, interfaces, and data of a system.</p>
<p>In other words, system design means explaining the different parts of a system, like its structure, building blocks (modules), and components.</p>
<p>It’s a process used to define, develop, and design a system in a way that meets the specific needs of a business or organisation.</p>
<p>The main goal of system design is to give enough information and details about the system, and to properly implement its parts using models and views. Let’s now talk about the different parts of a system.</p>
<h3 id="heading-elements-of-a-system">Elements of a System:</h3>
<ul>
<li><p><strong>Architecture:</strong> This is a basic structure or model that shows how the system works, looks, and behaves.<br>  We often use <strong>flowcharts</strong> to explain and represent this architecture.</p>
</li>
<li><p><strong>Modules:</strong> These are smaller parts or sections of the system. Each module handles a specific task. When all modules are combined, they make the complete system.</p>
</li>
<li><p><strong>Components:</strong> These provide a specific function or a group of related functions. Components are usually made from one or more modules.</p>
</li>
<li><p><strong>Interfaces:</strong> This is the connection point where different parts (components) of the system exchange information with each other.</p>
</li>
<li><p><strong>Data:</strong> This refers to managing information and how it flows through the system.</p>
</li>
</ul>
<h3 id="heading-why-system-design-matters">Why System Design Matters</h3>
<p>System design is important for a number of practical reasons. First, it can help companies and teams solve complex business problems and make sure they thoroughly analyse all requirements before building. It also reduces the chance that errors will be introduced into processes while making design phases more efficient and structured. Finally, it helps you efficiently gather and present your data in a useful format and improves the overall quality of the system.</p>
<h2 id="heading-approaches-to-system-design">Approaches to System Design</h2>
<p>There are several methods you can use to approach system design. The main ones are:</p>
<h3 id="heading-1-bottom-up-approach">1. Bottom-Up Approach</h3>
<p>In this method, the design starts from the lowest-level components or subsystems. These small parts are gradually combined to form higher-level components. This process continues until the entire system is built as one complete structure.</p>
<p>The more abstraction we use, the higher the level of the design becomes.</p>
<p><strong>Advantages:</strong></p>
<ul>
<li><p>Components can be reused in other systems.</p>
</li>
<li><p>It’s easier to identify risks early.</p>
</li>
<li><p>It helps in hiding low-level technical details and can be combined with the top-down approach.</p>
</li>
</ul>
<p><strong>Disadvantages:</strong></p>
<ul>
<li><p>It’s not very focused on the overall structure of the problem.</p>
</li>
<li><p>Building high-quality bottom-up solutions is hard and time-consuming.</p>
</li>
</ul>
<h3 id="heading-2-top-down-approach">2. Top-Down Approach</h3>
<p>Here, the design starts from the entire system, and you break it down into smaller subsystems and components as you go. Each of these subsystems then gets broken down further, step by step, creating a hierarchical structure.</p>
<p>In simple terms, you start with the big picture and keep dividing it until you reach the smallest parts of the system.</p>
<p>To sum up, design starts with defining the whole system, then continues by defining its subsystems and components. When all definitions are ready and fit together, the system is complete.</p>
<p><strong>Advantages</strong>:</p>
<ul>
<li><p>The focus is on understanding the requirements first, which leads to a responsive and purpose-driven design.</p>
</li>
<li><p>It’s easier to handle errors in interfaces between components.</p>
</li>
</ul>
<p><strong>Disadvantages</strong>:</p>
<ul>
<li><p>Components can’t be reused easily in other systems.</p>
</li>
<li><p>The resulting architecture is often less flexible or not very clean.</p>
</li>
</ul>
<h3 id="heading-3-hybrid-design">3. Hybrid Design</h3>
<p>The hybrid design approach is a mix of <strong>top-down</strong> and <strong>bottom-up</strong> methods. Instead of committing to just one way, it takes the strengths of both. You start by looking at the overall system (like in top-down) so that you don’t lose sight of the big picture. At the same time, you also focus on building solid, reusable modules or components (like in bottom-up).</p>
<p>In simple terms, you first plan the big picture, then create smaller components that can work independently, and finally combine everything into a cohesive system.</p>
<p>For instance, in our sports team site, we’d use top-down to define the whole fan journey (homepage → match details → live scores). But bottom-up, we’d build modular components like authentication or stats tracking, which can later be reused in new features like ticket booking or merchandise sales.</p>
<p><strong>Advantages:</strong></p>
<ul>
<li><p>You get the clarity of a top-down plan while still building reusable modules.</p>
</li>
<li><p>It strikes a balance between high-level design and detailed implementation.</p>
</li>
<li><p>Risks are easier to manage since you’re considering both structure and components.</p>
</li>
</ul>
<p><strong>Disadvantages:</strong></p>
<ul>
<li><p>It can be complex to manage since you’re juggling two approaches.</p>
</li>
<li><p>Requires more coordination between teams working on different levels.</p>
</li>
<li><p>It might take more time compared to using a single approach.</p>
</li>
</ul>
<h2 id="heading-important-concepts-in-system-design">Important Concepts in System Design</h2>
<p>Before exploring core components, I want you to first understand two key concepts:</p>
<ul>
<li><p>Full stack web application components</p>
</li>
<li><p>How computers talk to each other (via the internet)</p>
</li>
</ul>
<h3 id="heading-full-stack-web-application-components">Full Stack Web Application Components</h3>
<p>A full-stack web application is a software application that combines both the frontend (what users see and interact with) and the backend (the server, database, and logic that power the app) into one complete system.</p>
<p>Generally, simple websites don’t require much system design – and in some cases, no system design at all. But when it comes to viral applications or platforms offering complex services, system design becomes essential. Most modern applications are full-stack applications, meaning they involve multiple interconnected layers working together.</p>
<p>Here’s a simplified overview of a typical full-stack application:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1755603745131/1114a65f-ea7c-4e3f-aca6-4821c8ca683a.png" alt="full stack web overview" width="600" height="400" loading="lazy"></p>
<p>Before diving deep into each of these components, let me first give you a quick, high-level overview of what they are and how they fit into the bigger picture (starting from the bottom of the image above).</p>
<ul>
<li><p><strong>Frontend</strong> – The user interface where people interact with your application.</p>
</li>
<li><p><strong>Backend</strong> – The logic and brain of the application that processes requests.</p>
</li>
<li><p><strong>APIs</strong> – The bridge that allows communication between frontend, backend, and external services.</p>
</li>
<li><p><strong>Database</strong> – The storage system where all your structured information lives.</p>
</li>
<li><p><strong>Server</strong> – The infrastructure that hosts, runs, and delivers your application.</p>
</li>
</ul>
<p>Now, we need to understand how computers talk to each other.</p>
<h3 id="heading-how-computers-talk-to-each-other-the-internet">How Computers Talk to Each Other (The Internet)</h3>
<p>When you type a website's URL into the browser – and this site could be a simple portfolio site or a full stack app – how does your computer know where to send the request? It uses the <a target="_blank" href="https://www.freecodecamp.org/news/what-is-dns/"><strong>Domain Name System</strong></a> <strong>(DNS)</strong>. The DNS is like a phonebook for the internet – it translates a human-readable website name, like "example.com," into a unique numeric IP address that computers can understand.</p>
<p>Once your computer has the IP address, it uses <strong>communication protocols</strong> to send and receive data. One of the most important protocols is <a target="_blank" href="https://www.freecodecamp.org/news/tcp-vs-udp/"><strong>TCP</strong></a>. It breaks data into small, numbered packets. If a packet gets lost or arrives out of order, TCP ensures it's resent and reassembled correctly, making it a very reliable way to send data.</p>
<p>On top of TCP, we use higher-level protocols like <a target="_blank" href="https://www.freecodecamp.org/news/what-is-http/"><strong>HTTP</strong></a>. This is an application-level protocol that's easier for developers to use. It's the language your browser speaks to the server.</p>
<p><strong>HTTPS</strong> is the same, but it adds an extra layer of encryption for security.</p>
<p>Now that we understand the basics of the Internet, remember that it serves billions of people worldwide.</p>
<p>Let’s break this down with a real-life example. Imagine you own a restaurant with a seating capacity of 50 people. One day, 10 extra guests arrive – and with a bit of adjustment, you still manage. But suddenly, a thousand more people show up at your door. What would you do then? It’s not just about adding more chairs and tables anymore – you’ll need extra food supplies, more staff, and a bigger setup to handle such massive traffic.</p>
<p>This simple example reflects the real challenge of growth and scalability. And that’s exactly what I’ll be diving into in the next chapter of this tutorial.</p>
<h3 id="heading-the-problem-of-growth">The Problem of Growth</h3>
<p>Imagine you've built a simple website for a local sports team. Initially, it's just you and a few friends using it, so a single server is sufficient. This server holds all the website's logic and connects to a single database where player stats are stored.</p>
<p>As the team becomes more popular, though, more people visit your site, and it suddenly becomes slow. This is a <strong>scaling issue</strong>. Your system can't handle all the new traffic.</p>
<h4 id="heading-scaling-your-system-two-main-ways">Scaling Your System: Two Main Ways</h4>
<p>There are two ways to solve this. The first is <strong>vertical scaling</strong>. This is like giving your one server a bigger engine and more memory. You'd upgrade the CPU (the brain) or add more RAM (temporary memory). You could also use a faster disk storage like an SSD.</p>
<p>The problem is, you can only upgrade so much before you hit the limits of what's available. Plus, if that single server fails, your entire website goes down.</p>
<p>A better approach is <strong>horizontal scaling</strong>. This means adding more servers instead of just upgrading one. Now you have a team of servers, and each can handle a portion of the incoming user requests.</p>
<p>This approach allows for almost unlimited growth. It also creates redundancy and fault tolerance, because if one server breaks, the others can pick up the slack, and your site stays online.</p>
<h4 id="heading-directing-traffic-with-a-load-balancer">Directing Traffic with a Load Balancer</h4>
<p>With multiple servers, you need a way to make sure no single server gets overwhelmed. This is where a <strong>load balancer</strong> comes in. It acts like a traffic cop, sitting in front of your servers and directing each new request to the best-suited server. It uses different algorithms to decide where to send the traffic.</p>
<p>For example, the <strong>Round Robin</strong> method sends requests to servers one by one, in a cycle. Another method is <strong>Least Connection</strong>, which sends the request to the server that has the fewest active connections.</p>
<h3 id="heading-speeding-up-your-website-with-caching-and-cdns">Speeding Up Your Website with Caching and CDNs</h3>
<p>Imagine your website is now used by people all over the world. A user in another country might experience slow loading times because their request has to travel all the way to your servers.</p>
<p>To fix this, you can use a <a target="_blank" href="https://www.freecodecamp.org/news/how-cdns-improve-performance-in-front-end-projects/"><strong>Content Delivery Network (CDN)</strong></a>. A CDN is a network of servers around the world that store copies of your website's static files – like images, videos, and text files. When a user requests one of these files, the CDN serves it from the closest server, making the website load much faster for them.</p>
<p>This process is a form of <strong>caching</strong>. Caching is the general idea of making copies of data and storing them in a faster-to-access location. You can cache data on your server so it doesn't need to fetch the same player stats from the database every time. This reduces the load on your database and speeds up the entire application.</p>
<p>You can read more about the <a target="_blank" href="https://www.freecodecamp.org/news/caching-vs-content-delivery-network/">difference between CDNs and caching here</a>.</p>
<h3 id="heading-building-your-application-monolith-vs-microservices">Building Your Application: Monolith vs. Microservices</h3>
<p>As your website grows, its code can become a tangled mess. You might start with a <strong>monolith</strong>, where all the features (like player stats and live scores, in our example) are built into a single, large program. <a target="_blank" href="https://www.freecodecamp.org/news/microservices-vs-monoliths-explained/">A monolith is easier to start with</a>, but it can be hard to manage and update.</p>
<p>A better approach for a large-scale application is to use a <a target="_blank" href="https://www.freecodecamp.org/news/the-microservices-book-build-and-manage-services-in-the-cloud/"><strong>microservice architecture</strong></a>. This means breaking your application into smaller, independent services, each with a specific job. For example, one service could handle player stats and another could handle live scores. This makes your code more organised and easier to update, because a change in one service won't affect the others.</p>
<p>With microservices, you need an <a target="_blank" href="https://www.freecodecamp.org/news/what-are-api-gateways/"><strong>API Gateway</strong></a>. This acts as a single entry point for all user requests, directing them to the correct microservice behind the scenes. It also handles security and other common tasks.</p>
<h3 id="heading-the-apis">The APIs</h3>
<p>Think of <strong>APIs (Application Programming Interfaces)</strong> as the “middlemen” that let different pieces of software talk to each other.</p>
<p>In simple terms, an API is like a waiter in a restaurant. You (the user) tell the waiter what you want, the waiter takes your order to the kitchen (the system), and then brings the food (data or result) back to you.</p>
<p>Without APIs, your app, website, or software wouldn’t know how to ask another system for information or services.</p>
<p>For example, on our sports team website:</p>
<ul>
<li><p>The front-end (what fans see) uses an API to <strong>fetch player stats</strong> from the database.</p>
</li>
<li><p>When someone buys match tickets, the API talks to the <strong>payment system</strong> to confirm the transaction.</p>
</li>
<li><p>If fans want live score updates, the API makes sure the real-time data flows smoothly from the server to their screen.</p>
</li>
</ul>
<p>So, APIs are important for system design because they shape how efficiently different systems connect, share data, and stay reliable under real-world use.</p>
<p>Your front-end and back-end services can communicate in several ways. The most common is a <a target="_blank" href="https://www.freecodecamp.org/news/what-is-a-rest-api/"><strong>REST API</strong></a>. It's a standardised set of rules that uses HTTP to create a consistent way for a client and server to talk to each other. For example, it defines a standard way to signal a successful request ("OK") or a server error ("Internal Server Error").</p>
<h4 id="heading-when-to-use-rest">When to use REST</h4>
<ul>
<li><p>Best when: you need simplicity, broad adoption, and easy integration with browsers, mobile apps, or third-party services.</p>
</li>
<li><p>Example: CRUD apps (blogging platforms, e-commerce sites, user management).</p>
</li>
<li><p>Strength: Human-readable JSON, stateless, widely supported.</p>
</li>
<li><p>Weakness: Over-fetching (getting more data than needed) or under-fetching (not enough data).</p>
</li>
</ul>
<p>Another style is <a target="_blank" href="https://www.freecodecamp.org/news/building-consuming-and-documenting-a-graphql-api/"><strong>GraphQL</strong></a>. Instead of getting all the data a REST API provides, GraphQL lets the client ask for only the specific data it needs, which can make things faster and more efficient.</p>
<h4 id="heading-when-to-use-graphql">When to use GraphQL</h4>
<ul>
<li><p>Best when: clients (like mobile apps) need fine-grained control over exactly what data they fetch.</p>
</li>
<li><p>Example: social media feeds, dashboards with lots of widgets, mobile apps with limited bandwidth.</p>
</li>
<li><p>Strength: Flexible queries, reduces over-fetching, strong typing system.</p>
</li>
<li><p>Weakness: More complex server setup, which can cause performance issues if queries aren’t optimised.</p>
</li>
</ul>
<p>For server-to-server communication, <a target="_blank" href="https://www.freecodecamp.org/news/what-is-grpc-protocol-buffers-stream-architecture/"><strong>gRPC</strong></a> is often used. It's known for being very fast because it uses a more efficient data format called Protocol Buffers instead of JSON.</p>
<h4 id="heading-when-to-use-grpc">When to use gRPC</h4>
<ul>
<li><p>Best when: services talk to each other in microservice architectures, and speed/efficiency is critical.</p>
</li>
<li><p>Example: real-time systems (streaming, payments, IoT, machine learning inference).</p>
</li>
<li><p>Strength: Super fast (binary Protocol Buffers), built-in support for streaming, strong contracts.</p>
</li>
<li><p>Weakness: Not browser-native (needs extra tooling for web), harder debugging compared to REST</p>
</li>
</ul>
<p>So to summarize based on my observations of what I have worked on so far:</p>
<ul>
<li><p>If you’re building something <strong>public-facing and widely consumed</strong> → go for REST.</p>
</li>
<li><p>If your app has <strong>complex, dynamic queries from clients</strong> → go for GraphQL.</p>
</li>
<li><p>If you’re dealing with <strong>high-performance internal service-to-service calls</strong> → go for gRPC.</p>
</li>
</ul>
<p>In system design, choosing the right API style directly affects performance, scalability, and user experience. If you pick REST for its simplicity, GraphQL for its flexibility, or gRPC for its speed, you’re shaping how well your system can grow and adapt as real-world demands change.</p>
<h3 id="heading-handling-real-time-data">Handling Real-Time Data</h3>
<p>Real-time data handling is challenging because it requires maintaining an active connection to continuously transmit and receive data simultaneously. Traditional servers follow a request–response model, where data is only sent when explicitly requested.</p>
<p>That's where <a target="_blank" href="https://www.freecodecamp.org/news/learn-websockets-socket-io/"><strong>WebSockets</strong></a> come in. Unlike HTTP, which is a one-and-done request-and-response model, a WebSocket creates a continuous, two-way connection between the client and server. This allows the server to send updates to the user as soon as they happen, creating a real-time experience.</p>
<p>When microservices need to communicate without being directly connected, they can use <a target="_blank" href="https://www.freecodecamp.org/news/how-message-queues-make-distributed-systems-more-reliable/"><strong>message queues</strong></a>. A service sends a message to the queue, and another service picks it up when it's ready. This helps to decouple the services, so they don't have to worry about the other service being available at that exact moment.</p>
<p>On our sports site, WebSockets allow fans to see live scores instantly without refreshing the page – just like in chat apps, but here it keeps the excitement of the game alive in real time</p>
<h3 id="heading-databases">Databases</h3>
<p>Databases are a critical part of any full-stack application because they serve as the permanent home for user data. Once you’ve decided how to scale your servers and manage communication, you also need to consider the database layer. If everything else scales but the database does not, it can quickly become a bottleneck – leading to crashes, inconsistent records, or even data loss.</p>
<p>Many applications rely on <a target="_blank" href="https://www.freecodecamp.org/news/learn-relational-database-basics-key-concepts-for-beginners/"><strong>relational databases (SQL)</strong></a>, which store data in structured tables with rows and columns and are great for handling structured information. But for applications requiring high flexibility or handling massive unstructured datasets, <a target="_blank" href="https://www.freecodecamp.org/news/learn-nosql-in-3-hours/"><strong>NoSQL databases</strong></a> (like MongoDB or Cassandra) are often chosen. These databases don't follow the strict rules of SQL and are better for handling massive amounts of data.</p>
<p>They follow <a target="_blank" href="https://www.freecodecamp.org/news/acid-databases-explained/">ACID properties</a>:</p>
<ul>
<li><p><strong>Atomicity:</strong> A transaction is all or nothing.</p>
</li>
<li><p><strong>Consistency:</strong> The data always remains in a valid state.</p>
</li>
<li><p><strong>Isolation:</strong> Multiple transactions don't interfere with each other.</p>
</li>
<li><p><strong>Durability:</strong> Once a transaction is complete, the data is permanently saved.</p>
</li>
</ul>
<p>Just like with servers, you might need to scale your database. You can use <strong>sharding</strong>, which divides your data across multiple databases, or <strong>replication</strong>, which creates copies of your database to handle more read requests.</p>
<h3 id="heading-understanding-the-cap-theorem">Understanding the CAP Theorem</h3>
<p>When you're dealing with a distributed system and multiple databases, you inevitably face trade-offs. The <strong>CAP Theorem</strong> states that you can only guarantee two out of the following three properties at the same time:</p>
<ul>
<li><p><strong>Consistency</strong> – Every user sees the same, most up-to-date data.</p>
</li>
<li><p><strong>Availability</strong> – The system is always available to respond to requests.</p>
</li>
<li><p><strong>Partition Tolerance</strong> – The system continues to operate even if a part of the network fails.</p>
</li>
</ul>
<p>Now, from a system design perspective, this theorem forces us to make conscious architectural choices. For example, in financial applications (like banking), consistency often takes priority over availability because even a small inconsistency in balance data can cause chaos.</p>
<p>On the other hand, in social media feeds, availability and partition tolerance are often prioritised – it's okay if you see a slightly outdated post, but the system should never be down.</p>
<p>In the flow we’ve been discussing, whenever we introduce a new component or scale out across multiple regions, we need to reassess which two guarantees matter most for our business case. That decision directly drives what database technology we pick, how we design failover strategies, and what trade-offs we accept in user experience.</p>
<p>In short, the CAP theorem isn’t just a theory – it’s a practical compass. It guides us to balance user expectations, business priorities, and technical feasibility without breaking existing functionality, while still leaving room for future growth.</p>
<h3 id="heading-rate-limiting-and-monitoring">Rate Limiting and Monitoring</h3>
<p>When designing a system, it’s not just about making it <em>work</em> – it’s about making it resilient. Two core guardrails here are <strong>rate limiting</strong> and <strong>monitoring</strong>.</p>
<h4 id="heading-what-is-rate-limiting">What is Rate Limiting?</h4>
<p>Rate limiting is the practice of controlling how many requests a user, client, or service can make to your system within a given timeframe. For example, you might cap an API at 100 calls per user per hour. This prevents abuse, safeguards against denial-of-service attempts, and ensures fair usage across all consumers.</p>
<p>Rate limiting comes into play any time your service is exposed publicly or internally to multiple clients.</p>
<p><a target="_blank" href="https://www.freecodecamp.org/news/implement-api-rate-limiting-in-strapi/">To incorporate it</a>, you can implement limits at the API gateway, reverse proxy (like NGINX), or within your service logic itself. Many cloud providers (AWS API Gateway, GCP Endpoints) also have built-in support.</p>
<h4 id="heading-what-is-monitoring">What is Monitoring?</h4>
<p><a target="_blank" href="https://www.freecodecamp.org/news/the-front-end-monitoring-handbook/">Monitoring</a> is the practice of collecting metrics, logs, and traces from your system to understand its health in real time. Typical signals include:</p>
<ul>
<li><p><strong>Error rates</strong> (for example, how often requests fail)</p>
</li>
<li><p><strong>Latency</strong> (how long requests take)</p>
</li>
<li><p><strong>Traffic volume</strong> (load across the system)</p>
</li>
<li><p><strong>Resource utilisation</strong> (CPU, memory, disk, and so on)</p>
</li>
</ul>
<p>Monitoring is important from day one – it’s your feedback loop. Without it, you’re essentially flying blind.</p>
<p>To work it into your system, you can use observability stacks like <a target="_blank" href="https://www.freecodecamp.org/news/kubernetes-cluster-observability-with-prometheus-and-grafana-on-aws/">Prometheus + Grafana</a>, or managed solutions like Datadog, New Relic, or CloudWatch. You can also set alerts for threshold breaches (for example, 5% error rate spike).</p>
<p>In practice, rate limiting and monitoring work hand-in-hand. Rate limiting proactively guards against overload, while monitoring gives you visibility into whether the limits are working, whether scaling is needed, or whether a new type of failure is emerging.</p>
<p>For example, if you’ve designed a booking system (like in our earlier flow), rate limiting would ensure a single user can’t spam seat reservations, while monitoring would flag anomalies such as unusual spikes in request volume or sudden latency increases – helping you act before the system collapses.</p>
<h4 id="heading-why-does-this-matter-for-system-design">Why Does This Matter for System Design?</h4>
<p>These topics matter for good system design because they form the foundational building blocks of how modern applications actually operate in the real world. The way systems communicate, the type of APIs we adopt, and how we manage real-time interactions directly influence whether a product feels fast, reliable, and seamless – or slow and frustrating. In short, they determine how well the overall experience holds up when real users put it to the test.</p>
<p>When we develop a deeper understanding of how computers communicate, we begin to see the inner mechanics of client–server architecture – how APIs fetch data from databases through backend system calls. From this baseline, we can pivot into higher-level concerns:</p>
<ul>
<li><p><strong>Scalability and resilience</strong>: Using load balancers to protect against server overload.</p>
</li>
<li><p><strong>Security</strong>: Introducing rate limiting to mitigate potential cyberattacks.</p>
</li>
<li><p><strong>Efficiency</strong>: Choosing the right type of API calls and leveraging caching/CDNs for speed and reduced overhead.</p>
</li>
<li><p><strong>Reliability</strong>: Implementing logging and monitoring to detect issues early and debug faster.</p>
</li>
</ul>
<p>Together, these practices elevate a system from simply <em>working</em> to being robust, performant, and future-ready.</p>
<p>We’ve discussed the basics of all the most important concepts you’ll need to understand before building an end-to-end system. Now it’s time to deep dive into the case studies, where I’ll show you how different types of applications use system design to scale and serve billions of users.</p>
<p>I have picked services that are complex to build and handle multiple different types of components at a time, like gaming, education, and job search platforms.</p>
<p>Now let’s decode each of them together, and I’ll explain how I would scale the application if I were the developer building it.</p>
<h2 id="heading-case-studies-scaling-in-the-real-world">Case Studies: Scaling in the Real World</h2>
<p>System design is best understood when you see it in action. To show how principles like scaling, caching, load balancing, and real-time data management come together, let’s walk through two very different types of applications:</p>
<ul>
<li><p>A <strong>job search platform</strong> (focused on structured data and reliability).</p>
</li>
<li><p>An <strong>online gaming platform</strong> (focused on real-time speed and responsiveness).</p>
</li>
</ul>
<p>Looking at both will show you that, while the tools and concepts may be similar, the way we apply them depends on the type of system we’re building.</p>
<p>Both are high-traffic platforms, but with totally different needs. The job portal is about accuracy, reliability, and data-driven workflows, while the gaming platform is about instant responsiveness, fairness, and global reach.</p>
<p>In a job portal, a 1-second delay just means waiting. In a gaming app, a 1-second delay could mean losing the match. Both are failures – but for completely different reasons, and with different consequences.</p>
<p>Together, they show how the same building blocks of system design (scaling, caching, APIs, monitoring) are applied differently depending on context.</p>
<h3 id="heading-case-study-1-scaling-a-job-search-application">Case Study 1: Scaling a Job Search Application</h3>
<p>A job search platform is one of the most used applications nowadays, as there are always people looking for a job. And there are many different job portals out there that handle the complete process, from finding jobs to user onboarding.</p>
<p>We’ll look at an example site called <a target="_blank" href="https://upstaff.com/">Upstaff</a>. It’s a platform that focuses on hiring AI engineers as its core service (although it services other job profiles as well). At its core, it handles structured information – things like user profiles, job postings, and applications.</p>
<p>Day one, you have a few hundred users. On day one hundred, you may have tens of thousands. And in a year? Possibly millions. That growth means you have to think about scale, speed, and data integrity from the start.</p>
<h4 id="heading-the-core-components">🔹 The Core Components</h4>
<ul>
<li><p><strong>User Management:</strong> registration, login, and role-based access (job seeker vs employer).</p>
</li>
<li><p><strong>User Profiles</strong>: résumés, skills, preferences, stored in structured databases.</p>
</li>
<li><p><strong>Job Posting and Listings</strong>: employers create jobs, seekers browse/search/filter.</p>
</li>
<li><p><strong>Application Tracking</strong>: Every job seeker’s application status needs to be accurate and up to date.</p>
</li>
<li><p><strong>Recommendation Engine</strong>: jobs matched to users based on history and profile.</p>
</li>
<li><p><strong>Notifications</strong>: alerts for new job matches, recruiter replies, deadlines.</p>
</li>
</ul>
<p>Every one of these features depends on the system’s ability to handle large amounts of structured data – and handle it reliably.</p>
<h4 id="heading-step-1-starting-small">Step 1: Starting Small</h4>
<p>At the beginning, everything can run on one server with a single database. This setup is enough for a few thousand users.</p>
<h4 id="heading-step-2-growth-and-traffic-spikes">Step 2: Growth and Traffic Spikes</h4>
<p>As more users join, the single server starts to slow down. To fix this, we add a load balancer and scale horizontally – adding multiple servers that share the traffic.</p>
<h4 id="heading-step-3-database-challenges">Step 3: Database Challenges</h4>
<p>Soon, the database becomes the bottleneck. Searching across thousands of jobs slows things down. To fix this, we:</p>
<ul>
<li><p>Use sharding (split the database by user IDs or job IDs).</p>
</li>
<li><p>Add a cache (like Redis) to store frequent queries such as “Software Engineer in New York.”</p>
</li>
<li><p>Use a CDN to deliver logos, profile pictures, and other static files faster.</p>
</li>
</ul>
<h4 id="heading-step-4-heavy-features">Step 4: Heavy Features</h4>
<p>New features like a résumé parser or recommendation engine require extra computing power. Instead of overloading the main app, we move these into separate microservices.</p>
<h4 id="heading-step-5-security-and-reliability">Step 5: Security and Reliability</h4>
<p>Finally, as traffic grows, we add:</p>
<ul>
<li><p><strong>Rate limiting</strong> to stop any one user from spamming APIs.</p>
</li>
<li><p><strong>Monitoring</strong> to track errors, latency, and user activity in real time.</p>
</li>
<li><p><strong>API Gateway</strong> to ensure all requests are secure and validated. Here is an overview of the entire system scaling in an image :</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754281195211/570680c1-2813-43b0-87a1-48a817ab6c9a.png" alt="system design job portal flowchart" width="600" height="400" loading="lazy"></p>
<p>This example shows how careful planning makes growth smooth. By scaling horizontally, caching smartly, and splitting heavy features into microservices, a job portal like Upstaff can handle millions of users without breaking.</p>
<h3 id="heading-case-study-2-scaling-an-online-gaming-application">Case Study 2: Scaling an Online Gaming Application</h3>
<p>Now let’s flip the script. In a gaming platform like <a target="_blank" href="https://xn--ntcasinoutanlicens-ltb.com">this site</a>, speed and responsiveness matter more than anything. A 1-second delay in a job search is annoying. But in gaming, a 1-second delay can make players quit forever. Unlike job portals, the biggest challenge here is real-time responsiveness. A tiny delay can ruin the user experience.</p>
<h4 id="heading-the-core-components-1">🔹 The Core Components</h4>
<ul>
<li><p><strong>User Management Service</strong>: accounts, profiles, and login.</p>
</li>
<li><p><strong>Game Lobby and Matchmaking</strong>: pair players by skill, region, and latency.</p>
</li>
<li><p><strong>Game Server Manager</strong>: spin up and manage live matches.</p>
</li>
<li><p><strong>Real-Time Communication</strong>: powered by WebSockets or UDP for low latency.</p>
</li>
<li><p><strong>Game State Store (Redis)</strong>: fast sync of health, scores, and positions.</p>
</li>
<li><p><strong>Leaderboard &amp; Stats Engine</strong>: global rankings, achievements, and progress.</p>
</li>
<li><p><strong>In-Game Economy</strong>: coins, tokens, inventory.</p>
</li>
<li><p><strong>Payment Gateway</strong>: subscriptions and purchases.</p>
</li>
<li><p><strong>Anti-Cheat Security Layer</strong>: fairness across all players.</p>
</li>
<li><p><strong>Monitoring and Logging</strong>: server uptime, latency, and crash reports.</p>
</li>
</ul>
<p>Unlike a job portal, every millisecond counts.</p>
<h4 id="heading-step-1-starting-small-1">Step 1: Starting Small</h4>
<p>At first, one powerful server is enough to run both the game logic and user accounts. With just a few players, things run smoothly.</p>
<h4 id="heading-step-2-more-players-more-problems">Step 2: More Players, More Problems</h4>
<p>As millions of players log in, the single server crashes. To fix this, we:</p>
<ul>
<li><p>Add a Game Server Manager that spins up separate servers for each match.</p>
</li>
<li><p>Introduce a load balancer that assigns players to available servers.</p>
</li>
</ul>
<h4 id="heading-step-3-real-time-data-handling">Step 3: Real-Time Data Handling</h4>
<p>In gaming, speed is everything. Instead of slow HTTP, we switch to WebSockets or UDP for instant communication. To keep everyone’s game view in sync:</p>
<ul>
<li><p>Use in-memory databases like Redis for positions, scores, and health.</p>
</li>
<li><p>Update leaderboards in near real time.</p>
</li>
</ul>
<h4 id="heading-step-4-scaling-features">Step 4: Scaling Features</h4>
<p>Other services run in parallel:</p>
<ul>
<li><p><strong>Matchmaking service</strong> pairs players by skill, location, and latency.</p>
</li>
<li><p><strong>Economy service</strong> manages coins, rewards, and in-game items.</p>
</li>
<li><p><strong>Payment gateway</strong> handles subscriptions and purchases securely.</p>
</li>
<li><p><strong>Notification system</strong> sends updates like “new event starting.”</p>
</li>
</ul>
<h4 id="heading-step-5-global-expansion-and-security">Step 5: Global Expansion and Security</h4>
<p>When the game expands worldwide:</p>
<ul>
<li><p>Use a CDN to deliver maps and skins quickly to all regions.</p>
</li>
<li><p>Add an Anti-Cheat layer to detect and block unfair play.</p>
</li>
<li><p>Build an Admin and Monitoring panel to track system health and user behavior.</p>
</li>
</ul>
<p>In gaming, system design focuses less on structured data and more on low latency, real-time communication, and fairness. Scaling here means keeping gameplay smooth and secure, even when millions of players join at once. Here is the image representation of the complete game platform system design</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754287625776/546f3949-efa1-4a57-9906-ceb3f8a62f63.png" alt="system design game website flowchart" width="600" height="400" loading="lazy"></p>
<h3 id="heading-why-both-case-studies-matter">Why Both Case Studies Matter</h3>
<p>You might wonder – why show two different systems instead of just one? The answer is that system design isn’t “one-size-fits-all.”</p>
<ul>
<li><p>The job portal teaches us how to scale structured, data-heavy applications where reliability and accuracy matter most.</p>
</li>
<li><p>The gaming platform shows us how to design for speed, real-time communication, and fairness under extreme load.</p>
</li>
</ul>
<p>Together, these examples prove that the same system design principles of scaling, caching, monitoring, and microservices apply everywhere. What changes is <em>how you use them</em> to solve the unique challenges of your platform.</p>
<h2 id="heading-qampa">Q&amp;A</h2>
<h3 id="heading-how-to-get-into-system-design-if-you-dont-understand-anything-yet"><strong>How to get into system design if you don’t understand anything (yet)?</strong></h3>
<p>I get this question all the time – and the first thing you need to know is that system design isn’t some separate, elite domain. It’s an <em>additional skill</em> that complements your development journey.</p>
<p>If you're a full-stack developer (or aiming to be one), learning system design gives you a huge edge. After all, building an app isn't just about making it work – it’s about making it <em>work well</em> at scale.</p>
<p>So if you’re just starting and don’t even know how to become a full-stack developer yet, start there. Learn to build applications first, and then system design will start making a lot more sense. Read this guide <a target="_blank" href="https://www.freecodecamp.org/news/become-a-full-stack-developer-and-get-a-job/">How to Become a Full-Stack Developer in 2025 (and Get a Job) – A Handbook for Beginners</a> to learn how to become a full-stack developer.</p>
<h3 id="heading-how-do-you-understand-system-design-concepts"><strong>How do you understand system design concepts?</strong></h3>
<p>The short answer: with time and consistent practice.</p>
<p>Think of it like this: if you know how to use a pencil, it’s up to you whether you use it to sketch or to write. The pencil is just a tool. Similarly, in system design, once you understand the core concepts, it’s about knowing <em>when</em> and <em>where</em> to apply them. The rest – frameworks, tools, and technologies – are just means to an end.</p>
<p>It’s not about memorising patterns, it’s about developing the instinct to use the right building blocks at the right time.</p>
<h3 id="heading-what-tools-should-you-know-before-diving-into-system-design">What tools should you know before diving into system design?</h3>
<p>The truth is, the list keeps growing. New tools and platforms are constantly emerging. But in my experience, having a solid foundation in the following areas makes a huge difference:</p>
<ul>
<li><p><strong>Full Stack Development</strong> – so you understand how both frontend and backend systems interact.</p>
</li>
<li><p><strong>Cloud Platforms</strong> (like AWS, GCP, or Azure) – because most modern systems are cloud-native.</p>
</li>
<li><p><strong>CI/CD Pipelines</strong> – for automating testing, integration, and deployment.</p>
</li>
<li><p><strong>Deployment Strategies</strong> – to know how to roll out new changes with minimal risk.</p>
</li>
</ul>
<p>Mastering these gives you the technical muscle to design systems that are scalable, reliable, and production-ready. I am a frontend developer, why should I know the system design</p>
<h3 id="heading-what-resources-should-i-study-to-learn-system-design">What resources should I study to learn system design?</h3>
<p>In my last <a target="_blank" href="https://www.freecodecamp.org/news/become-a-full-stack-developer-and-get-a-job">article</a>, I shared all the resources that helped me learn system design.</p>
<p>System design is crucial for building reliable, high-performance applications. I explored the following resources:</p>
<ul>
<li><p><a target="_blank" href="https://github.com/donnemartin/system-design-primer"><strong>Free GitHub system design repositor</strong></a><strong>y</strong></p>
</li>
<li><p><a target="_blank" href="https://github.com/ByteByteGoHq/system-design-101"><strong>Another free GitHub system design repositor</strong></a><strong>y</strong></p>
</li>
<li><p><a target="_blank" href="https://www.systemdesignhandbook.com/system-design-interview-handbook/">Free System Design Handbook</a></p>
</li>
<li><p><a target="_blank" href="https://grokkingthesystemdesign.com/intro-to-system-design/">Free Hands-on System Design Learning Platform</a></p>
</li>
<li><p><a target="_blank" href="https://www.educative.io/guide/system-design">Free Intro to System Design Blog</a></p>
</li>
</ul>
<p>Case studies and real-world architectures can also help you understand large-scale systems. You can follow any big tech engineering blog (Uber has a great one).</p>
<p>For high-level concepts, I went through the <a target="_blank" href="https://www.educative.io/courses/grokking-the-system-design-interview"><strong>Grokking System Design</strong></a> course. It’s a paid resource, and I used it to deepen my understanding of system design. It’s not mandatory, but it helped me think about architecture at scale.</p>
<p><strong>Note:</strong> there are other sites and courses out there of course, but I only share what I have personally experienced and used, and I focus on FREE material first.</p>
<h3 id="heading-where-to-practice-system-design">Where to practice system design</h3>
<p>This is where real learning begins. Start by picking any existing application from the internet, just like I did. Google something specific, like “job application portal,” but avoid the results on the first page. Those apps are usually well-optimised and already follow best practices in system design.</p>
<p>Instead, dig deeper and explore results from the second or third page. Look for an app that seems to be in its early stages.</p>
<p>Once you find one, try to understand how the entire application works. Break it down into its core components and then imagine what would happen if that app started receiving 1 million users a day. You’ll naturally begin to see what system design elements are needed to handle that kind of load.</p>
<h2 id="heading-final-notes">Final Notes</h2>
<p>Learning system design becomes much easier when you’ve already built something. Let’s say you’ve created an app and now you're thinking about how to scale it – that’s where real learning begins. The moment you start writing down your requirements (like how your app should behave when it starts getting more traffic), you naturally begin to develop system-level thinking. It’s this process of planning and anticipating real-world usage that turns theory into a practical skill.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Full Stack + System Design = The Ultimate Developer Stack 🔥</p>
<p>By mastering these skills, you can turn any idea into a real-world product, secure high-paying jobs, and even start your tech venture.</p>
<p>Now it's your turn – what are you building next? Let me know!</p>
<p>That’s all from my side. If you found this article helpful, feel free to share it and connect with me. I’m always open to new opportunities:</p>
<ul>
<li><p>Follow me on X: <a target="_blank" href="https://x.com/prankurpandeyy">Prankur's Twitter</a></p>
</li>
<li><p>Connect with me on LinkedIn: <a target="_blank" href="https://linkedin.com/in/prankurpandeyy">Prankur's LinkedIn</a></p>
</li>
<li><p>Follow me on GitHub: <a target="_blank" href="https://github.com/prankurpandeyy">Prankur’s Github</a></p>
</li>
<li><p>View my Portfolio: <a target="_blank" href="https://prankurpandeyy.netlify.app/">Prankur's Portfolio</a></p>
</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Become a Full-Stack Developer in 2025 (and Get a Job) – A Handbook for Beginners ]]>
                </title>
                <description>
                    <![CDATA[ Whenever I publish a new article, I receive countless emails and DMs across social media asking, "How can I become a Full Stack Developer like you? How much DSA do I need to know? How long does it take?" Well, I always say, "Wait for my next tutorial... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/become-a-full-stack-developer-and-get-a-job/</link>
                <guid isPermaLink="false">67d1f8cced96446e8fad7db9</guid>
                
                    <category>
                        <![CDATA[ Full Stack Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ job search ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Prankur Pandey ]]>
                </dc:creator>
                <pubDate>Wed, 12 Mar 2025 21:12:44 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1741296524045/6d9bed13-d3bb-4fb3-95ac-45f5dd4f2033.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Whenever I publish a new article, I receive countless emails and DMs across social media asking, <em>"How can I become a Full Stack Developer like you? How much DSA do I need to know? How long does it take?"</em></p>
<p>Well, I always say, <em>"Wait for my next tutorial!"</em>—and here it is! This guide will walk you through everything I did to become a Full Stack Developer and how you can use the same approach to turn any idea into a real product.</p>
<p>I've recommended this approach to many developers before writing this article, and they were amazed at the results. Now, it's your turn. 🚀</p>
<h3 id="heading-what-we-will-cover"><strong>What We Will Cover</strong></h3>
<ul>
<li><p><a class="post-section-overview" href="#heading-why-full-stack-development">Why Full Stack Development?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-full-stack-development-including-devops">What is Full Stack Development (Including DevOps)?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-devops-for-full-stack-developers">DevOps for Full Stack Developers</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-learn-full-stack-development">How to Learn Full Stack Development</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-use-ai-in-your-development">How to Use AI in Your Development</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-building-full-stack-projects-with-ai">Building Full-Stack Projects with AI</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-land-a-full-stack-developer-job-in-2025">How to Land a Full Stack Developer Job in 2025</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-q-amp-a">Q &amp; A</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-final-notes">Final Notes</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-why-full-stack-development"><strong>Why Full Stack Development?</strong></h2>
<p>I chose Full Stack Development because my journey began with frontend development, and, over time, I found myself naturally transitioning into backend development.</p>
<p>When I first started, frontend development felt like an uphill battle. I was completely new to the space, and every concept seemed complex. But with patience and relentless practice, I reached a stage where I could take any design and turn it into functional code. Around that time, React was dominating the industry. It was trending, and once I grasped its core concepts, it became an intuitive and powerful tool in my arsenal.</p>
<p>As I gained confidence in frontend development, I started exploring more. Full Stack Development initially felt overwhelming, so I took it step by step. I focused on mastering frontend first, diving deep into the nuances of building intuitive and responsive interfaces. Over time, I worked on multiple projects—six practice projects and over twenty client projects—before I even considered backend development.</p>
<p>The turning point came when I became fascinated with APIs and databases. I wanted to understand how data flowed between the frontend and backend, how a single logic could control server behavior, and how each new function I added shaped the backend's response. It was challenging yet incredibly rewarding. I found joy in debugging, optimizing, and making everything work seamlessly together.</p>
<p>It was during my job search that I had a realization: companies weren’t just looking for frontend developers – they valued devs who could handle backend development as well. Having backend skills not only made me more competitive but also helped me refine my frontend capabilities.</p>
<p>That’s when I decided that I wouldn’t limit myself to one side of development. To build complete, production-ready applications, I committed to mastering both frontend and backend, ensuring I could create seamless, full-fledged digital experiences.</p>
<p>Now, let’s dive into the technical details so you can get there, too.</p>
<h2 id="heading-what-is-full-stack-development-including-devops"><strong>What is Full Stack Development (Including DevOps)?</strong></h2>
<p>When I first stepped into the world of coding, I was fascinated by how websites worked. Clicking a button, filling out a form, or watching animations unfold on a webpage felt almost magical.</p>
<p>But then, I had no idea about the complexity behind these interactions. I started with frontend development, where I learned how to design and build the visible part of applications—the user interface (UI) and user experience (UX).</p>
<h3 id="heading-the-frontend-bringing-ideas-to-life">The Frontend: Bringing Ideas to Life</h3>
<p>Frontend development is all about what users see and interact with. It involves writing code to design layouts, animations, and interactive elements that create a seamless user experience. I started with HTML, CSS, and JavaScript, the foundational technologies of the web. But as I built more projects, I realized that modern frontend development had evolved far beyond basic web pages.</p>
<p>That’s when I discovered React.js—a JavaScript library that makes it easier to build dynamic, fast, and scalable web applications. Unlike traditional methods, React uses a component-based approach, where every part of the UI (buttons, forms, navigation bars) is reusable and managed efficiently.</p>
<p>After I learned React, I explored Next.js, a powerful framework built on React that enhances performance with features like server-side rendering (SSR) and static site generation (SSG), making applications load faster and helping them become more SEO-friendly.</p>
<p>To style my applications, I moved beyond traditional CSS and started using Tailwind CSS, a utility-first framework that allowed me to create beautiful designs without writing repetitive styles. Tailwind made my workflow more efficient, helping me focus on design without getting lost in excessive CSS files.</p>
<p>But frontend alone wasn’t enough. I wanted to understand what happened behind the scenes when I clicked a button or submitted a form. That curiosity led me to backend development.</p>
<h3 id="heading-the-backend-powering-the-logic-behind-the-scenes">The Backend: Powering the Logic Behind the Scenes</h3>
<p>Backend development is the backbone of any application. It handles data storage, authentication, business logic, and communication with databases and APIs. My journey into backend development started with Node.js, a runtime that allows JavaScript to run on servers, making it possible to build full-fledged applications using a single programming language.</p>
<p>As I explored deeper, I discovered NestJS, a progressive Node.js framework that brings structure and scalability to backend development. Unlike traditional Node.js setups, NestJS follows an opinionated architecture inspired by Angular, making backend code more modular, reusable, and maintainable.</p>
<p>I also worked with tRPC, a modern framework that eliminates the need for REST APIs by providing a type-safe way for frontend and backend to communicate seamlessly. This reduced development time, improved security, and ensured fewer errors in data transmission.</p>
<p>For data storage, I experimented with different databases:</p>
<ul>
<li><p><strong>MongoDB</strong> – A NoSQL database that stores data in JSON-like documents, making it flexible for handling unstructured or semi-structured data.</p>
</li>
<li><p><strong>PostgreSQL</strong> – A relational database system known for its robustness, performance, and ability to handle complex queries.</p>
</li>
<li><p><strong>Appwrite</strong> – A cloud-based solution offering real-time data synchronization, authentication, and serverless backend services, making it ideal for fast-moving applications. I used it on my mobile app project just to test out the backend as a service and I was impressed to see the outcome.</p>
</li>
</ul>
<p>Working with databases helped me understand the importance of efficient data modeling and how backend services interact with the frontend. But my learning didn’t stop there—I wanted to go beyond development and dive into the world of deployment and cloud infrastructure.</p>
<h3 id="heading-devops-amp-cloud-making-applications-scalable-and-reliable">DevOps &amp; Cloud: Making Applications Scalable and Reliable</h3>
<p>Building an application is one thing, but making sure it runs smoothly, scales under heavy traffic, and remains secure is another challenge. That’s where DevOps and cloud technologies come into play.</p>
<p>I learned about Docker, a containerization tool that allows applications to run in isolated environments, ensuring they work the same way regardless of where they are deployed. Then came Kubernetes, an orchestration system that automates the deployment and scaling of applications, making infrastructure management seamless.</p>
<p>To deploy and host my applications, I explored AWS (Amazon Web Services), which offers cloud computing solutions for hosting databases, servers, and entire applications with high availability and security. Understanding cloud platforms gave me the confidence to handle production-ready deployments, ensuring applications ran efficiently without downtime.</p>
<h3 id="heading-the-responsibilities-of-a-full-stack-developer">The Responsibilities of a Full Stack Developer</h3>
<p>Looking back, the journey to Full Stack Development has been about taking ownership of the entire development lifecycle—from designing user interfaces to managing databases, optimizing performance, and deploying applications.</p>
<p>My role as a Full Stack Developer involves:</p>
<ul>
<li><p>Building intuitive and responsive user interfaces while ensuring seamless user experiences.</p>
</li>
<li><p>Writing efficient backend logic to handle authentication, data processing, and API communication.</p>
</li>
<li><p>Optimizing applications for performance, security, and scalability.</p>
</li>
<li><p>Collaborating with teams to integrate features, fix bugs, and enhance usability.</p>
</li>
<li><p>Keeping up with the latest technologies to continuously improve and stay ahead in the industry.</p>
</li>
</ul>
<h3 id="heading-ai-integration-pushing-the-boundaries-of-development">AI Integration: Pushing the Boundaries of Development</h3>
<p>As AI started transforming the tech landscape, I became interested in integrating it into applications. I explored CopilotKit and LangChain, a framework that connects AI models with real-world applications, enabling features like chatbots, automated content generation, and intelligent decision-making. AI-powered applications fascinated me because they opened up endless possibilities—from predictive analytics to smart automation.</p>
<h3 id="heading-the-bigger-picture-beyond-just-coding">The Bigger Picture: Beyond Just Coding</h3>
<p>Becoming a Full Stack Developer isn’t just about learning different technologies. It’s about problem-solving, system design, and coding best practices. I had to understand how all these pieces fit together—how the frontend communicates with the backend, how databases store and retrieve data, how servers process requests, and how everything is optimized for performance.</p>
<p>I also learned that software development is not a solo journey. Collaboration with designers, backend engineers, DevOps teams, and clients is crucial. Writing clean, maintainable code and following best practices like code reviews, documentation, and testing became second nature.</p>
<p>The beauty of Full Stack Development is that it’s ever-evolving. New frameworks, tools, and best practices emerge constantly, and adapting to change is what makes this field exciting. What started as a simple curiosity about how websites work has now turned into a passion for building complex, scalable, and intelligent applications.</p>
<p>Every project I take on brings new challenges and learning opportunities, and that’s what keeps me motivated.</p>
<p>Full Stack Development is about both coding as well as solving real-world problems, creating impactful digital experiences, and continuously pushing the boundaries of what’s possible.</p>
<h2 id="heading-devops-for-full-stack-developers"><strong>DevOps for Full Stack Developers</strong></h2>
<p>When I first started as a developer, my focus was purely on writing code. I built web applications, ensured smooth user experiences, and worked with databases. But the more I progressed, the more I realized that development was only half the battle. The real challenge came when I had to deploy my applications, manage servers, and ensure everything ran smoothly in a production environment.</p>
<p>This is where DevOps changed everything for me.</p>
<h3 id="heading-understanding-devops">Understanding DevOps</h3>
<p><a target="_blank" href="https://www.freecodecamp.org/news/how-devops-works/">DevOps (a combination of Development + Operations)</a> is a mindset that bridges the gap between developers and IT operations. It ensures that applications move smoothly from a developer’s local environment to a live server, running securely and efficiently.</p>
<p>Initially, I struggled with deployment. Writing code was one thing, but setting up servers, configuring environments, and handling cloud resources felt overwhelming. My first deployment experiences were frustrating—errors due to system differences, slow application performance, and unexpected crashes were common.</p>
<p>That’s when I realized I needed to master three essential DevOps concepts:</p>
<ol>
<li><p><strong>Linux</strong> – The backbone of servers</p>
</li>
<li><p><strong>Cloud</strong> – The key to scalability</p>
</li>
<li><p><strong>Docker</strong> – The game-changer for deployment</p>
</li>
</ol>
<h3 id="heading-linux-the-heart-of-servers">Linux: The Heart of Servers</h3>
<p>Most of the internet runs on Linux—it’s the backbone of servers, cloud platforms, and infrastructure management. But when I started, I had barely touched a Linux terminal. Everything seemed cryptic—the command line was intimidating, and I often wondered why developers preferred it over a simple graphical interface.</p>
<h4 id="heading-why-linux-is-essential-for-devops">Why Linux is Essential for DevOps</h4>
<p>Unlike Windows or macOS, Linux offers stability, security, and efficiency, making it the preferred choice for cloud deployments. Learning Linux gave me complete control over my server environment, allowing me to:</p>
<ul>
<li><p>Manage files and directories efficiently using commands like <code>ls</code>, <code>cd</code>, and <code>rm</code>.</p>
</li>
<li><p>Control system processes with <code>ps</code>, <code>kill</code>, and <code>top</code> to monitor resource usage.</p>
</li>
<li><p>Automate tasks with shell scripting, reducing manual work.</p>
</li>
<li><p>Secure my servers using SSH, firewalls, and user permissions.</p>
</li>
</ul>
<p>Once I got comfortable with Linux, I could confidently set up and manage my own servers, eliminating deployment roadblocks. But managing a single server wasn’t enough—I needed a scalable, flexible environment for real-world applications. That’s where the cloud came in.</p>
<h3 id="heading-cloud-scaling-beyond-a-single-server">Cloud: Scaling Beyond a Single Server</h3>
<p>Before I learned about cloud computing, I used to deploy my projects on shared hosting services. While they worked for small applications, they lacked scalability, control, and performance. As my applications grew, I needed a solution that could handle increased traffic, offer high availability, and support on-demand computing power.</p>
<h4 id="heading-why-cloud-computing-changed-everything">Why Cloud Computing Changed Everything</h4>
<p>Cloud platforms like AWS (Amazon Web Services), GCP (Google Cloud Platform), and Azure transformed the way I deployed applications. Unlike traditional hosting, cloud computing provided:</p>
<p>Scalability – Instantly add or reduce resources based on demand.<br>Cost-efficiency – Pay only for what you use, avoiding unnecessary expenses.<br>Global Availability – Deploy applications across multiple data centers for better performance.</p>
<p>Instead of worrying about physical servers, I could now launch virtual machines (EC2 on AWS, Compute Engine on GCP) to host applications, use managed databases (AWS RDS, Firebase, PostgreSQL on Azure) without setting up servers, and leverage serverless computing (AWS Lambda, Google Cloud Functions) for lightweight, event-driven applications.</p>
<p>With cloud expertise, I no longer feared deployment. I could confidently launch applications that scaled effortlessly, ensuring uptime and reliability. But I wasn’t done yet—there was one more challenge: ensuring consistent and fast deployments across different environments.</p>
<h3 id="heading-docker-the-game-changer-for-deployment">Docker: The Game-Changer for Deployment</h3>
<p>Before I learned Docker, I faced a recurring issue: code that worked perfectly on my local machine often failed when deployed on a server. This happened because of differences in dependencies, configurations, and operating systems between development and production environments.</p>
<h4 id="heading-how-docker-fixed-deployment-issues">How Docker Fixed Deployment Issues</h4>
<p>Docker solved this problem by introducing containerization. Instead of relying on system-specific settings, Docker allowed me to package my application, along with all its dependencies, into a single lightweight, portable container. This meant that the same container could run anywhere—on my laptop, a cloud server, or even inside Kubernetes clusters.</p>
<p>With Docker, I could:</p>
<ul>
<li><p>Package my app into a Docker image and ensure it worked identically across environments.</p>
</li>
<li><p>Run multiple services seamlessly using Docker Compose (for example, a Node.js backend, a database, and a caching system like Redis—all in separate containers).</p>
</li>
<li><p>Reduce deployment failures, since everything was pre-configured inside the container.</p>
</li>
</ul>
<p>Once I mastered Docker, I no longer had to worry about "it works on my machine but not on the server" issues. It streamlined my workflow, making deployments faster, more secure, and more efficient.</p>
<h3 id="heading-the-impact-of-devops-on-my-full-stack-journey">The Impact of DevOps on My Full Stack Journey</h3>
<p>Learning DevOps transformed me from just a developer into a deployment expert. Instead of only writing code, I could now also deploy applications with confidence using Linux servers, scale infrastructure efficiently with cloud computing, and ensure seamless deployments using Docker and containerization.</p>
<p>This not only made me a better Full Stack Developer but also opened doors to DevOps roles, giving me the flexibility to work across both development and infrastructure management.</p>
<h4 id="heading-a-never-ending-learning-process">A Never-Ending Learning Process</h4>
<p>The world of DevOps is vast, and there’s always something new to learn:</p>
<ul>
<li><p>Kubernetes for container orchestration</p>
</li>
<li><p>CI/CD pipelines for automated deployments</p>
</li>
<li><p>Infrastructure as Code (Terraform, Ansible) for managing cloud resources effortlessly</p>
</li>
</ul>
<p>But what I love most about DevOps is its impact—it turns ideas into live, scalable applications without friction. Whether I’m building a personal project or working on a high-traffic production system, DevOps ensures that my applications are not only well-built but also well-deployed.</p>
<p>For any developer looking to grow, DevOps is not optional—it’s essential. It’s the bridge between development and real-world execution, ensuring that the software we write doesn’t just run on our machines, but thrives in the real world.</p>
<h2 id="heading-how-to-learn-full-stack-development"><strong>How to Learn Full Stack Development</strong></h2>
<p>When I first started coding, I was overwhelmed by the sheer number of technologies out there. Where do you begin with HTML, CSS, JavaScript, backend frameworks, databases, DevOps? It felt like a mountain too big to climb. But as I broke it down into smaller steps and worked through them individually, everything started to make sense.</p>
<p>I’ve attached an image showcasing how I learned and experimented with various technologies. The tools mentioned in the image are specifically for those starting their journey from scratch, with no prior knowledge. That’s why I’ve omitted minor details. For example, if I mention React, it implies learning all its fundamental concepts, such as props, state management, and hooks.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741288473953/18d24a2c-c44d-4a58-a34c-431bd337842e.png" alt="Why you should learn to become a full-stack developer" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Embarking on the journey to become a full stack developer can be both exciting and overwhelming. With many technologies to learn, it's essential to have a clear roadmap. This next part of the article will break down each component of this roadmap, explaining its importance and core concepts.</p>
<h3 id="heading-frontend-development">Frontend Development</h3>
<h4 id="heading-basics-of-web-browsers">Basics of Web Browsers</h4>
<p>Understanding how <a target="_blank" href="https://www.freecodecamp.org/news/web-page-rendering-on-the-browser-different-methods/">web browsers work</a> is fundamental to web development. Browsers like Chrome, Firefox, and Safari process HTML, CSS, and JavaScript to render web pages. Knowing their functionality helps in optimizing code for better performance, compatibility, and user experience.</p>
<p><strong>Key Topics to Learn:</strong></p>
<ul>
<li><p>How browsers parse and render HTML, CSS, and JavaScript</p>
</li>
<li><p>Browser compatibility and developer tools</p>
</li>
<li><p>Techniques for optimizing website performance</p>
</li>
</ul>
<h4 id="heading-html-structuring-web-content">HTML – Structuring Web Content</h4>
<p>HTML (HyperText Markup Language) is the backbone of every website. It defines the structure of web pages using elements like headings, paragraphs, lists, and links. Writing semantic HTML ensures accessibility and better SEO.</p>
<p><strong>Important Concepts:</strong></p>
<ul>
<li><p>HTML elements and attributes</p>
</li>
<li><p>Forms and input validation</p>
</li>
<li><p>Accessibility best practices (ARIA roles, semantic tags)</p>
</li>
</ul>
<h4 id="heading-css-styling-web-pages">CSS – Styling Web Pages</h4>
<p>CSS (Cascading Style Sheets) controls the appearance of web pages, including layout, colors, fonts, and responsiveness. Using modern CSS techniques can improve design consistency and reduce development time.</p>
<p><strong>Key Topics to Learn:</strong></p>
<ul>
<li><p><strong>Media Queries:</strong> Adjusting layouts based on screen size</p>
</li>
<li><p><strong>Flexbox,Grid &amp; Box Model:</strong> Efficiently structuring page layouts</p>
</li>
<li><p><strong>CSS Frameworks (Tailwind CSS):</strong> Speeding up development with utility-first styling</p>
</li>
</ul>
<h4 id="heading-javascript-adding-interactivity">JavaScript – Adding Interactivity</h4>
<p>JavaScript is the scripting language that makes web pages dynamic. It enables interactive elements such as animations, forms, and real-time updates.</p>
<p><strong>Core Concepts:</strong></p>
<ul>
<li><p>DOM (Document Object Model) manipulation</p>
</li>
<li><p>Event handling (clicks, keyboard inputs, hover effects)</p>
</li>
<li><p>Asynchronous programming (Variables, Functions, Promises, async/await, fetch requests)</p>
</li>
</ul>
<p>I’ve shared the important things to learn in another guide, where I have built a moderate level front end project: <a target="_blank" href="https://www.freecodecamp.org/news/how-to-build-a-css-component-library-step-by-step/"><strong>How to Build a CSS Component Library and Improve Your Web Development Skills</strong></a></p>
<p>You can also check out <a target="_blank" href="https://www.freecodecamp.org/learn/full-stack-developer/">freeCodeCamp’s new beta Certified Full Stack Developer curriculum</a>. It’s a completely reworked version of the curriculum that covers everything from HTML, CSS, and JavaScript to databases, Node.js, Python, and more.</p>
<h4 id="heading-react-building-ui-components">React – Building UI Components</h4>
<p>React is a JavaScript library for creating interactive and efficient user interfaces. It uses a component-based architecture, allowing for reusable and maintainable code.</p>
<p>Learning React offers several advantages. It promotes component-based development, which leads to better code organization and reusability. React also provides robust state management through hooks and the context API, making it easier to manage application state.</p>
<p>Also, React's use of the virtual DOM ensures fast rendering, enhancing the performance of web applications.</p>
<p>Here’s a <a target="_blank" href="https://www.freecodecamp.org/news/learn-react-2024/">popular course</a> that’ll teach you all the React fundamentals you need to know to get started. And <a target="_blank" href="https://www.freecodecamp.org/news/react-for-beginners-handbook/">this handbook</a> will help reinforce these key React concepts.</p>
<h4 id="heading-tailwind-css-responsive-ui-development">Tailwind CSS – Responsive UI Development</h4>
<p>Tailwind CSS is a utility-first CSS framework that simplifies styling by providing prebuilt classes. It allows rapid development without writing custom CSS from scratch.</p>
<p>To effectively learn and utilize Tailwind CSS, it's important to grasp several key concepts. Start with the basics of CSS3 to understand the foundational principles of styling web pages. Next, delve into Tailwind configuration to learn how to set up and customize the framework according to your project's needs.</p>
<p>Tailwind CSS offers several key features that make it a powerful tool for web development. It provides a wide range of utility classes for spacing, typography, and colors, allowing for quick and efficient styling.</p>
<p>Tailwind also supports responsive design with built-in breakpoints, ensuring your web pages look great on all devices. Customization is another strong point, as you can tailor the framework to your specific requirements through the Tailwind configuration file.</p>
<p><a target="_blank" href="https://www.freecodecamp.org/news/learn-tailwind-css-by-building-a-responsive-product-card/">In this course</a>, you’ll learn Tailwind basics by building a responsive product card project.</p>
<h4 id="heading-performance-testing-optimizing-web-applications">Performance Testing – Optimizing Web Applications</h4>
<p><a target="_blank" href="https://www.freecodecamp.org/news/performance-testing-for-web-applications/">Ensuring smooth performance</a> is essential for user experience. Performance testing tools help identify bottlenecks and improve page speed.</p>
<p><strong>Tools to Use:</strong></p>
<ul>
<li><p><strong>Lighthouse:</strong> Analyzes performance, accessibility, and SEO</p>
</li>
<li><p><strong>WebPageTest:</strong> Tests load time and page rendering speed</p>
</li>
<li><p><strong>Chrome DevTools:</strong> Debugs slow-loading elements and scripts</p>
</li>
</ul>
<h4 id="heading-nextjs-advanced-react-framework">Next.js – Advanced React Framework</h4>
<p>Next.js is a powerful React framework that enhances web applications with several key features. It supports server-side rendering (SSR), which improves SEO and performance by pre-rendering pages on the server.</p>
<p>Also, Next.js offers static site generation (SSG), allowing pages to be generated at build time and served as static HTML files for faster loading times.</p>
<p>Next.js also includes API routes to handle backend functionality, making it a full-stack framework. The framework simplifies routing with its file-based routing system, eliminating the need for complex configurations.</p>
<p>In addition to all this, Next.js provides automatic code splitting, which optimizes performance by breaking JavaScript code into smaller chunks. It also supports image optimization with features like lazy loading and automatic generation of responsive image sets, enhancing performance and user experience.</p>
<p>Next.js is built on the latest React features and is designed to scale, making it a popular choice among leading companies for building dynamic and performant web applications.</p>
<p>Here are a couple courses to help you learn all about Next.js and how to build projects with it:</p>
<ul>
<li><p><a target="_blank" href="https://www.freecodecamp.org/news/create-a-google-photos-clone-with-nextjs-and-cloudinary/">Learn Next.js by building a cloud photo app</a></p>
</li>
<li><p><a target="_blank" href="https://www.freecodecamp.org/news/learn-next-js-tutorial/">Build scalable web apps with Next.js</a></p>
</li>
</ul>
<h4 id="heading-projects-applying-knowledge-in-real-world-applications">Projects – Applying Knowledge in Real-World Applications</h4>
<p>Building projects is the best way to strengthen frontend development skills. Working on real-world applications helps integrate different technologies and improve problem-solving abilities.</p>
<p><strong>Project Ideas:</strong></p>
<ul>
<li><p><strong>Weather App:</strong> Fetches and displays real-time weather data using an API.</p>
</li>
<li><p><strong>Chat App:</strong> Implements real-time messaging using WebSockets.</p>
</li>
<li><p><strong>Task Manager:</strong> Uses drag-and-drop functionality to manage tasks dynamically.</p>
</li>
</ul>
<h3 id="heading-backend-development">Backend Development</h3>
<h4 id="heading-advanced-javascript-core-concepts-for-backend-development">Advanced JavaScript – Core Concepts for Backend Development</h4>
<p>Before diving into backend technologies, it is crucial to have a solid grasp of JavaScript. Several important concepts are fundamental to mastering this language.</p>
<p><a target="_blank" href="https://www.freecodecamp.org/news/javascript-closures-explained-with-example/">Closures are a vital concept in JavaScript</a>. A closure allows a function to remember and access variables from its outer scope, even after the function has finished executing. This capability is particularly useful for maintaining data privacy and managing state within applications.</p>
<p><a target="_blank" href="https://www.freecodecamp.org/news/the-javascript-promises-handbook/">Promises are another essential concept</a>. A promise is a JavaScript object that represents the eventual completion or failure of an asynchronous operation. Promises are instrumental in managing tasks such as fetching data from a database without blocking the execution of other tasks, ensuring smoother and more efficient application performance.</p>
<p>Async/Await is a more modern and readable way to handle promises. It allows developers to write asynchronous code in a manner that resembles traditional synchronous code, making it easier to understand and maintain.</p>
<p>Key topics to focus on include understanding the JavaScript event loop and execution context, which are fundamental to how JavaScript manages and executes code. Also, learning to handle <a target="_blank" href="https://www.freecodecamp.org/news/learn-asynchronous-javascript/">asynchronous operations</a> effectively and implementing error handling using try/catch in asynchronous functions are crucial skills for any JavaScript developer.</p>
<h4 id="heading-revision-staying-up-to-date-with-backend-concepts">Revision – Staying Up to Date with Backend Concepts</h4>
<p>Technology evolves rapidly, and regularly reviewing what you have learned is essential to reinforce key concepts. One of the most important areas to revisit is APIs (Application Programming Interfaces), which facilitate communication between different parts of an application.</p>
<p><a target="_blank" href="https://www.freecodecamp.org/news/learn-rest-apis-javascript-project/">Understanding REST APIs</a> is crucial. REST (Representational State Transfer) APIs follow a standard set of rules for communication between the frontend and backend using HTTP methods.</p>
<ul>
<li><p>The GET method is used to retrieve data from the server, such as loading user profiles.</p>
</li>
<li><p>The POST method sends new data to the server, like creating a new account.</p>
</li>
<li><p>The PUT method updates existing data on the server, for example, editing a profile.</p>
</li>
<li><p>The DELETE method removes data from the server, such as deleting a user or post.</p>
</li>
</ul>
<p>Key topics to learn include designing RESTful APIs, handling API requests and responses, and understanding request headers, body, and status codes. These skills are fundamental for effective communication between different components of an application.</p>
<h4 id="heading-nodejs-running-javascript-on-the-server">Node.js – Running JavaScript on the Server</h4>
<p>JavaScript is commonly used in web browsers, but Node.js extends its capabilities by allowing it to run on a server, enabling the development of backend applications.</p>
<p>Node.js is a powerful choice for several reasons. Built on the V8 JavaScript engine, it ensures fast and efficient performance. Additionally, Node.js employs a non-blocking I/O model, which allows it to handle multiple requests simultaneously without slowing down the server.</p>
<p>This makes it particularly well-suited for applications that require real-time interactions. Furthermore, Node.js is lightweight and highly scalable, further enhancing its suitability for such applications.</p>
<p>Key topics to learn include understanding the event-driven architecture of Node.js, which is fundamental to its operation. Additionally, becoming proficient with npm (Node Package Manager) is essential for installing and managing libraries. Working with built-in modules like fs (file system) and http is also crucial for leveraging Node.js's capabilities effectively. <a target="_blank" href="https://www.freecodecamp.org/news/free-8-hour-node-express-course/">Here’s a course on Node.js + Express</a> to get you started.</p>
<h4 id="heading-expressjs-simplifying-backend-development">Express.js – Simplifying Backend Development</h4>
<p>Node.js provides core functionality, but setting up a web server manually can be complex. Express.js is a web framework that simplifies this process.</p>
<p>Express.js offers several key features that make web development more efficient. One of these features is routing, which defines how different API endpoints handle requests. For example, a GET request to /users might retrieve a list of users, while a POST request to /login could handle user login. This routing mechanism helps organize and manage the various endpoints in an application.</p>
<p>Another important feature of Express.js is middleware. Middleware functions process requests before they reach the backend logic. This can include tasks such as authentication, where the middleware checks if a user is logged in before allowing access to certain routes. Logging is another common use of middleware, where it records details about each request for monitoring and debugging purposes.</p>
<p>Express.js also provides robust error handling capabilities. It catches and manages errors, ensuring that the application runs smoothly even when issues arise. This is crucial for maintaining a good user experience and for debugging during development.</p>
<p>Express.js is commonly used for various tasks in web development. One of its primary uses is user authentication, which involves handling login and registration processes. This ensures that only authorized users can access certain parts of the application.</p>
<p>Another common use is storing and retrieving data from a database. Express.js can interact with databases to perform CRUD operations (Create, Read, Update, Delete), making it easier to manage data within the application.</p>
<p>Also, Express.js is often used for handling file uploads and user-generated content. This can include processing images, documents, or other files that users upload to the application. By simplifying these tasks, Express.js helps developers build robust and efficient web applications.</p>
<p><strong>Security in Backend Development</strong><br>To protect user data, there are various security mechanisms you can implement. One effective method is <a target="_blank" href="https://www.freecodecamp.org/news/how-to-sign-and-validate-json-web-tokens/">using JWTs, or JSON Web Tokens</a>, which is a token-based authentication system. JWTs allow users to be securely verified without requiring them to log in repeatedly. This is particularly useful for maintaining user sessions and ensuring that only authenticated users can access certain parts of an application.</p>
<p>Another important security mechanism is <a target="_blank" href="https://www.freecodecamp.org/news/how-to-use-social-login-with-oauth-for-more-secure-apps/">OAuth</a>. OAuth enables users to log in via third-party services such as Google or GitHub without needing to create a separate account for the application. This not only simplifies the login process for users but also enhances security by leveraging the authentication systems of trusted providers.</p>
<p>Encryption and hashing are crucial methods for protecting sensitive data. Before storing data such as passwords in a database, it should be encrypted or hashed. Encryption transforms the data into an unreadable format that can only be decrypted with a specific key, while hashing converts the data into a fixed-size string of characters that cannot be reversed. These techniques ensure that even if the database is compromised, the sensitive data remains secure.</p>
<p>When learning to implement these security mechanisms, there are several key topics to focus on. One essential topic is creating and managing APIs with Express.js. Express.js is a powerful framework for building web applications and APIs in Node.js. Understanding how to create and manage APIs with Express.js is fundamental for developing robust and scalable applications.</p>
<p>Implementing authentication and authorization is another critical topic. Authentication involves verifying the identity of users, while authorization determines what actions they are permitted to perform. By implementing these mechanisms, you can control access to different parts of your application and ensure that only authorized users can perform specific actions. Here’s a <a target="_blank" href="https://www.freecodecamp.org/news/whats-the-difference-between-authentication-and-authorisation/">more detailed comparison of authentication vs authorization</a> if you want to dive deeper.</p>
<p>Using middleware for logging and request validation is also important. Middleware functions in Express.js can process requests before they reach the main application logic. Logging middleware can record details about each request, which is useful for monitoring and debugging. Request validation middleware can ensure that incoming requests meet certain criteria, such as containing required fields or adhering to specific formats. This helps in maintaining the integrity and security of the application.</p>
<h4 id="heading-databases-storing-and-managing-data">Databases – Storing and Managing Data</h4>
<p>Databases are essential for storing and organizing application data. There are two main types of databases: NoSQL and SQL.</p>
<p><a target="_blank" href="https://www.freecodecamp.org/news/how-to-start-using-mongodb/">MongoDB is a popular NoSQL database</a> that stores data in flexible, JSON-like documents. This structure makes it ideal for applications with dynamic or unstructured data, where the data format may change over time. MongoDB is known for its ability to scale easily, handling large amounts of data efficiently. This makes it a good choice for applications that need to manage a lot of data or require high performance.</p>
<p>On the other hand, SQL databases like <a target="_blank" href="https://www.freecodecamp.org/news/learn-mysql-beginners-course/">MySQL</a> and <a target="_blank" href="https://www.freecodecamp.org/news/posgresql-course-for-beginners/">PostgreSQL</a> use structured tables with predefined schemas. These databases are best suited for applications that require complex relationships between data, such as financial transactions or e-commerce platforms. The structured nature of SQL databases ensures data integrity and supports complex queries.</p>
<p>When working with databases, it's important to understand <a target="_blank" href="https://www.freecodecamp.org/news/sql-vs-nosql-tutorial/">how to choose between SQL and NoSQL</a> based on the specific needs of your project. Each type of database has its strengths and is better suited for certain types of applications.</p>
<p>For example, if your application deals with a lot of unstructured data or requires high scalability, MongoDB might be the better choice. But if your application needs to manage complex data relationships and ensure data integrity, an SQL database like MySQL or PostgreSQL would be more appropriate.</p>
<p>Another key topic to learn is writing database queries to insert, update, and retrieve data. Whether you're using a NoSQL database like MongoDB or an SQL database, you'll need to know how to interact with the database to perform these operations. This involves understanding the query language used by the database and how to structure your queries to get the data you need.</p>
<p>It's also important to know how to connect a Node.js application to a database. Node.js is a popular runtime environment for building server-side applications, and being able to connect it to a database is crucial for managing application data. This involves setting up the necessary database drivers and configuring your application to communicate with the database. You’ll learn about this <a target="_blank" href="https://www.freecodecamp.org/news/how-to-build-an-event-app-with-node-js/">in this in-depth tutorial</a>.</p>
<p>By mastering these topics, you'll be able to build robust and efficient applications that can handle a wide range of data management needs. <a target="_blank" href="https://www.freecodecamp.org/news/how-to-authenticate-users-and-implement-cors-in-nodejs-applications/">This article</a> puts into practice many of the concepts we’ve discussed so far that relate to backend security, so give it a read.</p>
<h4 id="heading-cors-managing-cross-origin-requests">CORS – Managing Cross-Origin Requests</h4>
<p>CORS (Cross-Origin Resource Sharing) is a security feature implemented by web browsers to control how resources on a web page can be requested from another domain outside the domain from which the resource originated. This mechanism is crucial for preventing unauthorized access to sensitive data while allowing legitimate cross-origin requests.</p>
<h4 id="heading-how-browsers-enforce-cors-policies">How Browsers Enforce CORS Policies</h4>
<p>Browsers enforce CORS policies through a set of HTTP headers that dictate whether a request from one origin (domain) should be permitted to access resources from another origin.</p>
<p>When a web page makes a cross-origin request, the browser first sends a preflight request using the HTTP OPTIONS method to check if the actual request is allowed. The server responds with appropriate CORS headers, such as Access-Control-Allow-Origin, which specifies the permitted origins. If the server allows the request, the browser proceeds with the actual request – otherwise, it blocks the request.</p>
<h4 id="heading-configuring-cors-in-expressjs-applications">Configuring CORS in Express.js Applications</h4>
<p>To configure CORS in an Express.js application, you can use the cors middleware. This middleware allows you to specify which origins are permitted to access your API, which HTTP methods are allowed, and other CORS-related settings. Here's a basic example of how to set up CORS in an Express.js application:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express'</span>);
<span class="hljs-keyword">const</span> cors = <span class="hljs-built_in">require</span>(<span class="hljs-string">'cors'</span>);
<span class="hljs-keyword">const</span> app = express();

<span class="hljs-comment">// Use the cors middleware with default settings</span>
app.use(cors());

<span class="hljs-comment">// Or configure it with specific options</span>
app.use(cors({
  <span class="hljs-attr">origin</span>: <span class="hljs-string">'http://example.com'</span>,
  <span class="hljs-attr">methods</span>: <span class="hljs-string">'GET,POST'</span>,
  <span class="hljs-attr">allowedHeaders</span>: <span class="hljs-string">'Content-Type,Authorization'</span>
}));

app.get(<span class="hljs-string">'/'</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  res.send(<span class="hljs-string">'Hello World!'</span>);
});

app.listen(<span class="hljs-number">3000</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Server is running on port 3000'</span>);
});
</code></pre>
<p>In this example, the cors middleware is used to enable CORS for all routes in the Express.js application. You can customize the origin, methods, and allowed headers to fit your application's requirements.</p>
<h4 id="heading-importance-of-proper-cors-configuration">Importance of Proper CORS Configuration</h4>
<p>Proper CORS configuration is essential to maintain the security of your web application. Allowing all origins or using overly permissive CORS settings can expose your application to security vulnerabilities, such as cross-site request forgery (CSRF) attacks. It's important to specify only the trusted origins and limit the allowed methods and headers to what is necessary for your application to function properly.</p>
<h4 id="heading-env-files-managing-sensitive-data">.env Files – Managing Sensitive Data</h4>
<p>Sensitive information such as database credentials and API keys should not be hardcoded in the codebase. Instead, they are stored in .env (environment) files.</p>
<p>Example of a .env file:</p>
<pre><code class="lang-typescript">DATABASE_URL=mongodb:<span class="hljs-comment">//username:password@server SECRET_KEY=mysecurekey</span>
</code></pre>
<p>This ensures security and flexibility when deploying applications.</p>
<p><strong>Key Topics to Learn:</strong></p>
<ul>
<li><p>Using <a target="_blank" href="https://www.freecodecamp.org/news/how-to-use-node-environment-variables-with-a-dotenv-file-for-node-js-and-npm/">environment variables</a> in Node.js applications</p>
</li>
<li><p>Keeping sensitive data secure in production environments</p>
</li>
</ul>
<h4 id="heading-http-status-codes-understanding-server-responses">HTTP Status Codes – Understanding Server Responses</h4>
<p>Every API request returns an HTTP status code that indicates whether the request was successful or encountered an issue. These status codes are crucial for understanding the outcome of an API call and for debugging any issues that may arise.</p>
<p><strong>Common HTTP Status Codes</strong></p>
<p>The 200 OK status code indicates that the request was successful. It is the standard response for successful HTTP requests, meaning the requested resource was found and processed correctly. For example, when fetching a list of users from a database, if the data is retrieved without any issues, the server responds with a 200 OK.</p>
<p>The 400 Bad Request status code means the client sent an invalid request. This occurs when the server cannot understand the request due to incorrect syntax, malformed request structure, or deceptive routing. An example of this would be sending a JSON payload to an API that expects XML, causing the server to reject the request with a 400 response.</p>
<p>The 401 Unauthorized status code signals that authentication is required. It is returned when a request lacks valid authentication credentials or when provided credentials are incorrect. A common example is attempting to access a protected resource without logging in or supplying an invalid API key.</p>
<p>The 403 Forbidden status code indicates that the client does not have permission to access the requested resource. While the server understands the request, it refuses to authorize it due to insufficient permissions or access restrictions. For instance, trying to delete a resource without the necessary privileges would result in a 403 Forbidden response.</p>
<p>The 404 Not Found status code is returned when the requested resource does not exist. This could be because the resource has been moved, deleted, or the URL is incorrect. A typical example is attempting to access a user profile that does not exist in the database.</p>
<p>The 500 Internal Server Error status code indicates that something went wrong on the backend. It is a generic error response when the server encounters an unexpected condition that prevents it from processing the request. This could be due to a database connection failure or a bug in the server-side code.</p>
<p><strong>Key Topics to Learn</strong></p>
<p>Handling different HTTP status codes in API responses is crucial for building robust and user-friendly APIs. Each status code provides insight into the outcome of a request, and proper handling ensures better reliability and usability.</p>
<p>In an API, checking the response status and acting accordingly is essential. For example, receiving a 401 status code should prompt the user to log in again, while a 500 status code might require displaying a user-friendly error message and logging the error for debugging.</p>
<p>Implementing error handling in Express.js applications is essential for maintaining stability and security. Proper error handling helps in identifying and resolving issues quickly, leading to a better user experience.</p>
<p>In Express.js, you can use middleware to handle errors globally. A custom error-handling middleware can catch errors and send appropriate responses to the client. Also, built-in error-handling functions can manage specific errors, such as validation failures or database errors.</p>
<h4 id="heading-testing-ensuring-code-reliability">Testing – Ensuring Code Reliability</h4>
<p>Testing helps catch errors before they affect users. There are different types of tests. Unit tests check individual functions and components to ensure they work as expected. Integration tests verify that different parts of the application work together correctly. Popular testing tools include Jest and Mocha, which automate tests and improve code quality.</p>
<p>Key topics to learn include writing automated tests for backend applications and setting up a testing environment with Jest or Mocha.</p>
<h4 id="heading-building-real-world-projects">Building Real-World Projects</h4>
<p>The best way to solidify backend knowledge is by working on real projects. Some ideas include:</p>
<ul>
<li><p><strong>Note-Taking App:</strong> Allows users to create, edit, and delete notes with authentication.</p>
</li>
<li><p><strong>E-Commerce Website:</strong> Manages product listings, shopping carts, and checkout processes.</p>
</li>
<li><p><strong>Social Media Platform:</strong> Implements features like user profiles, posts, comments, and real-time messaging.</p>
</li>
</ul>
<p>Building these projects will help integrate everything you have learned and prepare you for real-world applications.</p>
<p><strong>Key Topics to Learn:</strong></p>
<ul>
<li><p>Combining frontend and backend for full-stack applications</p>
</li>
<li><p>Deploying backend applications to cloud platforms</p>
</li>
<li><p>Using system design to scale the apps</p>
</li>
<li><p>Implement security best practices</p>
</li>
</ul>
<h3 id="heading-additional-notes">Additional Notes</h3>
<h4 id="heading-dsa-data-structures-and-algorithms">DSA (Data Structures and Algorithms)</h4>
<p>While optional, <a target="_blank" href="https://www.freecodecamp.org/news/learn-data-structures-and-algorithms-2/">a solid understanding of DSA</a> can significantly improve your problem-solving skills and make you a more competent developer.</p>
<p>Data structures like arrays, linked lists, stacks, queues, trees, and graphs are fundamental to organizing and managing data efficiently. Algorithms, on the other hand, provide systematic methods for solving complex problems.</p>
<p>Mastering DSA enables you to write optimized code, enhance application performance, and tackle challenging programming tasks. It also prepares you for technical interviews, where DSA questions are commonly asked.</p>
<p>By practicing problems on platforms like LeetCode, HackerRank, and GeeksforGeeks, you can strengthen your analytical skills and become proficient in various algorithmic techniques.</p>
<h4 id="heading-system-design">System Design</h4>
<p><a target="_blank" href="https://www.freecodecamp.org/news/learn-system-design-principles/">Basic knowledge of system design</a> is a must. It helps you understand how to architect scalable and efficient systems, a critical skill for any full stack developer. System design involves designing the architecture of a software system, considering factors such as scalability, reliability, maintainability, and performance.</p>
<p>It includes understanding how different components of a system interact, how data flows between them, and how to handle failures and bottlenecks. Familiarity with design patterns, database design, caching strategies, and load balancing techniques is essential.</p>
<p>By studying system design principles and practicing with real-world examples, you can learn to build robust and efficient systems that can handle large-scale traffic and data processing requirements.</p>
<h4 id="heading-real-world-projects">Real-World Projects</h4>
<p>Finally, make sure to build at least five projects that solve real-world problems. Integrating full stack skills, including DevOps, will give you a comprehensive understanding and make you job-ready. Working on real-world projects allows you to apply your knowledge in practical scenarios, gain hands-on experience, and build a strong portfolio.</p>
<p>Choose projects that cover various domains such as e-commerce platforms, social media applications, content management systems, or data analytics dashboards. Incorporate technologies like React, Node.js, Django, and cloud services to demonstrate your versatility.</p>
<p>You should also document your projects well, including the challenges you faced and how you overcame them. This not only showcases your technical skills but also your problem-solving abilities and attention to detail.</p>
<p>By following this toolkit and continuously practicing, you'll be well on your way to becoming a proficient full stack developer. Happy coding!</p>
<h2 id="heading-how-to-use-ai-in-your-development"><strong>How to Use AI in Your Development</strong></h2>
<p>AI is revolutionizing the way Full Stack developers build, test, and maintain applications. By integrating AI-powered tools, you can speed up your workflows, reduce manual effort, and focus on solving more complex problems.</p>
<p>By embracing AI in responsible and effective ways, you’ll gain a significant advantage in terms of efficiency, productivity, and innovation.</p>
<p>Here’s how AI can be a game-changer in your development process:</p>
<h3 id="heading-1-automate-repetitive-coding-tasks"><strong>1. Automate Repetitive Coding Tasks</strong></h3>
<p>Writing boilerplate code, setting up configurations, or refactoring repetitive logic can take up valuable time. AI tools like GitHub Copilot, ChatGPT, and Tabnine can:</p>
<ul>
<li><p>Auto-generate function templates and commonly used patterns.</p>
</li>
<li><p>Suggest code completions based on context.</p>
</li>
<li><p>Convert pseudocode or plain-language descriptions into working code.</p>
</li>
<li><p>Speed up debugging by analyzing errors and suggesting fixes.</p>
</li>
</ul>
<h3 id="heading-2-enhance-project-development"><strong>2. Enhance Project Development</strong></h3>
<p>AI can assist throughout the entire development lifecycle, from ideation to deployment.</p>
<p>AI tools can help you optimize your code by analyzing performance bottlenecks and suggesting improvements. It can also automatically generate meaningful documentation based on your code’s structure.</p>
<p>You can use AI to create optimized database schemas based on use your cases, and tools like Galileo AI can help you generate UI components from sketches or text descriptions.</p>
<h3 id="heading-3-ai-driven-testing-tools"><strong>3. AI-Driven Testing Tools</strong></h3>
<p>Manually testing applications can be time-consuming, but AI can make the process smarter and more efficient.</p>
<p>First of all, AI can automatically create unit, integration, and functional tests with high coverage. Machine learning models can also identify potential vulnerabilities or bugs before they cause issues. And AI can update test cases when UI changes occur, reducing maintenance effort in automated testing.</p>
<h3 id="heading-4-integrate-ai-models-for-smart-features"><strong>4. Integrate AI Models for Smart Features</strong></h3>
<p>You can embed AI directly into your applications to create more intelligent user experiences. There are many potential use cases, including:</p>
<ul>
<li><p>Chatbots and virtual assistants – AI-powered chatbots (like ChatGPT API) can handle customer support and user queries.</p>
</li>
<li><p>Recommendation systems – Machine learning models can suggest relevant products, movies, or content based on user behavior.</p>
</li>
<li><p>Predictive analytics – AI can analyze historical data to forecast trends, optimize inventory, or improve decision-making.</p>
</li>
</ul>
<p><a target="_blank" href="https://www.freecodecamp.org/news/learn-to-code-without-being-a-coder/">Here’s a course</a> that’ll teach you the basics of using AI tools like ChatGPT in your development process.</p>
<h3 id="heading-when-not-to-use-ai-in-development"><strong>When Not to Use AI in Development</strong></h3>
<p>While AI is powerful, it’s not always the best solution. There are various cases where avoiding AI makes sense.</p>
<p>First, not every project needs AI, and it can introduce unnecessary complexity. Simple CRUD apps (Create, Read, Update, Delete) can be built efficiently with standard programming techniques. Over-engineering with AI may add unnecessary dependencies and slow down development.</p>
<p>Also, AI-generated code can increase maintenance overhead. It can sometimes be unpredictable or difficult to debug. If the AI-written code is too complex, maintaining or scaling the project can become a nightmare.</p>
<p>Another important thing to consider is whether your application deals with sensitive user data (like healthcare, banking, or legal records). In these cases, AI-generated solutions may introduce security risks. Always ensure AI tools comply with data protection regulations like GDPR or HIPAA.</p>
<p>And finally, while AI is a helpful assistant, it’s not a replacement for your own deep, experience-based coding knowledge. Relying too much on AI without understanding the logic behind the code can lead to poor decision-making and hard-to-fix errors.</p>
<h2 id="heading-building-full-stack-projects-with-ai"><strong>Building Full Stack Projects with AI</strong></h2>
<p>These project ideas are meant to inspire, not dictate, your learning path. Explore any concepts that excite you – just make sure that your project aligns with the following principles:</p>
<p>First, make sure your project solves real-world problems. Focus on practical applications rather than just theoretical exercises. Your project should aim to improve efficiency, accessibility, or automation in a meaningful way.</p>
<p>Your project should also be as unique as possible (and not just a clone of someone else’s project). Avoid directly copying existing platforms like Netflix, Twitter, or Spotify. Instead, add an innovative twist, such as AI-powered recommendations, smart automation, or predictive analytics.</p>
<p>Next, make sure you follow best coding practices. Write clean, maintainable, and well-documented code. Implement security measures, proper error handling, and optimized database queries.</p>
<p>And don’t forget about scalability and performance. Design your architecture to handle growth efficiently. Use microservices, caching, and cloud-based solutions to ensure smooth scalability.</p>
<p>Lastly, don’t just add AI for the sake of it. Ensure AI enhances the user experience or automates a meaningful task (for example, AI-powered chatbots, sentiment analysis, or personalized recommendations).</p>
<p><a target="_blank" href="https://www.freecodecamp.org/news/build-an-ai-chat-application-with-the-mern-stack/">Here’s a course</a> that teaches you how to build an AI-powered chat application using the MERN stack.</p>
<h3 id="heading-dos-and-donts-for-ai-powered-full-stack-projects"><strong>Do’s and Don’ts for AI-Powered Full Stack Projects</strong></h3>
<h4 id="heading-what-to-do"><strong>✅ What to Do:</strong></h4>
<ul>
<li><p><strong>Think beyond CRUD apps</strong> – Move past basic Create, Read, Update, Delete operations and integrate advanced features like real-time collaboration, AI-driven insights, or automation.</p>
</li>
<li><p><strong>Focus on user experience (UX)</strong> – Ensure your application is intuitive, accessible, and mobile-friendly.</p>
</li>
<li><p><strong>Use the right tech stack</strong> – Choose frameworks and tools based on project requirements, not just hype. Example: Next.js for SSR, FastAPI for AI-powered APIs, MongoDB for flexible data handling.</p>
</li>
<li><p><strong>Prioritize security</strong> – Implement authentication, authorization, rate limiting, and data encryption to protect users and their data.</p>
</li>
<li><p><strong>Optimize AI performance</strong> – If using AI, ensure your models are efficient, lightweight<strong>,</strong> and scalable. Consider deploying them using ONNX, TensorFlow.js, or cloud-based inference services.</p>
</li>
</ul>
<h4 id="heading-what-not-to-do"><strong>❌ What Not to Do:</strong></h4>
<ul>
<li><p><strong>Avoid over-engineering</strong> – Don’t use complex tech stacks unnecessarily. Just keep it simple, modular, and efficient.</p>
</li>
<li><p><strong>Don’t only make another To-Do app</strong> – Focus on projects with real impact rather than generic exercises.</p>
</li>
<li><p><strong>Avoid AI gimmicks</strong> – Adding AI without a clear purpose leads to unnecessary complexity. Ensure it enhances functionality.</p>
</li>
<li><p><strong>Don’t ignore performance</strong> – Poorly optimized AI or backend logic can slow down the user experience. Use caching (Redis), indexing, and pagination where needed.</p>
</li>
<li><p><strong>Avoid hardcoding everything</strong> – Make your application dynamic so that users can customize their experience rather than relying on static configurations.</p>
</li>
</ul>
<h2 id="heading-how-to-land-a-full-stack-developer-job-in-2025"><strong>How to Land a Full Stack Developer Job in 2025</strong></h2>
<p>You’ve learned full-stack development, one of the most in-demand tech skills. Now, it’s time to take the next step and land high-value job opportunities. Here’s exactly what I did to become an MVP Developer for web and mobile applications.</p>
<h3 id="heading-build-a-strong-portfolio">Build a Strong Portfolio</h3>
<p>Your portfolio is your first impression in the tech world. It’s not just a collection of projects—it’s proof of your skills, creativity, and ability to solve real problems.</p>
<p>A well-structured portfolio should be simple, clean, and easy to navigate. Instead of listing generic projects, focus on AI-powered applications that highlight your expertise in building intelligent solutions.</p>
<p>A strong portfolio should include:</p>
<ul>
<li><p><strong>AI-powered projects</strong>: Showcasing AI-driven applications like chatbots, recommendation systems, or automation tools can make your profile stand out.</p>
</li>
<li><p><strong>Live links</strong>: Recruiters and potential employers should be able to see your work in action. Hosting your projects online adds credibility.</p>
</li>
<li><p><strong>Well-organized GitHub repositories</strong>: Write clean, well-documented code with clear instructions in the README file. Think of it as a mini case study explaining what the project does, why you built it, and how someone else can use or contribute to it.</p>
</li>
</ul>
<p><a target="_blank" href="https://www.freecodecamp.org/news/how-to-create-a-great-personal-portfolio-page-a-step-by-step-guide/">Here’s a handbook</a> that shares a whole lot of tips and strategies for creating a great portfolio. Here’s a <a target="_blank" href="https://www.freecodecamp.org/news/how-to-create-an-interactive-terminal-portfolio-website/">fun tutorial</a> that walks you through building your own interactive terminal-style portfolio page. And <a target="_blank" href="https://www.freecodecamp.org/news/create-a-developer-portfolio-as-a-2d-game/">in this course</a>, you’ll learn how to build a portfolio that looks like a 2D game. As you can see, you can really have a good time with this.</p>
<h4 id="heading-where-can-you-host-your-portfolio-for-free">Where Can You Host Your Portfolio for Free?</h4>
<p>Hosting services play a crucial role in showcasing your work. Depending on the type of projects you build, here are some of the best free hosting options:</p>
<ul>
<li><p><strong>Vercel</strong> – Best for Next.js projects, offering seamless deployment.</p>
</li>
<li><p><strong>GitHub Pages</strong> – Great for hosting static websites and personal portfolios.</p>
</li>
<li><p><strong>Netlify</strong> – Ideal for frontend-heavy projects with easy deployment and CI/CD integration.</p>
</li>
</ul>
<h3 id="heading-craft-a-resume-that-grabs-attention">Craft a Résumé That Grabs Attention</h3>
<p><a target="_blank" href="https://www.freecodecamp.org/news/how-to-write-a-resume-that-works/">Your résumé</a> is a snapshot of your technical skills, projects, and achievements. Keep it concise, to the point, and well-structured to make it easy for recruiters to scan. Avoid unnecessary fluff and focus on real experience.</p>
<p>Key elements of a strong résumé<strong>:</strong></p>
<ul>
<li><p><strong>Highlight real projects</strong>: Avoid listing fake or irrelevant experiences. Recruiters value practical, hands-on experience over theoretical knowledge.</p>
</li>
<li><p><strong>Use bullet points</strong>: Résumés often go through an ATS (Applicant Tracking System). Structuring information in bullet points improves readability and increases the chances of passing initial screenings.</p>
</li>
<li><p><strong>Essential sections</strong>: Include Skills, Projects, Experience, Education, and Certifications.</p>
</li>
<li><p><strong>Keep it to one page</strong>: Unless you have extensive industry experience, a single-page résumé is best.</p>
</li>
</ul>
<h3 id="heading-optimize-linkedin-github-and-twitter-x-to-build-your-presence">Optimize LinkedIn, GitHub, and Twitter (X) to Build Your Presence</h3>
<p>Your online presence is just as important as your résumé. Recruiters often check social media to understand your work and contributions. Optimize your profiles to reflect your skills and showcase your work.</p>
<p><strong>LinkedIn:</strong> A well-crafted LinkedIn profile is your digital business card. It should include:</p>
<ul>
<li><p>A strong headline (like "Full-Stack Developer | AI-Powered Web &amp; Mobile Apps").</p>
</li>
<li><p>A detailed About section explaining your skills, experiences, and projects.</p>
</li>
<li><p>Regular posts sharing insights, projects, and engagement in tech communities.</p>
</li>
</ul>
<p><strong>GitHub:</strong> Your GitHub profile should reflect your coding abilities. Here’s how to make it stand out:</p>
<ul>
<li><p>Pin your best projects to give visitors an immediate sense of your work.</p>
</li>
<li><p>Write detailed README files with project explanations, installation guides, and use cases. Treat it like a case study to show why and how you built the project.</p>
</li>
</ul>
<p><strong>Twitter (X):</strong> Engaging in tech discussions can help you connect with industry professionals. Follow developers, share your work, and contribute to ongoing conversations in your field.</p>
<p><strong>Other Platforms to Showcase Your Knowledge:</strong></p>
<ul>
<li><p><strong>freeCodeCamp</strong> – Write advanced coding tutorials and technical blogs, get active on the forum, or contribute to the open-source codebase.</p>
</li>
<li><p><a target="_blank" href="http://Dev.to"><strong>Dev.to</strong></a> – Share coding insights and build credibility.</p>
</li>
<li><p><strong>Hashnode</strong> – A developer-focused blogging platform to showcase your learning journey.</p>
</li>
</ul>
<h3 id="heading-contribute-to-open-source-to-build-credibility">Contribute to Open Source to Build Credibility</h3>
<p>Open-source contributions demonstrate your ability to work in real-world software development environments. It shows you can collaborate with others, write maintainable code, and follow best practices.</p>
<h4 id="heading-how-to-start"><strong>How to start:</strong></h4>
<ol>
<li><p>Find a project you’re interested in and start small—fix bugs, update documentation, or improve existing features.</p>
</li>
<li><p>Use platforms like:</p>
<ul>
<li><p><a target="_blank" href="https://github.com"><strong>GitHub</strong></a> – Explore trending repositories and contribute.</p>
</li>
<li><p><a target="_blank" href="https://up-for-grabs.net/"><strong>Up For Grabs</strong></a> – Discover beginner-friendly open-source projects.</p>
</li>
<li><p><a target="_blank" href="https://www.firsttimersonly.com/"><strong>First Timers Only</strong></a> – Great for first-time contributors who want guidance.</p>
</li>
</ul>
</li>
</ol>
<p>Even small contributions can make a big impact on your resume and portfolio. <a target="_blank" href="https://www.freecodecamp.org/news/how-to-contribute-to-open-source-projects-as-a-beginner/">Here’s a guide</a> that’ll help you get started. And <a target="_blank" href="https://www.freecodecamp.org/news/how-to-contribute-to-open-source-handbook/">here’s a whole handbook</a> that goes into great detail on the process of contributing to open source projects.</p>
<h3 id="heading-smart-job-hunting-stand-out-from-the-crowd">Smart Job Hunting: Stand Out from the Crowd</h3>
<p>Most job seekers flood high-traffic platforms like LinkedIn Jobs and Indeed, making competition fierce. Instead of competing with thousands of applicants, target platforms where the competition is lower but opportunities are still high.</p>
<p><strong>Lesser-Known Job Platforms for Developers</strong></p>
<ul>
<li><p><a target="_blank" href="https://wellfound.com/"><strong>Wellfound (formerly AngelList Talent)</strong></a> – Best for startup jobs.</p>
</li>
<li><p><a target="_blank" href="https://www.ginitalent.com/"><strong>GiniTalent</strong></a> – Excellent level of job matching.</p>
</li>
<li><p><a target="_blank" href="https://himalayas.app/"><strong>Himalayas</strong></a> – Remote tech jobs.</p>
</li>
<li><p><a target="_blank" href="https://www.turing.com/"><strong>Turing</strong></a> – Exclusive global remote roles.</p>
</li>
<li><p><a target="_blank" href="http://lemon.io"><strong>Lemon.io</strong></a> – For top-rated freelance developers.</p>
</li>
<li><p><a target="_blank" href="http://arc.dev"><strong>Arc.dev</strong></a> – High-paying remote jobs for experienced devs.</p>
</li>
</ul>
<p>Since these platforms have a smaller user base, they increase your chances of getting noticed compared to saturated job boards with millions of applicants.</p>
<p>By taking a strategic approach to job applications, optimizing your online presence, and building an impressive portfolio, you can significantly improve your chances of landing a great job in tech.</p>
<p><a target="_blank" href="https://www.freecodecamp.org/news/learn-to-code-book/">Here’s a full book</a> by freeCodeCamp’s founder Quincy Larson on how to Learn to Code and Get a Developer Job.</p>
<h3 id="heading-final-thoughts-stand-out-be-proactive-and-keep-learning"><strong>Final Thoughts: Stand Out, Be Proactive, and Keep Learning</strong></h3>
<ul>
<li><p>Keep your portfolio and GitHub updated with new projects.</p>
</li>
<li><p>Stay active on LinkedIn &amp; Twitter—your next job might come from networking.</p>
</li>
<li><p>Contribute to open-source to gain credibility.</p>
</li>
<li><p>Apply strategically—don’t just spam resumes; focus on quality applications.</p>
</li>
</ul>
<p>👉 <strong>You have the skills. Now, position yourself where opportunities find you!</strong> 🔥</p>
<h3 id="heading-resources-i-followed-to-become-a-full-stack-developer">Resources I followed to become a full stack developer</h3>
<p>My approach to learning has always been practical and project-driven. Before diving into any new technology, I first determine what I can build with it. This not only keeps me motivated but also ensures I focus on the most relevant concepts.</p>
<p>Once I have a project idea, I research the essential technologies that will help bring it to life. Instead of getting lost in endless tutorials, I look for structured learning resources that provide hands-on practice. <strong>freeCodeCamp</strong> was instrumental in strengthening my frontend skills, particularly in JavaScript and React.</p>
<p>For backend development, I explored interactive learning platforms and official documentation to understand how databases, authentication, and APIs work. When I started learning system design, I realized it required a different way of thinking—focusing on scalability, performance, and reliability. Studying real-world architectures and large-scale applications helped me connect the dots between different technologies.</p>
<h3 id="heading-go-to-resources-for-core-web-technologies"><strong>Go-To Resources for Core Web Technologies</strong></h3>
<p>I prefer text-based learning as it allows me to absorb concepts at my own pace. Some of the best resources I used include:</p>
<h4 id="heading-frontend-development-1"><strong>Frontend Development:</strong></h4>
<ul>
<li><p><a target="_blank" href="https://www.freecodecamp.org/"><strong>freeCodeCamp</strong></a> – Hands-on projects with structured lessons.</p>
</li>
<li><p><a target="_blank" href="https://developer.mozilla.org/"><strong>MDN Docs</strong></a> – The official reference for web technologies.</p>
</li>
<li><p><a target="_blank" href="https://javascript.info/"><strong>JavaScript.info</strong></a> – A deep dive into JavaScript concepts.</p>
</li>
<li><p><a target="_blank" href="https://www.educative.io/learn-to-code">Learn to code</a> - learning Python or JavaScript by building small projects</p>
</li>
</ul>
<h4 id="heading-backend-development-1"><strong>Backend Development:</strong></h4>
<ul>
<li><p><strong>Node.js and Express.js Documentation</strong> – Essential for mastering server-side JavaScript.</p>
</li>
<li><p><a target="_blank" href="https://university.mongodb.com/"><strong>MongoDB University</strong></a> – Practical NoSQL database tutorials.</p>
</li>
</ul>
<h4 id="heading-devops-amp-system-design"><strong>DevOps &amp; System Design:</strong></h4>
<p>Unlike traditional development, DevOps is about automating workflows, improving collaboration, and ensuring seamless deployments. It involves different stacks, but I focused on the essentials—<strong>Docker, cloud services, and Linux fundamentals</strong>—to streamline my development process.</p>
<ul>
<li><p><a target="_blank" href="https://www.docker.com/101-tutorial/"><strong>Docker</strong></a><strong>:</strong> I started with <strong>Docker 101 (official Docker guide)</strong> to containerize applications.</p>
</li>
<li><p><strong>Cloud Services:</strong> I used <strong>AWS documentation (EC2)</strong> to deploy and scale backend services.</p>
</li>
<li><p><strong>Linux:</strong> Since Linux is fundamental in DevOps, I relied on <a target="_blank" href="https://linuxjourney.com/"><strong>Linux Journey</strong></a> and various open-source tools to strengthen my command-line skills. Though I’ve used Linux for 8 years, structured learning helped refine my workflow and automation techniques.</p>
</li>
</ul>
<h3 id="heading-system-design-understanding-how-scalable-systems-work"><strong>System Design: Understanding How Scalable Systems Work</strong></h3>
<p>System design is crucial for building reliable, high-performance applications. I explored:</p>
<ul>
<li><p><a target="_blank" href="https://github.com/devopsacademyau/academy"><strong>Free GitHub system design repositories</strong></a> to grasp the fundamentals.</p>
</li>
<li><p><strong>Case studies &amp; real-world architectures</strong> to understand large-scale systems, you can follow any big tech engineering blog, I prefer Uber blogs.</p>
</li>
<li><p>For high-level concepts, I went through the <a target="_blank" href="https://www.educative.io/courses/grokking-the-system-design-interview"><strong>Grokking System Design</strong></a> course. It’s a paid resource and I used it to deepen my understanding of system design. It’s not mandatory, but it helped me think about architecture at scale.</p>
</li>
</ul>
<p>By combining hands-on practice with real-world case studies, I built a strong foundation in both <strong>DevOps and system design</strong>, making my applications not just functional but also scalable and production-ready. Some important things to know about JS</p>
<ul>
<li><p><a target="_blank" href="https://github.com/ryanmcdermott/clean-code-javascript">JS Clean code</a></p>
</li>
<li><p><a target="_blank" href="https://github.com/leonardomso/33-js-concepts">JS Advance concepts</a></p>
</li>
</ul>
<h3 id="heading-the-dsa-grind-a-realistic-approach-for-frontend-amp-full-stack-developers">The DSA Grind: A Realistic Approach for Frontend &amp; Full-Stack Developers</h3>
<p>Let’s be honest—Data Structures and Algorithms (DSA) can feel overwhelming, especially if your main focus is building real-world applications. Many developers struggle to stay consistent with DSA practice, and I was no exception. I’ve tried multiple times to push myself into it, only to abandon it within minutes.</p>
<p>But while DSA may not be the most exciting part of development, it’s still essential for technical interviews, especially at mid-to-large companies. The good news? You <strong>don’t need to master every single topic</strong>—focusing on a few key concepts is often enough to clear most frontend and full-stack coding rounds.</p>
<h4 id="heading-dsa-grind"><strong>DSA Grind</strong></h4>
<p>If you’re a frontend or full-stack developer, you should focus on problem-solving techniques that align with real-world applications. These are the core topics that come up frequently in coding interviews:</p>
<p>Arrays form the foundation of data structure and algorithm problems. Efficient manipulation of arrays is essential, especially in frontend-focused roles where handling lists of data is common. Important concepts include sorting techniques such as Merge Sort and Quick Sort, searching methods like Binary Search and the Two-Pointer Approach, and optimization strategies such as the Sliding Window Technique. Kadane’s Algorithm is useful for finding the maximum subarray sum, while Prefix Sum and Difference Arrays are beneficial for solving range query problems.</p>
<p>String manipulation plays a crucial role in UI-driven applications and backend parsing. Many real-world problems require processing and transforming text data. Key concepts include string reversal and rotation, pattern matching techniques like the KMP Algorithm and Rabin-Karp, and working with anagrams and palindromes. String compression and encoding techniques help with data optimization, while the Trie data structure is widely used for applications like autocomplete and spell checkers.</p>
<p>Objects and hash tables are fundamental in JavaScript due to its object-based structure. These structures are critical for efficient lookups and caching. Essential topics include understanding the differences between hash maps and hash sets, handling collisions through chaining or open addressing, and implementing an LRU cache. Frequency counting is a useful technique for optimization problems, and graph adjacency lists are important for advanced system design concepts.</p>
<p>Linked lists, though less common in frontend development, frequently appear in coding interviews due to their recursive nature and memory efficiency. Key topics include the differences between singly and doubly linked lists, the Fast &amp; Slow Pointer Technique for cycle detection, and merging two sorted linked lists. Reversing a linked list is a classic problem that can be solved using both iterative and recursive approaches. The LRU cache implementation combines linked lists and hash maps to enable efficient data retrieval.</p>
<p>Stacks and queues are widely used in both frontend and backend applications. They are essential for features like undo/redo functionality and request handling. Important concepts include implementing stacks using arrays or linked lists, validating balanced parentheses for tasks like HTML tag matching and JSON validation, and designing Min/Max stacks for constant-time retrieval of minimum or maximum values. Queue and deque implementations, along with priority queues based on heaps, are valuable for solving scheduling and task management problems.</p>
<p>Trees and graphs, while not part of daily frontend tasks, play a crucial role in advanced full-stack and system design interviews. Binary Search Trees help optimize database queries, while Depth-First Search (DFS) and Breadth-First Search (BFS) are fundamental traversal techniques. Tries are commonly used for search and autocomplete functionalities. Graph traversal techniques are crucial for building recommendation engines and social networks, and Dijkstra’s Algorithm is widely used for shortest path calculations in routing systems.</p>
<h3 id="heading-advanced-javascript-topics-for-full-stack-interviews"><strong>Advanced JavaScript Topics for Full-Stack Interviews</strong></h3>
<p>Beyond data structures and algorithms, modern technical interviews emphasize JavaScript’s core mechanics and advanced concepts. A strong grasp of these topics is essential for full-stack roles, ensuring you can write efficient, maintainable, and optimized code.</p>
<p>Closures and scope are fundamental to understanding JavaScript’s function execution, memory management, and encapsulation. Key concepts include lexical scope, function hoisting, and private variables using closures. Real-world applications of closures, such as debouncing and throttling, are critical for performance optimization in web applications.</p>
<p>Asynchronous JavaScript is crucial for handling operations like fetching data on the frontend and managing requests on the backend. Understanding the event loop, callbacks, microtasks, and macrotasks is essential for writing non-blocking code. Promises and async/await simplify asynchronous logic, while proper error handling, resolving race conditions, and leveraging Promise.all() and Promise.race() improve efficiency.</p>
<p>Prototypes and object-oriented JavaScript play a key role in writing optimized and reusable code. A deep understanding of the prototype chain, prototypal inheritance, and the differences between <code>Object.create()</code> class-based and inheritance ensures better performance. Recognizing the distinctions between ES5 and ES6 classes and optimizing code with prototypes can lead to significant efficiency improvements.</p>
<p>Functional programming concepts are widely used in modern JavaScript frameworks like React. Understanding pure functions, higher-order functions, and function composition enhances code readability and maintainability. Key techniques include using <code>map</code>, <code>filter</code>, and <code>reduce</code> for array transformations, currying functions for partial application, and ensuring immutability to avoid unintended side effects.</p>
<p>Memory management and performance optimization are critical for building high-performance applications. Understanding garbage collection, identifying and preventing memory leaks, and utilizing WeakMap and WeakSet for optimized caching can help manage memory efficiently. Performance techniques such as debouncing and throttling improve responsiveness, while optimizing DOM manipulations enhances rendering speed.</p>
<p>A practical approach to mastering DSA and JavaScript involves integrating these concepts into real-world applications rather than blindly solving problems. Instead of random LeetCode grinding, focus on patterns like sliding window and recursion. Apply DSA principles in real projects by implementing caching with hash tables, optimizing search with tries, and structuring backend systems using trees and graphs.</p>
<p>Following a structured study plan enhances consistency and retention:</p>
<ul>
<li><p><strong>Weeks 1-2:</strong> Focus on arrays, strings, and hash tables.</p>
</li>
<li><p><strong>Weeks 3-4:</strong> Dive into linked lists, stacks, and queues.</p>
</li>
<li><p><strong>Weeks 5-6:</strong> Tackle trees, graphs, and dynamic programming.</p>
</li>
</ul>
<p>Teaching and sharing knowledge solidifies understanding. Explaining DSA problems to others, writing technical blogs, or creating tutorials on GitHub are excellent ways to reinforce learning and contribute to the developer community.</p>
<h2 id="heading-q-amp-a">Q &amp; A</h2>
<h4 id="heading-how-much-dsa-is-required-for-full-stack-development"><strong>How much DSA is required for full-stack development?</strong></h4>
<p>There’s no straightforward answer. While you may not implement data structures and algorithms (DSA) daily, they form the backbone of problem-solving in software development. A solid grasp of DSA enhances your ability to write efficient code, optimize performance, and tackle complex challenges.</p>
<h4 id="heading-how-much-math-do-i-need"><strong>How much math do I need?</strong></h4>
<p>For general full-stack development, basic arithmetic—addition, subtraction, multiplication, and division—is sufficient. But if you're diving into specialized fields like machine learning, artificial intelligence, or game development, higher-level mathematics (linear algebra, probability, and statistics) becomes essential.</p>
<h4 id="heading-how-long-does-it-take-to-become-a-full-stack-developer"><strong>How long does it take to become a full-stack developer?</strong></h4>
<p>There's no universal timeline—it depends on prior experience, learning speed, and consistency. The best approach is to break it into manageable parts and stay consistent. In my case, I dedicated roughly 6 hours daily for several months to build a strong foundation, but this may not be sustainable for you. It can take anywhere from months to years, depending on how much time you have to spend learning.</p>
<h4 id="heading-how-many-projects-should-i-build"><strong>How many projects should I build?</strong></h4>
<p>Instead of building several small, disconnected projects, aim for a comprehensive, feature-rich application that integrates multiple concepts. Think of it as building a single robust solution rather than managing multiple incomplete ones.</p>
<h4 id="heading-do-i-need-to-purchase-courses"><strong>Do I need to purchase courses?</strong></h4>
<p>It depends on your learning style. Many foundational resources are available for free, but structured paid courses can provide in-depth guidance and accountability. I started with free resources and later invested in paid courses to expand my knowledge, as I found few comprehensive free materials covering advanced topics.</p>
<h4 id="heading-do-i-need-to-grind-dsa"><strong>D</strong>o I need to grind DSA?</h4>
<p>If you are aiming for FAANG level software companies, then yes, you will have to learn DSA in-depth along with good projects and a command on a programming language.</p>
<h4 id="heading-do-i-need-certifications"><strong>Do I need certifications?</strong></h4>
<p>No, you don’t need any certificates to become a full stack developer, but having a certification from freeCodeCamp never hurts. :)</p>
<p>Learning is important, but without building projects, it remains theoretical. Apply what you learn through real-world projects to solidify your skills truly.</p>
<h2 id="heading-final-notes"><strong>Final Notes</strong></h2>
<p>Becoming a Full Stack Developer is more than just learning to code—it's about building, deploying, and scaling real-world applications. With the rise of AI, the future of Full Stack Development is even more exciting, and those who adapt early will have the edge.</p>
<p>If you’re serious about Full Stack Development, start with one step at a time, build projects, integrate AI where it makes sense, and never stop learning. 🚀</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>Full Stack + AI + DevOps = The Ultimate Developer Stack 🔥</p>
<p>By mastering these skills, you can turn any idea into a real-world product, secure high-paying jobs, and even start your tech venture.</p>
<p>Now it's your turn—what are you building next? Let me know in the comments or DM me! 👇</p>
<p>That’s all from my side. If you found this article helpful, feel free to share it and connect with me. I’m always open to new opportunities:</p>
<ul>
<li><p>Follow me on X: <a target="_blank" href="https://x.com/prankurpandeyy">Prankur's Twitter</a></p>
</li>
<li><p>Connect with me on LinkedIn: <a target="_blank" href="https://linkedin.com/in/prankurpandeyy">Prankur's LinkedIn</a></p>
</li>
<li><p>Follow me on Github: <a target="_blank" href="https://github.com/prankurpandeyy">Prankur’s Github</a></p>
</li>
<li><p>View my Portfolio: <a target="_blank" href="https://prankurpandeyy.netlify.app/">Prankur's Portfolio</a></p>
</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build a Replit Clone with Socket.io, Monaco Editor, and Copilotkit ]]>
                </title>
                <description>
                    <![CDATA[ I’ve been coding for about a decade now. And over the years, I’ve tried my fair share of development tools—especially IDEs like Sublime Text, Atom, and even NetBeans back in my college days. But when VS Code came along, it completely changed the game... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-a-replit-clone-with-socketio-monaco-editor-and-copilotkit/</link>
                <guid isPermaLink="false">67b7b7b46d2a73d146b3a978</guid>
                
                    <category>
                        <![CDATA[ AI ]]>
                    </category>
                
                    <category>
                        <![CDATA[ full stack ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Prankur Pandey ]]>
                </dc:creator>
                <pubDate>Thu, 20 Feb 2025 23:16:04 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1740064335866/a058fbf3-2d89-4e95-9d3b-07224f3985be.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>I’ve been coding for about a decade now. And over the years, I’ve tried my fair share of development tools—especially IDEs like Sublime Text, Atom, and even NetBeans back in my college days. But when VS Code came along, it completely changed the game for me. It’s lightweight, fast, and packed with features that just make life easier as a developer. It quickly became my favourite tool.</p>
<p>With all the recent advancements in AI, I wanted to build something that’s not just fun but also a meaningful learning experience. That’s how this project was born—a simple Replit-inspired clone for the web. It combines AI to generate code, lets you run React files, and displays the output seamlessly, just like Replit. On top of that, you can edit files and save your work in real-time, so nothing ever gets lost.</p>
<h3 id="heading-what-well-cover"><strong>What we’ll cover:</strong></h3>
<ul>
<li><p><a class="post-section-overview" href="#heading-prerequisites-amp-tools">Prerequisites &amp; Tools</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-well-do-here">What We’ll Do Here:</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-does-the-app-work">How Does the App Work?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-set-up-your-tools">How to Set Up Your Tools</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-structure-and-features-of-the-app">Structure and Features of the App</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-build-the-back-end">How to Build the Back End</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-build-the-front-end">How to Build the Front End</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-playing-with-the-replit-clone">Playing with the Replit Clone</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-prerequisites-amp-tools">Prerequisites &amp; Tools</h2>
<p>In this tutorial, we’ll build an AI-powered Replit clone—a web-based IDE. This IDE will enable you to generate React code files, edit them in a VSCode-like environment, preview the final output, and save the code in real time. It will also support CRUD operations on the generated files.</p>
<p>For this project, I’ll leverage some tools I’ve used in the past, including those from my <a target="_blank" href="https://www.freecodecamp.org/news/talk-to-databases-using-ai-build-a-sql-query-data-extractor">SQL Query Data Extractor project</a>. Below are the tools and technologies we’ll use:</p>
<h3 id="heading-database">Database</h3>
<p>The database is the backbone of any application—it stores data and serves it as needed. For this project, I’ll use my all-time favourite, MongoDB Atlas.</p>
<p>I chose MongoDB Atlas because it integrates seamlessly with Next.js, and since it’s a cloud-based database, I don’t need to host it manually—making it a plug-and-play solution. Performing CRUD operations with MongoDB Atlas is straightforward and efficient.</p>
<h3 id="heading-code-editor">Code Editor</h3>
<p>The code editor is the core of this project, as it powers the IDE experience. For this, I’ll use the legendary Monaco Editor, the same editor that drives VSCode. Monaco Editor handles files effortlessly and supports a wide range of file types. In this project, it will allow users to view and edit code files.</p>
<h3 id="heading-code-preview">Code Preview</h3>
<p>Once we generate and edit code in the Monaco Editor, we’ll need a way to preview its output. For this, I’ll use CodeSandbox’s Sandpack, a free and powerful tool for live code previews.</p>
<p>Sandpack supports various frameworks and file types, whether you’re working with static HTML/CSS files or frameworks like React. It displays files and their real-time output seamlessly.</p>
<h3 id="heading-ai-agent">AI Agent</h3>
<p>The AI Agent will be responsible for generating code using Natural Language Processing (NLP). Acting as a bridge between your ideas and the code, it will take user prompts and translate them into functional code files.</p>
<p>For this, I’ll use CopilotKit, my favourite free and open-source tool for AI-powered code generation. CopilotKit will take your ideas and create the corresponding code files based on your input.</p>
<h3 id="heading-ai-model">AI Model</h3>
<p>The AI Agent relies on an underlying AI model to process user inputs and generate code. For this project, I’ll use GroqAI, a flexible and reliable platform that supports various popular AI models. GroqAI’s versatility makes it perfect for this project’s requirements.</p>
<h3 id="heading-nextjs"><strong>Next.js</strong></h3>
<p>To build a robust web application that combines both frontend and backend functionalities, I’ll use Next.js. It’s an excellent framework for creating scalable applications, offering server-side rendering and other powerful features that are ideal for this project.</p>
<h3 id="heading-deployment"><strong>Deployment</strong></h3>
<p>For deployment, you can choose any service. I prefer Vercel, as it integrates seamlessly with Next.js and is free for hobby projects.</p>
<p>By combining these tools, you’ll build a powerful, user-friendly application that effortlessly produces the code and provides a live preview like Replit does.</p>
<h2 id="heading-what-well-do-here"><strong>What We’ll Do Here</strong></h2>
<p>In this tutorial, you’ll follow these steps to build our app:</p>
<p><strong>Step 1 – Set Up the Database:</strong></p>
<p>Set up a database either locally or on the cloud. For seamless integration, use an online database tool that supports data access and extraction via REST APIs.</p>
<p><strong>Step 2 – Obtain Cloud API Keys:</strong></p>
<p>Retrieve the necessary API keys for your AI model to enable smooth and secure integration.</p>
<p><strong>Step 3 – Build the Web Application:</strong></p>
<p>Develop a web application and configure the backend to integrate CopilotKit. Ensure it’s properly set up for efficient functionality.</p>
<p><strong>Step 4 – Train CopilotKit with Your Database:</strong></p>
<p>Provide your database data to CopilotKit so it can understand and utilize the information for natural language processing.</p>
<p><strong>Step 5 – Integrate the CopilotKit Chat Interface:</strong></p>
<p>Embed the CopilotKit chat interface into your application and configure it to work seamlessly with your app’s workflow.</p>
<p><strong>Step 6 – Test Locally:</strong></p>
<p>Run the application on your local machine, thoroughly testing each feature to identify and resolve any issues.</p>
<p><strong>Step 7 – Deploy the Application:</strong></p>
<p>Once testing is complete and the app is working as expected, deploy it to a hosting platform for public use.</p>
<h2 id="heading-how-does-the-app-work"><strong>How Does the App Work?</strong></h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739811798424/af2b925d-95d9-422c-8318-fe0d9d37962b.png" alt="working-app-explanation" class="image--center mx-auto" width="791" height="611" loading="lazy"></p>
<p>This project is a fun experiment and a step toward my long-term goal of building something around code editors, particularly inspired by VSCode.</p>
<p>The real magic happens with CopilotKit. As soon as you input an idea into CopilotKit, it uses predefined system prompts that adapt to your project requirements. These prompts allow CopilotKit to interpret plain English instructions and transform them into meaningful outputs. In this tutorial, I’ll show you how to configure these system prompts effectively to maximize results.</p>
<p>For example, if you enter the idea <em>“build a simple React app”</em>, CopilotKit passes that idea to the integrated AI model. The AI model, working in coordination with CopilotKit’s system prompts, generates the necessary code files based on your input.</p>
<p>The generated files are then displayed in the File Explorer on the left side of the screen. You can easily browse through the files created by CopilotKit.</p>
<p>To preview the code, simply click on a file like <code>App.js</code>. The file’s code will load into the Monaco Editor on the left, while the Sandpack preview on the right will render a real-time output of the file.</p>
<p>You can now experiment with the files—tweak the code, change colours, fonts, or text, and even write your own logic, just like working with regular HTML, CSS, or React files. Any changes you make will be saved in real time to the database. So even if you accidentally close the project, your progress will be intact. Simply refresh the page, and your code will be right where you left it.</p>
<h2 id="heading-how-to-set-up-your-tools"><strong>How to Set Up Your Tools</strong></h2>
<p>Now we’ll go through everything you need to set up the project.</p>
<h3 id="heading-install-nextjs-and-dependencies"><strong>Install Next.js and dependencies:</strong></h3>
<p>First, you’ll need to create a Next.js app. Go to the terminal and run the following command:</p>
<pre><code class="lang-javascript">npx create-next-app@latest my-next-app
</code></pre>
<p>Replace <code>my-next-app</code> with your desired project name and use TypeScript.</p>
<p>Navigate to the project folder:</p>
<pre><code class="lang-javascript">cd my-next-app
</code></pre>
<p>Start the development server:</p>
<pre><code class="lang-javascript">npm run dev
</code></pre>
<p>Open your browser and navigate to <a target="_blank" href="http://localhost:3000/"><code>http://localhost:3000</code></a> to see your Next.js app in action.</p>
<h3 id="heading-install-copilotkit-and-dependencies"><strong>Install CopilotKit and dependencies</strong></h3>
<p>Navigate to the project’s root folder in the terminal and run the following command. This will install all the necessary dependencies for CopilotKit along with other essential packages, such as dotenv, groq-sdk, sandpack, Monaco Editor, Lucide React, Socket and Mongoose.</p>
<pre><code class="lang-javascript">npm install @copilotkit/react-ui @copilotkit/react-core
npm install dotenv
npm install groq-sdk
npm install @codesandbox/sandpack-react
npm install @monaco-editor/react
npm install lucide-react
npm install mongoose
npm install socket.io
npm install socket.io-client
</code></pre>
<ul>
<li><p><strong>CopilotKit</strong>: This dependency handles all operations and configurations related to CopilotKit.</p>
</li>
<li><p><strong>Dotenv</strong>: Used for managing environment variables, and keeping sensitive keys secure within the project.</p>
</li>
<li><p><strong>GroqSDK</strong>: Facilitates access to various LLM models through a single API key.</p>
</li>
<li><p><strong>CodeSandbox Sandpack (React)</strong>: Provides the ability to display real-time previews of the code.</p>
</li>
<li><p><strong>Monaco Editor</strong>: Powers the VSCode-like environment, enabling real-time code editing.</p>
</li>
<li><p><strong>Lucide React</strong>: An icon library used to display icons for files and folders.</p>
</li>
<li><p><strong>Mongoose</strong>: Manages MongoDB schemas for storing and retrieving data from the database.</p>
</li>
<li><p><strong>socket.io:</strong> A very powerful tool for real-time data syncing between client and server.</p>
</li>
<li><p><strong>socket.io client</strong>: Extra socket.io client package for data communication.</p>
</li>
</ul>
<h3 id="heading-set-up-the-llm-for-action"><strong>Set Up the LLM for Action:</strong></h3>
<p>This step is crucial for the project, as it involves setting up the LLM (Large Language Model) to convert natural language (plain English) queries into a React framework working code.</p>
<p>There are many LLMs available, each with its unique strengths. Some are free, while others are paid, making the selection process for this project a bit challenging.</p>
<p>After thorough experimentation, I chose the Groq Adapter because:</p>
<ul>
<li><p>It integrates multiple LLMs into a single platform.</p>
</li>
<li><p>It offers access via a unified API key.</p>
</li>
<li><p>It’s fully compatible with CopilotKit.</p>
</li>
</ul>
<h4 id="heading-how-to-set-up-groq-cloud"><strong>How to Set Up Groq Cloud</strong></h4>
<p>To get started with Groq Cloud, visit its website and either log in if you already have an account or create a new account if you’re new. Once logged in, navigate to the Groq Dashboard.</p>
<p>This is the homepage of Groq cloud:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736352733541/92012af5-b3c4-4277-a50f-834c1900a2de.png" alt="groq cloud homepage" width="1366" height="768" loading="lazy"></p>
<p>Once logged in, a new page will open that’ll look like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736353229314/67313c60-47b8-4f23-b3c0-e46fcdd5201a.png" alt="groq cloud dahsboard page " width="1366" height="768" loading="lazy"></p>
<p>As you can see, the sidebar has an API Keys link. Click on it, and it will open a new page as shown in the image below. You can also select any LLM of your choice which is given at the top right before the view code option.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736353347970/3406fa54-ddc2-4a00-8b27-22536486fc64.png" alt="groqcloud api section" width="1366" height="768" loading="lazy"></p>
<p>Here, click on the Create API Key button it will open a pop up like you see below. Just enter the name of your API key and click on Submit to create a new API key for you. Then copy this API key and paste it inside your <code>.env</code> file.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736353563741/cd1a185a-2c77-470a-a5ce-eca564cf524a.png" alt="groq cloud api key creation page " width="1366" height="768" loading="lazy"></p>
<p>To enable seamless access to various LLMs on Groq Cloud, generate an API key by going to the Groq API Keys section. Create a new API key specifically for the LLM, ensuring that it is properly configured.</p>
<p>With the LLM set-up and all components ready, you are now prepared to build the project.</p>
<h3 id="heading-how-to-setup-the-database">How to setup the database</h3>
<h3 id="heading-step-1-create-a-mongodb-atlas-account"><strong>Step 1: Create a MongoDB Atlas Account</strong></h3>
<ol>
<li><p>Go to the <a target="_blank" href="https://www.mongodb.com/cloud/atlas">MongoDB Atlas website</a>.</p>
</li>
<li><p>Click on <strong>"Try Free"</strong> or <strong>"Sign Up"</strong>.</p>
</li>
<li><p>Fill in your details (name, email, password) to create an account.</p>
</li>
<li><p>Verify your email address by clicking the link sent to your inbox.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1738858230073/c150c2be-8c4c-4e79-af44-3c0792b764e3.png" alt="mongodb signup/login page" class="image--center mx-auto" width="1366" height="768" loading="lazy"></p>
<p> <strong>Step 2: Create a New Project</strong></p>
</li>
<li><p>After logging in, you will be directed to the MongoDB Atlas dashboard.</p>
</li>
<li><p>Click on the "New Project" button. This will take you to the Create a Project page.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739188846705/a25e1885-6f7d-4b00-907e-f03e4198d131.png" alt="mongodb create project page" class="image--center mx-auto" width="1366" height="768" loading="lazy"></p>
</li>
<li><p>Fill in the Project name and click on the next button, and it will open a new page to show the project owner's information.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739189031867/42ae7fda-2a8e-4bd1-92f3-5c3dae4cc502.png" alt="mongodb create project page" class="image--center mx-auto" width="1366" height="768" loading="lazy"></p>
</li>
<li><p>Now click on the Create Project Button. This will take you to the main dashboard of the project where you will get the option to create the database.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739189159505/35ecaac7-bbc4-4ee8-8ba0-196da2eaa311.png" alt="mongodb overview page" class="image--center mx-auto" width="1366" height="768" loading="lazy"></p>
</li>
<li><p>Now Click on the Create Button to open a new page with details of deploying your cluster.</p>
</li>
<li><p>Choose a cloud provider (AWS, Google Cloud, or Azure) and a region closest to your location.</p>
</li>
<li><p>Select the "Free Tier" (free forever, but with limited resources) or a paid tier for larger projects.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739189327083/46c38f50-519e-473c-b302-b0239ab409f8.png" alt="mongodb cluster selection page" class="image--center mx-auto" width="1366" height="768" loading="lazy"></p>
</li>
<li><p>Give your cluster a name (for example, <code>MyCluster</code>).</p>
</li>
<li><p>Click "Create Deployment". It will take a few minutes for the cluster to be provisioned.</p>
</li>
<li><p>Then It will ask you to connect your cluster to the database through a service. You should see your username and password – keep this somewhere.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739189624879/68a26902-861a-44b2-8d01-d04ceef55ddc.png" alt="mogodb database connection page" class="image--center mx-auto" width="1366" height="768" loading="lazy"></p>
</li>
<li><p>Here, you will have to make yourself a database user, so click on the Create Database user button.</p>
</li>
<li><p>It will take a few seconds to complete this process. Once it’s done, close the pop-up and return back to the dashboard.</p>
</li>
<li><p>On the dashboard page you can see Get Connection String button. Go on and click on it.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739189943883/84621420-312f-45e7-995e-18bf68245b1d.png" alt="mongodb db setup page" class="image--center mx-auto" width="1366" height="768" loading="lazy"></p>
</li>
<li><p>It will open a new popup containing your MongoDB atlas URI. Simply copy the string, put it into your <code>.env</code> file and use the password you created in step 14.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739190119546/2dab2beb-02aa-4450-9272-fb7aac99c313.png" alt="mongodb URL view/hide page" class="image--center mx-auto" width="1366" height="768" loading="lazy"></p>
</li>
</ol>
<h3 id="heading-example-use-case">Example use case :</h3>
<pre><code class="lang-javascript"><span class="hljs-comment">//.env file</span>
MONGODB_URI=<span class="hljs-string">'YOUR MONGODB URL'</span>
</code></pre>
<h2 id="heading-structure-and-features-of-the-app"><strong>Structure and Features of the App</strong></h2>
<p>The focus of this project is on simplicity and functionality, to replicate Replit's core features like code editing and real-time previews. The idea is to create a straightforward web application that lets you:</p>
<ul>
<li><p>Host three essential components: a File Explorer, the Monaco Editor, and a Sandbox.</p>
</li>
<li><p>Open files generated by CopilotKit in the Monaco Editor and perform CRUD operations on them.</p>
</li>
<li><p>See the real-time output of your code as you work.</p>
</li>
<li><p>Chat with the CopilotKit chatbot, which will be fully integrated into the front end.</p>
</li>
</ul>
<p>The plan is to keep the implementation clean and practical while delivering a smooth coding experience.</p>
<h3 id="heading-webpage-structure"><strong>Webpage Structure</strong></h3>
<p>Since we’ve already set up the Next.js app, the next step is to create a minimalistic webpage with the following components:</p>
<ol>
<li><p><strong>File Explorer:</strong> Displays the files generated by CopilotKit.</p>
</li>
<li><p><strong>Monaco Editor:</strong> A versatile code editor that handles various file types and displays the content.</p>
</li>
<li><p><strong>Sandbox:</strong> Shows the real-time output of the code.</p>
</li>
<li><p><strong>CopilotKit Chatbot:</strong> Generates code files based on natural language prompts.</p>
</li>
</ol>
<h3 id="heading-key-features"><strong>Key Features</strong></h3>
<ul>
<li><p><strong>Error Handling:</strong> Any failures, such as API or database issues, will be highlighted with red text for immediate visibility.</p>
</li>
<li><p><strong>Data Presentation:</strong> Data is presented in two parts: first in the File Explorer for code files, and second in the Monaco Editor for viewing the content of those files.</p>
</li>
<li><p><strong>CopilotKit Chatbot Integration:</strong> The chatbot will allow natural language interactions with the database. The blue-coloured ball on the page represents the CopilotKit chatbot, which serves as the key interface for interacting with the database.</p>
<ul>
<li><p>Users can ask questions about the database using natural language.</p>
</li>
<li><p>The chatbot processes these queries, converts them into SQL, and fetches the results seamlessly.</p>
</li>
</ul>
</li>
</ul>
<p>The front end will look something like this: <a target="_blank" href="https://replit-mongodb.vercel.app/">https://replit-mongodb.vercel.app/</a></p>
<h2 id="heading-how-to-build-the-back-end"><strong>How to Build the Back End</strong></h2>
<p>Before we start building the back end, you’ll need to put all important credentials into your <code>.env</code> file, which should look like this:</p>
<pre><code class="lang-xml">NEXT_PUBLIC_GROQ_CLOUD_API_KEY=<span class="hljs-tag">&lt;<span class="hljs-name">your-key-here</span>&gt;</span>
MONGODB_URI=<span class="hljs-tag">&lt;<span class="hljs-name">your-mongodb-url</span>&gt;</span>
</code></pre>
<p>These are environment variables used to configure sensitive or environment-specific settings in an application:</p>
<ol>
<li><p><code>NEXT_PUBLIC_GROQ_CLOUD_API_KEY</code>:</p>
<ul>
<li><p>This is a public API key for accessing the Groq Cloud API.</p>
</li>
<li><p>It is prefixed with <code>NEXT_PUBLIC_</code>, which means it is exposed to the client-side code in a Next.js application.</p>
</li>
<li><p>Replace <code>&lt;your-key-here&gt;</code> with the actual API key provided by Groq Cloud.</p>
</li>
</ul>
</li>
<li><p><code>MONGODB_URI</code>:</p>
<ul>
<li><p>This is the connection string for a MongoDB database.</p>
</li>
<li><p>It includes the database URL, credentials, and other connection details.</p>
</li>
<li><p>Replace <code>&lt;your-mongodb-url&gt;</code> with the actual MongoDB connection string.</p>
</li>
</ul>
</li>
</ol>
<h3 id="heading-how-to-configure-the-copilotkit-back-end"><strong>How to Configure the CopilotKit Back End</strong></h3>
<p>Open your Next.js app in any code editor—I prefer VSCode—and go to the root folder, which looks like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1738858655371/f648cb98-62a0-4bdd-9d03-994c7bbf758f.png" alt="f648cb98-62a0-4bdd-9d03-994c7bbf758f" class="image--center mx-auto" width="317" height="490" loading="lazy"></p>
<p>Inside the <code>app</code> folder, make a new folder called <code>api</code>. Inside the API folder, make another folder called <code>copilotkit</code>. Then in there, make a new file called <code>route.js</code> and paste this code inside the file:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> {
  CopilotRuntime,
  GroqAdapter,
  copilotRuntimeNextJSAppRouterEndpoint,
} <span class="hljs-keyword">from</span> <span class="hljs-string">"@copilotkit/runtime"</span>;

<span class="hljs-keyword">import</span> Groq <span class="hljs-keyword">from</span> <span class="hljs-string">"groq-sdk"</span>;

<span class="hljs-keyword">const</span> groq = <span class="hljs-keyword">new</span> Groq({ <span class="hljs-attr">apiKey</span>: process.env.NEXT_PUBLIC_GROQ_CLOUD_API_KEY });

<span class="hljs-keyword">const</span> copilotKit = <span class="hljs-keyword">new</span> CopilotRuntime({
  <span class="hljs-keyword">async</span> onResponse({ message, context }) {
    <span class="hljs-keyword">try</span> {
      <span class="hljs-comment">// Extract any file operations from the message and process them</span>
      <span class="hljs-keyword">const</span> fileBlocks = message.content.split(<span class="hljs-string">"---"</span>);
      <span class="hljs-keyword">if</span> (fileBlocks.length &gt; <span class="hljs-number">0</span>) {
        <span class="hljs-comment">// Format the response to use processFiles action</span>
        <span class="hljs-keyword">return</span> {
          <span class="hljs-attr">content</span>: <span class="hljs-string">`@processFiles(response: \\`</span>${message.content}\\<span class="hljs-string">`)`</span>,
        };
      }
      <span class="hljs-keyword">return</span> message;
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Error in onResponse:"</span>, error);
      <span class="hljs-keyword">return</span> message;
    }
  },
});

<span class="hljs-keyword">const</span> serviceAdapter = <span class="hljs-keyword">new</span> GroqAdapter({
  groq,
  <span class="hljs-attr">model</span>: <span class="hljs-string">"llama-3.3-70b-versatile"</span>,
  <span class="hljs-attr">systemPrompt</span>: <span class="hljs-string">`You are an AI-powered code generator integrated into a web-based IDE. Your task is to generate project files and code based on user commands.

When generating files, use this exact format:

FILE: filename.ext
CODE:
[code content here]

For multiple files, separate them with "---".

Example response:
I'll create a React component:

FILE: Button.jsx
CODE:
import React from 'react';

const Button = () =&gt; {
  return (
    &lt;button className="btn"&gt;Click me&lt;/button&gt;
  );
};

export default Button;

Important rules:
- Always include both FILE: and CODE: markers
- Use appropriate file extensions
- Generate complete, working code
- Maintain proper indentation
- Explain what you're creating before showing the files
- Make sure code is syntactically correct`</span>,
});

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> POST = <span class="hljs-keyword">async</span> (req) =&gt; {
  <span class="hljs-keyword">const</span> { handleRequest } = copilotRuntimeNextJSAppRouterEndpoint({
    <span class="hljs-attr">runtime</span>: copilotKit,
    serviceAdapter,
    <span class="hljs-attr">endpoint</span>: <span class="hljs-string">"/api/copilotkit"</span>,
  });

  <span class="hljs-keyword">return</span> handleRequest(req);
};
</code></pre>
<p>Here’s a detailed explanation of each part:</p>
<p>This code defines a CopilotKit Runtime integration with Next.js, designed to process requests for generating and managing code files in a web-based IDE environment. It connects to the <code>Groq</code> cloud service for additional functionalities and processes file-based outputs from AI-generated responses.</p>
<p>This code sets up a <code>CopilotRuntime</code> integration with Groq's AI model to generate and process code files in response to user requests. Here's a breakdown:</p>
<h3 id="heading-key-components"><strong>Key Components</strong>:</h3>
<ol>
<li><p><strong>Groq Initialization</strong>:</p>
<ul>
<li><p>The <code>Groq</code> SDK is initialized using the <code>NEXT_PUBLIC_GROQ_CLOUD_API_KEY</code> environment variable.</p>
</li>
<li><p>The model used is <code>llama-3.3-70b-versatile</code>.</p>
</li>
</ul>
</li>
<li><p><strong>CopilotRuntime</strong>:</p>
<ul>
<li><p>A <code>CopilotRuntime</code> instance is created with a custom <code>onResponse</code> handler.</p>
</li>
<li><p>The <code>onResponse</code> function processes the AI's response:</p>
<ul>
<li><p>Extracts file blocks (separated by <code>---</code>) from the message.</p>
</li>
<li><p>Formats the response to trigger a <code>processFiles</code> action if file blocks are detected.</p>
</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>GroqAdapter</strong>:</p>
<ul>
<li><p>A <code>GroqAdapter</code> is configured to interact with the Groq API.</p>
</li>
<li><p>It includes a system prompt that instructs the AI to generate code files in a specific format:</p>
<ul>
<li><p>Files are marked with <code>FILE:</code> and <code>CODE:</code>.</p>
</li>
<li><p>Multiple files are separated by <code>---</code>.</p>
</li>
<li><p>The AI is instructed to generate complete, syntactically correct code with proper explanations.</p>
</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>API Endpoint</strong>:</p>
<ul>
<li><p>A <code>POST</code> the endpoint is exposed using Next.js App Router.</p>
</li>
<li><p>It uses <code>copilotRuntimeNextJSAppRouterEndpoint</code> to handle incoming requests, passing them to the <code>CopilotRuntime</code> and <code>GroqAdapter</code>.</p>
</li>
</ul>
</li>
</ol>
<h3 id="heading-example-usage">Example Usage</h3>
<ol>
<li><p><strong>Request</strong></p>
<ul>
<li><p>A POST request to <code>/api/copilotkit</code> might look like this:</p>
<pre><code class="lang-bash">  curl -X POST http://localhost:3000/api/copilotkit \
  -H <span class="hljs-string">"Content-Type: application/json"</span> \
  -d <span class="hljs-string">'{"command": "Create a React component for a button"}'</span>
</code></pre>
</li>
</ul>
</li>
<li><p><strong>AI Response (Processed by</strong> <code>onResponse</code>)</p>
<ul>
<li><p>AI might return this response:</p>
<pre><code class="lang-plaintext">  FILE: Button.jsx
  CODE:
  import React from 'react';

  const Button = () =&gt; {
    return &lt;button&gt;Click me&lt;/button&gt;;
  };

  export default Button;
</code></pre>
</li>
</ul>
</li>
<li><p><strong>Response to Client</strong></p>
<ul>
<li><p>The API wraps the response into the formatted structure:</p>
<pre><code class="lang-json">  {
    <span class="hljs-attr">"content"</span>: <span class="hljs-string">"@processFiles(response: `FILE: Button.jsx\nCODE:\nimport React from 'react';\n\nconst Button = () =&gt; {\n  return &lt;button&gt;Click me&lt;/button&gt;;\n};\n\nexport default Button;`)"</span>
  }
</code></pre>
</li>
</ul>
</li>
</ol>
<h3 id="heading-key-features-1">Key Features</h3>
<ol>
<li><p><strong>AI-Powered Code Generation with copilotkit popup</strong>:</p>
<ul>
<li><p>The system generates complete project files based on user instructions.</p>
</li>
<li><p>Ensures proper formatting (for example, <code>FILE:</code> and <code>CODE:</code> markers).</p>
</li>
</ul>
</li>
<li><p><strong>File Handling</strong>:</p>
<ul>
<li><p>Splits multi-file responses into manageable blocks using <code>---</code>.</p>
</li>
<li><p>Supports actions like <code>@processFiles</code> for integration with the IDE.</p>
</li>
</ul>
</li>
<li><p><strong>Scalable API</strong>:</p>
<ul>
<li>Modular design with <code>CopilotRuntime</code> and <code>GroqAdapter</code> allows easy extension and customization.</li>
</ul>
</li>
<li><p><strong>Error Handling</strong>:</p>
<ul>
<li><p>Logs errors without interrupting the workflow.</p>
</li>
<li><p>Defaults to returning the unprocessed message on failure.</p>
</li>
</ul>
</li>
</ol>
<h3 id="heading-making-routes-for-crud-operation">Making Routes for CRUD Operation</h3>
<p>So far, we've covered how to integrate CopilotKit into the backend. Now, we need to handle file operations, so we'll create another route to manage files with the database.</p>
<p>To develop the backend for file handling, I'll create a new folder inside the API folder and name it <code>files</code>. Inside the <code>files</code> folder, I’ll create a simple <code>route.js</code> file. Here’s the code I’ll be using inside the file:</p>
<ul>
<li><p><code>app/api/files/route.tsx</code></p>
</li>
<li><pre><code class="lang-javascript">
  <span class="hljs-keyword">import</span> { NextResponse } <span class="hljs-keyword">from</span> <span class="hljs-string">"next/server"</span>;
  <span class="hljs-keyword">import</span> mongoose <span class="hljs-keyword">from</span> <span class="hljs-string">"mongoose"</span>;
  <span class="hljs-keyword">import</span> { connectDB, File } <span class="hljs-keyword">from</span> <span class="hljs-string">"@/app/lib/mongodb"</span>;

  <span class="hljs-comment">// Type for the request body</span>
  interface FileRequestBody {
    id?: string;
    name?: string;
    content?: string;
  }interface FileCreateRequest {
    <span class="hljs-attr">name</span>: string;
    content: string;
  }

  interface FileUpdateRequest {
    <span class="hljs-attr">id</span>: string;
    name?: string;
    content?: string;
  }

  <span class="hljs-comment">// Fetch all files (GET /api/files)</span>
  <span class="hljs-keyword">export</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">GET</span>(<span class="hljs-params"></span>): <span class="hljs-title">Promise</span>&lt;<span class="hljs-title">Response</span>&gt; </span>{
  <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">await</span> connectDB(); <span class="hljs-comment">// Ensure DB connection</span>
      <span class="hljs-keyword">const</span> files = <span class="hljs-keyword">await</span> File.find({});
      <span class="hljs-keyword">return</span> NextResponse.json(files, { <span class="hljs-attr">status</span>: <span class="hljs-number">200</span> });
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-keyword">return</span> NextResponse.json(
        { <span class="hljs-attr">error</span>: <span class="hljs-string">"Failed to fetch files"</span> },
        { <span class="hljs-attr">status</span>: <span class="hljs-number">500</span> }
      );
    }
  }

  <span class="hljs-comment">// Create a new file (POST /api/files)</span>
  <span class="hljs-keyword">export</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">POST</span>(<span class="hljs-params">req: Request</span>): <span class="hljs-title">Promise</span>&lt;<span class="hljs-title">Response</span>&gt; </span>{
  <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">await</span> connectDB(); <span class="hljs-comment">// Ensure DB connection is successful</span>
      <span class="hljs-comment">// Parse the request body</span>
      <span class="hljs-keyword">const</span> { name, content }: FileRequestBody = <span class="hljs-keyword">await</span> req.json();
      <span class="hljs-keyword">if</span> (!name || !content) {
        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Missing required fields: name or content"</span>);
      }

      <span class="hljs-comment">// Log the incoming data for debugging</span>
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Creating file with data:"</span>, { name, content });

      <span class="hljs-comment">// Create a new file in the database</span>
      <span class="hljs-keyword">const</span> newFile = <span class="hljs-keyword">new</span> File({ name, content });
      <span class="hljs-keyword">await</span> newFile.save();

      <span class="hljs-comment">// Return the newly created file</span>
      <span class="hljs-keyword">return</span> NextResponse.json(newFile, { <span class="hljs-attr">status</span>: <span class="hljs-number">201</span> });
    } <span class="hljs-keyword">catch</span> (error: any) {
      <span class="hljs-comment">// Log the error for debugging</span>
      <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Error creating file:"</span>, error);

      <span class="hljs-keyword">return</span> NextResponse.json(
        { <span class="hljs-attr">error</span>: <span class="hljs-string">"Failed to create file"</span>, <span class="hljs-attr">message</span>: error.message },
        { <span class="hljs-attr">status</span>: <span class="hljs-number">400</span> }
      );
    }
  }

  <span class="hljs-comment">// Update file content (PUT /api/files)</span>
  <span class="hljs-keyword">export</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">PUT</span>(<span class="hljs-params">req: Request</span>): <span class="hljs-title">Promise</span>&lt;<span class="hljs-title">Response</span>&gt; </span>{
  <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">await</span> connectDB(); <span class="hljs-comment">// Ensure DB connection</span>
      <span class="hljs-keyword">const</span> { id, name, content }: FileRequestBody = <span class="hljs-keyword">await</span> req.json();

      <span class="hljs-comment">// Validate ID format</span>
      <span class="hljs-keyword">if</span> (!id || !mongoose.Types.ObjectId.isValid(id)) {
        <span class="hljs-keyword">return</span> NextResponse.json({ <span class="hljs-attr">error</span>: <span class="hljs-string">"Invalid file ID"</span> }, { <span class="hljs-attr">status</span>: <span class="hljs-number">400</span> });
      }

      <span class="hljs-comment">// Update file name or content if provided</span>
      <span class="hljs-keyword">const</span> updatedFile = <span class="hljs-keyword">await</span> File.findByIdAndUpdate(
        id,
        { ...(name &amp;&amp; { name }), ...(content &amp;&amp; { content }) },
        { <span class="hljs-attr">new</span>: <span class="hljs-literal">true</span> }
      );

      <span class="hljs-keyword">if</span> (!updatedFile) {
        <span class="hljs-keyword">return</span> NextResponse.json({ <span class="hljs-attr">error</span>: <span class="hljs-string">"File not found"</span> }, { <span class="hljs-attr">status</span>: <span class="hljs-number">404</span> });
      }

      <span class="hljs-keyword">return</span> NextResponse.json(updatedFile, { <span class="hljs-attr">status</span>: <span class="hljs-number">200</span> });
    } <span class="hljs-keyword">catch</span> (error: any) {
      <span class="hljs-keyword">return</span> NextResponse.json(
        { <span class="hljs-attr">error</span>: <span class="hljs-string">"Failed to update file"</span> },
        { <span class="hljs-attr">status</span>: <span class="hljs-number">400</span> }
      );
    }
  }

  <span class="hljs-comment">// Delete a file (DELETE /api/files)</span>
  <span class="hljs-keyword">export</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">DELETE</span>(<span class="hljs-params">req: Request</span>): <span class="hljs-title">Promise</span>&lt;<span class="hljs-title">Response</span>&gt; </span>{
  <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">await</span> connectDB(); <span class="hljs-comment">// Ensure DB connection</span>
      <span class="hljs-keyword">const</span> { id }: FileRequestBody = <span class="hljs-keyword">await</span> req.json();

      <span class="hljs-comment">// Validate ID format</span>
      <span class="hljs-keyword">if</span> (!id || !mongoose.Types.ObjectId.isValid(id)) {
        <span class="hljs-keyword">return</span> NextResponse.json({ <span class="hljs-attr">error</span>: <span class="hljs-string">"Invalid file ID"</span> }, { <span class="hljs-attr">status</span>: <span class="hljs-number">400</span> });
      }

      <span class="hljs-keyword">await</span> File.findByIdAndDelete(id);
      <span class="hljs-keyword">return</span> NextResponse.json(
        { <span class="hljs-attr">message</span>: <span class="hljs-string">"File deleted successfully"</span> },
        { <span class="hljs-attr">status</span>: <span class="hljs-number">200</span> }
      );
    } <span class="hljs-keyword">catch</span> (error: any) {
      <span class="hljs-keyword">return</span> NextResponse.json(
        { <span class="hljs-attr">error</span>: <span class="hljs-string">"Failed to delete file"</span> },
        { <span class="hljs-attr">status</span>: <span class="hljs-number">400</span> }
      );
    }
  }
</code></pre>
</li>
</ul>
<h3 id="heading-code-explanation"><strong>Code explanation</strong> :</h3>
<p>This code defines API routes for handling CRUD operations (Create, Read, Update, Delete) on a MongoDB collection called <code>File</code> in a Next.js application. Each route is connected to MongoDB using Mongoose and we used <code>NextResponse</code> to format the responses.</p>
<h3 id="heading-code-breakdown">Code Breakdown</h3>
<h4 id="heading-1-imports">1. <strong>Imports</strong></h4>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { NextResponse } <span class="hljs-keyword">from</span> <span class="hljs-string">"next/server"</span>;
<span class="hljs-keyword">import</span> mongoose <span class="hljs-keyword">from</span> <span class="hljs-string">"mongoose"</span>;
<span class="hljs-keyword">import</span> connectDB <span class="hljs-keyword">from</span> <span class="hljs-string">"@/app/lib/mongodb"</span>; <span class="hljs-comment">//we made this file</span>
<span class="hljs-keyword">import</span> File <span class="hljs-keyword">from</span> <span class="hljs-string">"@/app/lib/models/File"</span>; <span class="hljs-comment">//we made this file</span>
</code></pre>
<ul>
<li><p><code>NextResponse</code>: Used for creating HTTP responses in Next.js API routes.</p>
</li>
<li><p><code>connectDB</code>: Connects to the MongoDB database.</p>
</li>
<li><p><code>File</code>: A Mongoose model representing the <code>File</code> collection.</p>
</li>
</ul>
<h4 id="heading-2-fetch-all-files-get">2. <strong>Fetch All Files (GET)</strong></h4>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">GET</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">await</span> connectDB(); <span class="hljs-comment">// Ensure DB connection</span>
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> files = <span class="hljs-keyword">await</span> File.find({}); <span class="hljs-comment">// Fetch all files</span>
    <span class="hljs-keyword">return</span> NextResponse.json(files, { <span class="hljs-attr">status</span>: <span class="hljs-number">200</span> }); <span class="hljs-comment">// Return files in JSON format</span>
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-keyword">return</span> NextResponse.json(
      { <span class="hljs-attr">error</span>: <span class="hljs-string">"Failed to fetch files"</span> },
      { <span class="hljs-attr">status</span>: <span class="hljs-number">500</span> }
    );
  }
}
</code></pre>
<ul>
<li><p><strong>Purpose</strong>: Retrieves all documents in the <code>File</code> collection.</p>
</li>
<li><p><strong>Flow</strong>:</p>
<ol>
<li><p>Connects to MongoDB.</p>
</li>
<li><p>Uses <code>File.find({})</code> to fetch all files.</p>
</li>
<li><p>Returns the files with a <code>200</code> status or an error with a <code>500</code> status.</p>
</li>
</ol>
</li>
</ul>
<h4 id="heading-3-create-a-new-file-post">3. <strong>Create a New File (POST)</strong></h4>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">POST</span>(<span class="hljs-params">req</span>) </span>{
  <span class="hljs-keyword">await</span> connectDB(); <span class="hljs-comment">// Ensure DB connection</span>

  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> { name, content } = <span class="hljs-keyword">await</span> req.json(); <span class="hljs-comment">// Parse the request body</span>
    <span class="hljs-keyword">if</span> (!name || !content) {
      <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Missing required fields: name or content"</span>);
    }

    <span class="hljs-keyword">const</span> newFile = <span class="hljs-keyword">new</span> File({ name, content }); <span class="hljs-comment">// Create new file</span>
    <span class="hljs-keyword">await</span> newFile.save(); <span class="hljs-comment">// Save to MongoDB</span>

    <span class="hljs-keyword">return</span> NextResponse.json(newFile, { <span class="hljs-attr">status</span>: <span class="hljs-number">201</span> }); <span class="hljs-comment">// Return the new file</span>
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-keyword">return</span> NextResponse.json(
      { <span class="hljs-attr">error</span>: <span class="hljs-string">"Failed to create file"</span>, <span class="hljs-attr">message</span>: error.message },
      { <span class="hljs-attr">status</span>: <span class="hljs-number">400</span> }
    );
  }
}
</code></pre>
<ul>
<li><p><strong>Purpose</strong>: Creates a new document in the <code>File</code> collection.</p>
</li>
<li><p><strong>Flow</strong>:</p>
<ol>
<li><p>Parses the <code>name</code> and <code>content</code> fields from the request body.</p>
</li>
<li><p>Validates the required fields.</p>
</li>
<li><p>Creates and save the file in MongoDB.</p>
</li>
<li><p>Returns the new file with a <code>201</code> status or an error with a <code>400</code> status.</p>
</li>
</ol>
</li>
</ul>
<h4 id="heading-4-update-a-file-put">4. <strong>Update a File (PUT)</strong></h4>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">PUT</span>(<span class="hljs-params">req</span>) </span>{
  <span class="hljs-keyword">await</span> connectDB(); <span class="hljs-comment">// Ensure DB connection</span>
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> { id, name, content } = <span class="hljs-keyword">await</span> req.json();

    <span class="hljs-keyword">if</span> (!mongoose.Types.ObjectId.isValid(id)) {
      <span class="hljs-keyword">return</span> NextResponse.json({ <span class="hljs-attr">error</span>: <span class="hljs-string">"Invalid file ID"</span> }, { <span class="hljs-attr">status</span>: <span class="hljs-number">400</span> });
    }

    <span class="hljs-keyword">const</span> updatedFile = <span class="hljs-keyword">await</span> File.findByIdAndUpdate(
      id,
      { ...(name &amp;&amp; { name }), ...(content &amp;&amp; { content }) },
      { <span class="hljs-attr">new</span>: <span class="hljs-literal">true</span> }
    );

    <span class="hljs-keyword">if</span> (!updatedFile) {
      <span class="hljs-keyword">return</span> NextResponse.json({ <span class="hljs-attr">error</span>: <span class="hljs-string">"File not found"</span> }, { <span class="hljs-attr">status</span>: <span class="hljs-number">404</span> });
    }

    <span class="hljs-keyword">return</span> NextResponse.json(updatedFile, { <span class="hljs-attr">status</span>: <span class="hljs-number">200</span> });
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-keyword">return</span> NextResponse.json(
      { <span class="hljs-attr">error</span>: <span class="hljs-string">"Failed to update file"</span> },
      { <span class="hljs-attr">status</span>: <span class="hljs-number">400</span> }
    );
  }
}
</code></pre>
<ul>
<li><p><strong>Purpose</strong>: Updates an existing document in the <code>File</code> collection.</p>
</li>
<li><p><strong>Flow</strong>:</p>
<ol>
<li><p>Parses the <code>id</code>, <code>name</code>, and <code>content</code> from the request body.</p>
</li>
<li><p>Validates the <code>id</code> using Mongoose's <code>ObjectId</code>.</p>
</li>
<li><p>Updates the document using <code>File.findByIdAndUpdate()</code> (updates only provided fields).</p>
</li>
<li><p>Returns the updated document with a <code>200</code> status, or an error with <code>400</code> or <code>404</code>.</p>
</li>
</ol>
</li>
</ul>
<h4 id="heading-5-delete-a-file-delete">5. <strong>Delete a File (DELETE)</strong></h4>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">DELETE</span>(<span class="hljs-params">req</span>) </span>{
  <span class="hljs-keyword">await</span> connectDB(); <span class="hljs-comment">// Ensure DB connection</span>
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> { id } = <span class="hljs-keyword">await</span> req.json();

    <span class="hljs-keyword">if</span> (!mongoose.Types.ObjectId.isValid(id)) {
      <span class="hljs-keyword">return</span> NextResponse.json({ <span class="hljs-attr">error</span>: <span class="hljs-string">"Invalid file ID"</span> }, { <span class="hljs-attr">status</span>: <span class="hljs-number">400</span> });
    }

    <span class="hljs-keyword">await</span> File.findByIdAndDelete(id); <span class="hljs-comment">// Delete the document</span>
    <span class="hljs-keyword">return</span> NextResponse.json(
      { <span class="hljs-attr">message</span>: <span class="hljs-string">"File deleted successfully"</span> },
      { <span class="hljs-attr">status</span>: <span class="hljs-number">200</span> }
    );
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-keyword">return</span> NextResponse.json(
      { <span class="hljs-attr">error</span>: <span class="hljs-string">"Failed to delete file"</span> },
      { <span class="hljs-attr">status</span>: <span class="hljs-number">400</span> }
    );
  }
}
</code></pre>
<ul>
<li><p><strong>Purpose</strong>: Deletes a document from the <code>File</code> collection.</p>
</li>
<li><p><strong>Flow</strong>:</p>
<ol>
<li><p>Parses the <code>id</code> from the request body.</p>
</li>
<li><p>Validates the <code>id</code> format.</p>
</li>
<li><p>Uses <code>File.findByIdAndDelete()</code> to remove the document.</p>
</li>
<li><p>Returns a success message with a <code>200</code> status or an error with <code>400</code>.</p>
</li>
</ol>
</li>
</ul>
<h3 id="heading-example-api-requests-how-to-test-api-in-local">Example API Requests: How to test API in local</h3>
<ol>
<li><p><strong>GET All Files</strong></p>
<pre><code class="lang-bash"> curl -X GET http://localhost:3000/api/files
</code></pre>
</li>
<li><p><strong>Create a File (POST)</strong></p>
<pre><code class="lang-bash"> curl -X POST http://localhost:3000/api/files \
 -H <span class="hljs-string">"Content-Type: application/json"</span> \
 -d <span class="hljs-string">'{"name": "example.txt", "content": "This is a test file"}'</span>
</code></pre>
</li>
<li><p><strong>Update a File (PUT)</strong></p>
<pre><code class="lang-bash"> curl -X PUT http://localhost:3000/api/files \
 -H <span class="hljs-string">"Content-Type: application/json"</span> \
 -d <span class="hljs-string">'{"id": "64ffab67c728f51234567890", "name": "updated.txt", "content": "Updated content"}'</span>
</code></pre>
</li>
<li><p><strong>Delete a File (DELETE)</strong></p>
<pre><code class="lang-bash"> curl -X DELETE http://localhost:3000/api/files \
 -H <span class="hljs-string">"Content-Type: application/json"</span> \
 -d <span class="hljs-string">'{"id": "64ffab67c728f51234567890"}'</span>
</code></pre>
</li>
</ol>
<h3 id="heading-creating-mongodb-schemas">Creating MongoDB Schemas</h3>
<p>Now, create a <code>lib</code> folder inside the <code>app</code> folder. This <code>lib</code> folder will handle essential database tasks, such as database schema and connectivity. Inside the <code>lib</code> folder, create another folder named <code>models</code>. Within this <code>models</code> folder, create a new file called <code>File.js</code> and paste the following code into it.</p>
<p>This version simplifies the instructions and improves clarity while maintaining the original meaning.</p>
<pre><code class="lang-typescript">
<span class="hljs-keyword">import</span> mongoose, { Schema, Document, Model } <span class="hljs-keyword">from</span> <span class="hljs-string">"mongoose"</span>;

<span class="hljs-comment">// Define an interface for the file document</span>
<span class="hljs-keyword">interface</span> IFile <span class="hljs-keyword">extends</span> Document {
  name: <span class="hljs-built_in">string</span>;
  content: <span class="hljs-built_in">string</span>;
  createdAt: <span class="hljs-built_in">Date</span>;
  updatedAt: <span class="hljs-built_in">Date</span>;
}

<span class="hljs-comment">// Define the schema for the file model</span>
<span class="hljs-keyword">const</span> fileSchema = <span class="hljs-keyword">new</span> Schema&lt;IFile&gt;(
  {
    _id: { <span class="hljs-keyword">type</span>: Schema.Types.ObjectId, auto: <span class="hljs-literal">true</span> }, <span class="hljs-comment">// MongoDB default _id</span>
    name: { <span class="hljs-keyword">type</span>: <span class="hljs-built_in">String</span>, required: <span class="hljs-literal">true</span> }, <span class="hljs-comment">// Removed unique constraint</span>
    content: { <span class="hljs-keyword">type</span>: <span class="hljs-built_in">String</span>, required: <span class="hljs-literal">true</span> },
  },
  { timestamps: <span class="hljs-literal">true</span> } <span class="hljs-comment">// Automatically adds createdAt &amp; updatedAt</span>
);

<span class="hljs-comment">// Export the File model with type safety</span>
<span class="hljs-keyword">const</span> File: Model&lt;IFile&gt; =
  mongoose.models.File || mongoose.model&lt;IFile&gt;(<span class="hljs-string">"File"</span>, fileSchema);

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> File;
</code></pre>
<h3 id="heading-code-explanation-1">Code Explanation</h3>
<p>This code defines a Mongoose schema and model for a <code>File</code> collection in a MongoDB database. It specifies the structure and rules for documents in the collection.</p>
<p>This code defines a Mongoose schema and model for a File document in MongoDB. Here's a brief explanation:</p>
<h3 id="heading-key-components-1"><strong>Key Components</strong>:</h3>
<ol>
<li><p><strong>Interface (</strong><code>IFile</code>):</p>
<ul>
<li><p>Defines the structure of a <code>File</code> document with:</p>
<ul>
<li><p><code>name</code> (string, required).</p>
</li>
<li><p><code>content</code> (string, required).</p>
</li>
<li><p><code>createdAt</code> and <code>updatedAt</code> (automatically managed by Mongoose).</p>
</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>Schema (</strong><code>fileSchema</code>):</p>
<ul>
<li><p>Maps the <code>IFile</code> interface to a MongoDB schema.</p>
</li>
<li><p>Includes:</p>
<ul>
<li><p><code>_id</code>: Auto-generated MongoDB ObjectId.</p>
</li>
<li><p><code>name</code> and <code>content</code>: Required fields.</p>
</li>
<li><p><code>timestamps: true</code>: Automatically adds <code>createdAt</code> and <code>updatedAt</code> fields.</p>
</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>Model (</strong><code>File</code>):</p>
<ul>
<li><p>Creates or retrieves the Mongoose model for the <code>File</code> collection.</p>
</li>
<li><p>Ensures type safety using the <code>IFile</code> interface.</p>
</li>
</ul>
</li>
</ol>
<h3 id="heading-connecting-to-database">Connecting to database</h3>
<p>Half of the work is done! Now, it’s time to connect our app to the database. To do this, I’ll create a new file inside the <code>lib</code> folder, where we previously created the database schema. I’ll name the file <code>mongodb.tsx</code> and paste the following code inside it:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> mongoose, { Schema, Model, Connection } <span class="hljs-keyword">from</span> <span class="hljs-string">"mongoose"</span>;
<span class="hljs-keyword">import</span> { IFile } <span class="hljs-keyword">from</span> <span class="hljs-string">"../types"</span>;

<span class="hljs-comment">// Define mongoose connection URI</span>
<span class="hljs-keyword">const</span> MONGODB_URI = process.env.MONGODB_URI;

<span class="hljs-keyword">if</span> (!MONGODB_URI) {
  <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(
    <span class="hljs-string">"Please define the MONGODB_URI environment variable inside .env.local"</span>
  );
}

<span class="hljs-keyword">let</span> cached: {
  conn: Connection | <span class="hljs-literal">null</span>;
  promise: <span class="hljs-built_in">Promise</span>&lt;Connection&gt; | <span class="hljs-literal">null</span>;
} = { conn: <span class="hljs-literal">null</span>, promise: <span class="hljs-literal">null</span> };

<span class="hljs-keyword">export</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">connectDB</span>(<span class="hljs-params"></span>): <span class="hljs-title">Promise</span>&lt;<span class="hljs-title">Connection</span>&gt; </span>{
  <span class="hljs-keyword">if</span> (cached.conn) {
    <span class="hljs-keyword">return</span> cached.conn;
  }

  <span class="hljs-keyword">if</span> (!cached.promise) {
    cached.promise = mongoose.connect(MONGODB_URI!).then(<span class="hljs-function">(<span class="hljs-params">mongoose</span>) =&gt;</span> {
      <span class="hljs-keyword">return</span> mongoose.connection;
    });
  }

  <span class="hljs-keyword">try</span> {
    cached.conn = <span class="hljs-keyword">await</span> cached.promise;
  } <span class="hljs-keyword">catch</span> (e) {
    cached.promise = <span class="hljs-literal">null</span>;
    <span class="hljs-keyword">throw</span> e;
  }

  <span class="hljs-keyword">return</span> cached.conn;
}

<span class="hljs-comment">// Define the schema for the file model</span>
<span class="hljs-keyword">const</span> fileSchema = <span class="hljs-keyword">new</span> Schema&lt;IFile&gt;(
  {
    name: { <span class="hljs-keyword">type</span>: <span class="hljs-built_in">String</span>, required: <span class="hljs-literal">true</span> },
    content: { <span class="hljs-keyword">type</span>: <span class="hljs-built_in">String</span>, required: <span class="hljs-literal">true</span> },
  },
  {
    timestamps: <span class="hljs-literal">true</span>,
  }
);

<span class="hljs-comment">// Export the File model with type safety</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> File = (mongoose.models.File ||
mongoose.model&lt;IFile&gt;(<span class="hljs-string">"File"</span>, fileSchema)) <span class="hljs-keyword">as</span> Model&lt;IFile&gt;;
</code></pre>
<h3 id="heading-code-explanation-2">Code Explanation</h3>
<p>This code sets up a MongoDB connection using the <code>mongoose</code> library in a Node.js or Next.js application. It ensures that the database is connected efficiently and prevents redundant connections.</p>
<p>This code sets up a MongoDB connection and defines a Mongoose schema and model for a <code>File</code> document. Here's a brief explanation:</p>
<h3 id="heading-key-components-2"><strong>Key Components</strong>:</h3>
<ol>
<li><p><strong>MongoDB Connection</strong>:</p>
<ul>
<li><p>Uses the <code>MONGODB_URI</code> environment variable to connect to MongoDB.</p>
</li>
<li><p>Implements a caching mechanism to reuse the connection and avoid multiple connections.</p>
</li>
<li><p>Throws an error if <code>MONGODB_URI</code> is not defined.</p>
</li>
</ul>
</li>
<li><p><strong>Schema (</strong><code>fileSchema</code>):</p>
<ul>
<li><p>Defines the structure of a <code>File</code> document with:</p>
<ul>
<li><p><code>name</code> (string, required).</p>
</li>
<li><p><code>content</code> (string, required).</p>
</li>
</ul>
</li>
<li><p>Automatically adds <code>createdAt</code> and <code>updatedAt</code> timestamps.</p>
</li>
</ul>
</li>
<li><p><strong>Model (</strong><code>File</code>):</p>
<ul>
<li><p>Creates or retrieves the Mongoose model for the <code>File</code> collection.</p>
</li>
<li><p>Ensures type safety using the <code>IFile</code> interface.</p>
</li>
</ul>
</li>
</ol>
<h4 id="heading-example-directory-structure">Example Directory Structure:</h4>
<pre><code class="lang-javascript">/project
  /pages
    /api
      test.js
  /utils
    connectDB.js
  .env.local
</code></pre>
<h3 id="heading-final-notes">Final Notes:</h3>
<ul>
<li><p>This code avoids multiple MongoDB connections by checking the <code>readyState</code>.</p>
</li>
<li><p>It's reusable and modular, making it easy to maintain.</p>
</li>
<li><p>Always secure the <code>MONGODB_URI</code> in-environment variables to avoid exposing sensitive credentials.</p>
</li>
</ul>
<h3 id="heading-ensuring-type-safety">Ensuring type safety</h3>
<p>Since we are using TypeScript, we will have to declare the file type <code>files</code> , <code>socket</code> and an <code>index</code>. To do so, create a new folder in root directory of the project and name it <code>types</code> and make three files <code>socket.ts</code> ,<code>files.ts</code> and <code>index.ts</code> inside the folder. Inside each file, paste the given code for their respective file.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">//index.ts</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">interface</span> IFile {
  _id: <span class="hljs-built_in">string</span>;
  name: <span class="hljs-built_in">string</span>;
  content: <span class="hljs-built_in">string</span>;
  createdAt?: <span class="hljs-built_in">Date</span>;
  updatedAt?: <span class="hljs-built_in">Date</span>;
}
<span class="hljs-comment">//socket.ts</span>
<span class="hljs-keyword">import</span> { FileData } <span class="hljs-keyword">from</span> <span class="hljs-string">'../types/file'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">interface</span> ServerToClientEvents {
<span class="hljs-string">"new-file"</span>: <span class="hljs-function">(<span class="hljs-params">file: FileData</span>) =&gt;</span> <span class="hljs-built_in">void</span>;
<span class="hljs-string">"delete-file"</span>: <span class="hljs-function">(<span class="hljs-params">fileId: <span class="hljs-built_in">string</span></span>) =&gt;</span> <span class="hljs-built_in">void</span>;
<span class="hljs-string">"file-update"</span>: <span class="hljs-function">(<span class="hljs-params">data: { fileId: <span class="hljs-built_in">string</span>; content: <span class="hljs-built_in">string</span> }</span>) =&gt;</span> <span class="hljs-built_in">void</span>;
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">interface</span> ClientToServerEvents {
<span class="hljs-string">"new-file"</span>: <span class="hljs-function">(<span class="hljs-params">file: FileData</span>) =&gt;</span> <span class="hljs-built_in">void</span>;
<span class="hljs-string">"delete-file"</span>: <span class="hljs-function">(<span class="hljs-params">fileId: <span class="hljs-built_in">string</span></span>) =&gt;</span> <span class="hljs-built_in">void</span>;
<span class="hljs-string">"file-update"</span>: <span class="hljs-function">(<span class="hljs-params">data: { fileId: <span class="hljs-built_in">string</span>; content: <span class="hljs-built_in">string</span> }</span>) =&gt;</span> <span class="hljs-built_in">void</span>;
}
<span class="hljs-comment">//file.ts</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">interface</span> FileData {
_id: <span class="hljs-built_in">string</span>;
name: <span class="hljs-built_in">string</span>;
content: <span class="hljs-built_in">string</span>;
}
</code></pre>
<h2 id="heading-how-to-build-the-front-end"><strong>How to Build the Front End</strong></h2>
<p>For the front end, we’ll keep it simple, aiming for a UI that closely resembles Replit. The key components we need for this project are a File Explorer, Monaco Editor, and Sandbox component.</p>
<ul>
<li><p><strong>File Explorer</strong>: This component will display and manage the code files, positioned on the left side of the screen.</p>
</li>
<li><p><strong>Monaco Editor</strong>: This component will allow users to view and edit the content of the code files.</p>
</li>
<li><p><strong>Sandbox</strong>: This component will render the live preview of the content inside the code files.</p>
</li>
</ul>
<p>To build these components, we won’t use any third-party UI libraries; instead, we’ll rely solely on TailwindCSS, which is pre-configured with Next.js.</p>
<p>Now, let’s build the components:</p>
<ol>
<li><p>Open your VS Code.</p>
</li>
<li><p>Open the Next.js folder where you created your project.</p>
<p> Since I work without a <code>src</code> folder, you’ll find only an <code>app</code> folder. Inside the <code>app</code> folder, create a new folder called components.</p>
</li>
</ol>
<ul>
<li><p>After creating the folder, your project structure should look something like this:</p>
</li>
<li><p><strong>FileExplorer.js -</strong>This is our file explorer</p>
</li>
<li><p><strong>ScreenOne.js-</strong> This is our Monaco editor</p>
</li>
<li><p><strong>LivePreview.js-</strong> This is our sandbox component</p>
</li>
</ul>
<p>Let’s see how I build these components and you can too,</p>
<h3 id="heading-fileexploertsx">FileExploer.tsx</h3>
<p>The <code>FileExplorer</code> is a React component that displays a list of files fetched from a backend (MongoDB) and allows users to select, create, edit, and delete files. It uses React Hooks for state management and lifecycle effects, Tailwind CSS for styling, and <code>lucide-react</code> icons for UI actions.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> React, { useEffect, useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { Plus, Trash2, Pencil } <span class="hljs-keyword">from</span> <span class="hljs-string">"lucide-react"</span>;
<span class="hljs-keyword">import</span> io, { Socket } <span class="hljs-keyword">from</span> <span class="hljs-string">"socket.io-client"</span>;
<span class="hljs-keyword">import</span> { FileData } <span class="hljs-keyword">from</span> <span class="hljs-string">'../types/file'</span>;

<span class="hljs-keyword">interface</span> FileExplorerProps {
files: FileData[];
onFileSelect: <span class="hljs-function">(<span class="hljs-params">file: FileData</span>) =&gt;</span> <span class="hljs-built_in">void</span>;
currentFile: FileData | <span class="hljs-literal">null</span>;
}

<span class="hljs-keyword">const</span> FileExplorer: React.FC&lt;FileExplorerProps&gt; = <span class="hljs-function">(<span class="hljs-params">{
files: initialFiles,
onFileSelect,
currentFile,
}</span>) =&gt;</span> {
<span class="hljs-keyword">const</span> [files, setFiles] = useState&lt;FileData[]&gt;(initialFiles);
  <span class="hljs-keyword">const</span> [socket, setSocket] = useState&lt;Socket | <span class="hljs-literal">null</span>&gt;(<span class="hljs-literal">null</span>);
  <span class="hljs-keyword">const</span> [loading, setLoading] = useState&lt;<span class="hljs-built_in">boolean</span>&gt;(<span class="hljs-literal">true</span>);
  <span class="hljs-keyword">const</span> [error, setError] = useState&lt;<span class="hljs-built_in">string</span> | <span class="hljs-literal">null</span>&gt;(<span class="hljs-literal">null</span>);
  <span class="hljs-keyword">const</span> [newFileName, setNewFileName] = useState&lt;<span class="hljs-built_in">string</span>&gt;(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [editingFile, setEditingFile] = useState&lt;<span class="hljs-built_in">string</span> | <span class="hljs-literal">null</span>&gt;(<span class="hljs-literal">null</span>);
  <span class="hljs-keyword">const</span> [editedFileName, setEditedFileName] = useState&lt;<span class="hljs-built_in">string</span>&gt;(<span class="hljs-string">""</span>);

  <span class="hljs-comment">// Initialize socket connection</span>
  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> socketInstance = io(<span class="hljs-string">"http://localhost:3000"</span>, {
      reconnection: <span class="hljs-literal">true</span>,
      reconnectionAttempts: <span class="hljs-number">5</span>,
      reconnectionDelay: <span class="hljs-number">1000</span>,
    });

    socketInstance.on(<span class="hljs-string">"connect"</span>, <span class="hljs-function">() =&gt;</span> {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Connected to Socket.IO server"</span>);
    });

    socketInstance.on(<span class="hljs-string">"connect_error"</span>, <span class="hljs-function">(<span class="hljs-params">error</span>) =&gt;</span> {
      <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Socket connection error:"</span>, error);
    });

    socketInstance.on(<span class="hljs-string">"disconnect"</span>, <span class="hljs-function">() =&gt;</span> {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Disconnected from Socket.IO server"</span>);
    });

    setSocket(socketInstance);

    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
      <span class="hljs-keyword">if</span> (socketInstance) {
        socketInstance.disconnect();
      }
    };
  }, []);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">if</span> (!socket) <span class="hljs-keyword">return</span>;

    <span class="hljs-comment">// Listen for real-time updates</span>
    socket.on(<span class="hljs-string">"new-file"</span>, <span class="hljs-function">(<span class="hljs-params">newFile: FileData</span>) =&gt;</span> {
      setFiles(<span class="hljs-function">(<span class="hljs-params">prevFiles</span>) =&gt;</span> {
        <span class="hljs-keyword">if</span> (!prevFiles.some(<span class="hljs-function">(<span class="hljs-params">file</span>) =&gt;</span> file._id === newFile._id)) {
          <span class="hljs-keyword">return</span> [...prevFiles, newFile];
        }
        <span class="hljs-keyword">return</span> prevFiles;
      });
    });

    socket.on(<span class="hljs-string">"delete-file"</span>, <span class="hljs-function">(<span class="hljs-params">fileId: <span class="hljs-built_in">string</span></span>) =&gt;</span> {
      setFiles(<span class="hljs-function">(<span class="hljs-params">prevFiles</span>) =&gt;</span> prevFiles.filter(<span class="hljs-function">(<span class="hljs-params">file</span>) =&gt;</span> file._id !== fileId));
    });

    socket.on(<span class="hljs-string">"update-file"</span>, <span class="hljs-function">(<span class="hljs-params">updatedFile: FileData</span>) =&gt;</span> {
      setFiles(<span class="hljs-function">(<span class="hljs-params">prevFiles</span>) =&gt;</span>
        prevFiles.map(<span class="hljs-function">(<span class="hljs-params">file</span>) =&gt;</span>
          file._id === updatedFile._id
            ? { ...file, name: updatedFile.name }
            : file
        )
      );
    });

    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
      socket.off(<span class="hljs-string">"new-file"</span>);
      socket.off(<span class="hljs-string">"delete-file"</span>);
      socket.off(<span class="hljs-string">"update-file"</span>);
    };
  }, [socket]);

  <span class="hljs-comment">// Fetch initial files</span>
  <span class="hljs-keyword">const</span> fetchFiles = <span class="hljs-keyword">async</span> () =&gt; {
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">"/api/files"</span>);
      <span class="hljs-keyword">if</span> (!response.ok) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Failed to fetch files"</span>);
    <span class="hljs-keyword">const</span> data: FileData[] = <span class="hljs-keyword">await</span> response.json();
      setFiles(data);
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Error fetching files:"</span>, error);
      setError(<span class="hljs-string">"Failed to load files"</span>);
    } <span class="hljs-keyword">finally</span> {
      setLoading(<span class="hljs-literal">false</span>);
    }
  };

  useEffect(<span class="hljs-function">() =&gt;</span> {
    fetchFiles();
  }, []);

  <span class="hljs-comment">// Create new file</span>
  <span class="hljs-keyword">const</span> createNewFile = <span class="hljs-keyword">async</span> () =&gt; {
    <span class="hljs-keyword">if</span> (!newFileName.trim()) <span class="hljs-keyword">return</span>;
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">"/api/files"</span>, {
        method: <span class="hljs-string">"POST"</span>,
        headers: { <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"application/json"</span> },
        body: <span class="hljs-built_in">JSON</span>.stringify({ name: newFileName }),
      });

      <span class="hljs-keyword">if</span> (!response.ok) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Failed to create file"</span>);

    <span class="hljs-keyword">const</span> newFile: FileData = <span class="hljs-keyword">await</span> response.json();
      socket?.emit(<span class="hljs-string">"new-file"</span>, newFile);
      setNewFileName(<span class="hljs-string">""</span>);
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Error creating file:"</span>, error);
    }
  };

  <span class="hljs-keyword">const</span> handleDeleteFile = <span class="hljs-keyword">async</span> (e: React.MouseEvent, id: <span class="hljs-built_in">string</span>) =&gt; {
    e.stopPropagation();
    setFiles(<span class="hljs-function">(<span class="hljs-params">prevFiles</span>) =&gt;</span> prevFiles.filter(<span class="hljs-function">(<span class="hljs-params">file</span>) =&gt;</span> file._id !== id)); <span class="hljs-comment">// Optimistic update</span>

    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">"/api/files"</span>, {
        method: <span class="hljs-string">"DELETE"</span>,
        headers: { <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"application/json"</span> },
        body: <span class="hljs-built_in">JSON</span>.stringify({ id }),
      });

      <span class="hljs-keyword">if</span> (!response.ok) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Failed to delete file"</span>);

      socket?.emit(<span class="hljs-string">"delete-file"</span>, id);
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Error deleting file:"</span>, error);
      <span class="hljs-keyword">await</span> fetchFiles(); <span class="hljs-comment">// Revert state if API call fails</span>
    }
  };

<span class="hljs-keyword">const</span> handleEditStart = <span class="hljs-function">(<span class="hljs-params">e: React.MouseEvent, file: FileData</span>) =&gt;</span> {
    e.stopPropagation();
    setEditingFile(file._id);
    setEditedFileName(file.name);
  };

  <span class="hljs-keyword">const</span> handleEditSave = <span class="hljs-keyword">async</span> (
    e: React.FocusEvent | React.KeyboardEvent,
    id: <span class="hljs-built_in">string</span>
  ) =&gt; {
    e.preventDefault();
    <span class="hljs-keyword">if</span> (!editedFileName.trim()) <span class="hljs-keyword">return</span>;

    <span class="hljs-keyword">const</span> previousFiles = [...files];
    setFiles(<span class="hljs-function">(<span class="hljs-params">prevFiles</span>) =&gt;</span>
      prevFiles.map(<span class="hljs-function">(<span class="hljs-params">file</span>) =&gt;</span>
        file._id === id ? { ...file, name: editedFileName } : file
      )
    ); <span class="hljs-comment">// Optimistic update</span>

    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">"/api/files"</span>, {
        method: <span class="hljs-string">"PUT"</span>,
        headers: { <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"application/json"</span> },
        body: <span class="hljs-built_in">JSON</span>.stringify({ id, name: editedFileName }),
      });

      <span class="hljs-keyword">if</span> (!response.ok) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Failed to update file"</span>);

    <span class="hljs-keyword">const</span> updatedFile: FileData = <span class="hljs-keyword">await</span> response.json();
      socket?.emit(<span class="hljs-string">"update-file"</span>, updatedFile);
      setEditingFile(<span class="hljs-literal">null</span>);
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Error updating file:"</span>, error);
      setFiles(previousFiles); <span class="hljs-comment">// Revert state if API call fails</span>
    }
  };

  <span class="hljs-keyword">return</span> (
    &lt;div className=<span class="hljs-string">"w-64 bg-gray-900 p-4 h-full text-white rounded-lg shadow-lg flex flex-col"</span>&gt;
      &lt;h2 className=<span class="hljs-string">"text-lg font-semibold mb-4"</span>&gt;Files&lt;/h2&gt;

      {loading ? (
        &lt;div className=<span class="hljs-string">"text-gray-400 text-sm"</span>&gt;Loading files...&lt;/div&gt;
      ) : error ? (
        &lt;div className=<span class="hljs-string">"text-red-500 text-sm"</span>&gt;{error}&lt;/div&gt;
      ) : files.length === <span class="hljs-number">0</span> ? (
        &lt;div className=<span class="hljs-string">"text-gray-400 text-sm"</span>&gt;No files yet&lt;/div&gt;
      ) : (
        &lt;div className=<span class="hljs-string">"space-y-2 overflow-y-auto flex-grow"</span>&gt;
          {files.map(<span class="hljs-function">(<span class="hljs-params">file</span>) =&gt;</span> (
            &lt;div
              key={file._id}
              className={<span class="hljs-string">`cursor-pointer flex justify-between items-center p-2 rounded text-white transition-all duration-200 <span class="hljs-subst">${
                currentFile?._id === file._id
                  ? <span class="hljs-string">"bg-blue-600"</span>
                  : <span class="hljs-string">"hover:bg-gray-700"</span>
              }</span>`</span>}
              onClick={<span class="hljs-function">() =&gt;</span> onFileSelect(file)}
            &gt;
              {editingFile === file._id ? (
                &lt;input
                  <span class="hljs-keyword">type</span>=<span class="hljs-string">"text"</span>
                  value={editedFileName}
                onChange={<span class="hljs-function">(<span class="hljs-params">e: React.ChangeEvent&lt;HTMLInputElement&gt;</span>) =&gt;</span> setEditedFileName(e.target.value)}
                onBlur={<span class="hljs-function">(<span class="hljs-params">e: React.FocusEvent&lt;HTMLInputElement&gt;</span>) =&gt;</span> handleEditSave(e, file._id)}
                onKeyDown={<span class="hljs-function">(<span class="hljs-params">e: React.KeyboardEvent&lt;HTMLInputElement&gt;</span>) =&gt;</span>
                e.key === <span class="hljs-string">"Enter"</span> ? handleEditSave(e, file._id) : <span class="hljs-literal">null</span>
                }
                  autoFocus
                  className=<span class="hljs-string">"bg-gray-800 text-white p-1 rounded outline-none w-32"</span>
                /&gt;
              ) : (
                &lt;span className=<span class="hljs-string">"truncate flex-grow"</span>&gt;📄 {file.name}&lt;/span&gt;
              )}

              &lt;div className=<span class="hljs-string">"flex items-center gap-2"</span>&gt;
                &lt;button
                onClick={<span class="hljs-function">(<span class="hljs-params">e: React.MouseEvent</span>) =&gt;</span> handleEditStart(e, file)}
                  className=<span class="hljs-string">"text-yellow-400 hover:text-yellow-600 p-1 rounded"</span>
                &gt;
                  &lt;Pencil size={<span class="hljs-number">16</span>} /&gt;
                &lt;/button&gt;
                &lt;button
                onClick={<span class="hljs-function">(<span class="hljs-params">e: React.MouseEvent</span>) =&gt;</span> handleDeleteFile(e, file._id)}
                  className=<span class="hljs-string">"text-red-400 hover:text-red-600 p-1 rounded"</span>
                &gt;
                  &lt;Trash2 size={<span class="hljs-number">16</span>} /&gt;
                &lt;/button&gt;
              &lt;/div&gt;
            &lt;/div&gt;
          ))}
        &lt;/div&gt;
      )}


    &lt;/div&gt;
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> FileExplorer;
</code></pre>
<h3 id="heading-code-explanation-3"><strong>Code Explanation</strong></h3>
<h3 id="heading-brief-explanation-of-the-code">Brief Explanation of the Code</h3>
<p>The <code>FileExplorer</code> component is a React component designed to manage and display a list of files in real time. It uses <a target="_blank" href="http://Socket.IO"><strong>Socket.IO</strong></a> for real-time updates, allowing users to add, delete, and edit files dynamically.</p>
<h3 id="heading-key-features-2">Key Features:</h3>
<h4 id="heading-1-state-management">1. <strong>State Management</strong></h4>
<p>The component uses React's <code>useState</code> Hook to manage the following states:</p>
<ul>
<li><p><code>files</code>: List of files displayed in the File Explorer.</p>
</li>
<li><p><code>socket</code>: The active <a target="_blank" href="http://Socket.IO">Socket.IO</a> connection.</p>
</li>
<li><p><code>loading</code> &amp; <code>error</code>: Manage the state of file loading.</p>
</li>
<li><p><code>newFileName</code>, <code>editingFile</code>, and <code>editedFileName</code>: Manage file creation and editing processes.</p>
</li>
</ul>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> [files, setFiles] = useState([]);
<span class="hljs-keyword">const</span> [socket, setSocket] = useState(<span class="hljs-literal">null</span>);
<span class="hljs-keyword">const</span> [loading, setLoading] = useState(<span class="hljs-literal">true</span>);
<span class="hljs-keyword">const</span> [error, setError] = useState(<span class="hljs-literal">null</span>);
<span class="hljs-keyword">const</span> [newFileName, setNewFileName] = useState(<span class="hljs-string">""</span>);
<span class="hljs-keyword">const</span> [editingFile, setEditingFile] = useState(<span class="hljs-literal">null</span>);
<span class="hljs-keyword">const</span> [editedFileName, setEditedFileName] = useState(<span class="hljs-string">""</span>);
</code></pre>
<h4 id="heading-2-socketiohttpsocketio-integration">2. <a target="_blank" href="http://Socket.IO"><strong>Socket.IO</strong></a> <strong>Integration</strong></h4>
<ul>
<li><p>Establishes a real-time connection to a <a target="_blank" href="http://Socket.IO">Socket.IO</a> server.</p>
</li>
<li><p>Listens for events like <code>new-file</code>, <code>delete-file</code>, and <code>update-file</code> to update the file list dynamically.</p>
</li>
<li><p>Cleans up the socket connection when the component unmounts.</p>
</li>
</ul>
<pre><code class="lang-javascript">useEffect(<span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> socketInstance = io(<span class="hljs-string">"http://localhost:3000"</span>, {
    <span class="hljs-attr">reconnection</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">reconnectionAttempts</span>: <span class="hljs-number">5</span>,
    <span class="hljs-attr">reconnectionDelay</span>: <span class="hljs-number">1000</span>,
  });

  socketInstance.on(<span class="hljs-string">"connect"</span>, <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Connected to Socket.IO server"</span>);
  });

  setSocket(socketInstance);

  <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">if</span> (socketInstance) socketInstance.disconnect();
  };
}, []);
</code></pre>
<h4 id="heading-3-real-time-file-updates">3. <strong>Real-Time File Updates</strong></h4>
<p>Handles real-time events for creating, deleting, and updating files.</p>
<pre><code class="lang-javascript">useEffect(<span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">if</span> (!socket) <span class="hljs-keyword">return</span>;

  socket.on(<span class="hljs-string">"new-file"</span>, <span class="hljs-function">(<span class="hljs-params">newFile</span>) =&gt;</span> {
    setFiles(<span class="hljs-function">(<span class="hljs-params">prevFiles</span>) =&gt;</span>
      prevFiles.some(<span class="hljs-function">(<span class="hljs-params">file</span>) =&gt;</span> file._id === newFile._id)
        ? prevFiles
        : [...prevFiles, newFile]
    );
  });

  socket.on(<span class="hljs-string">"delete-file"</span>, <span class="hljs-function">(<span class="hljs-params">fileId</span>) =&gt;</span> {
    setFiles(<span class="hljs-function">(<span class="hljs-params">prevFiles</span>) =&gt;</span> prevFiles.filter(<span class="hljs-function">(<span class="hljs-params">file</span>) =&gt;</span> file._id !== fileId));
  });

  socket.on(<span class="hljs-string">"update-file"</span>, <span class="hljs-function">(<span class="hljs-params">updatedFile</span>) =&gt;</span> {
    setFiles(<span class="hljs-function">(<span class="hljs-params">prevFiles</span>) =&gt;</span>
      prevFiles.map(<span class="hljs-function">(<span class="hljs-params">file</span>) =&gt;</span>
        file._id === updatedFile._id
          ? { ...file, <span class="hljs-attr">name</span>: updatedFile.name }
          : file
      )
    );
  });

  <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
    socket.off(<span class="hljs-string">"new-file"</span>);
    socket.off(<span class="hljs-string">"delete-file"</span>);
    socket.off(<span class="hljs-string">"update-file"</span>);
  };
}, [socket]);
</code></pre>
<h4 id="heading-4-crud-operations">4. <strong>CRUD Operations</strong></h4>
<ul>
<li><p><strong>Fetch Files</strong>: Retrieves the initial list of files from the server.</p>
</li>
<li><p><strong>Create File</strong>: Sends a POST request to add a new file.</p>
</li>
<li><p><strong>Delete File</strong>: Sends a DELETE request to remove a file and updates the UI optimistically.</p>
</li>
<li><p><strong>Edit File</strong>: Sends a PUT request to update a file's name and performs optimistic updates.</p>
<p>  This code defines a FileExplorer React component that allows users to manage and interact with files in a file system.</p>
<p>  <strong>Note: All the operations on the application get saved in real-time for the demo you can refresh the page to see the changes don’t get removed.</strong></p>
</li>
</ul>
<h3 id="heading-screenonetsx"><strong>ScreenOne.tsx</strong></h3>
<p>The <code>ScreenOne</code> component is a code editor panel that dynamically displays and updates code for a selected file. It integrates the Monaco Editor to highlight syntax based on the file type (for example, JavaScript, HTML, CSS).</p>
<p>The component shows the selected file's name, allows users to edit its content, and sends updates back to the database in real time. It also offers a clean, user-friendly interface with a dark theme and configurable editor options. This is ideal for coding environments like IDEs or code playgrounds.</p>
<pre><code class="lang-typescript">
<span class="hljs-keyword">import</span> React, { useEffect, useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { Editor } <span class="hljs-keyword">from</span> <span class="hljs-string">"@monaco-editor/react"</span>;

<span class="hljs-keyword">interface</span> File {
  name: <span class="hljs-built_in">string</span>;
}

<span class="hljs-keyword">interface</span> ScreenOneProps {
  selectedFile: File | <span class="hljs-literal">null</span>;
  code: <span class="hljs-built_in">string</span>;
  onChange: <span class="hljs-function">(<span class="hljs-params">newCode: <span class="hljs-built_in">string</span> | <span class="hljs-literal">undefined</span></span>) =&gt;</span> <span class="hljs-built_in">void</span>;
}

<span class="hljs-keyword">const</span> ScreenOne: React.FC&lt;ScreenOneProps&gt; = <span class="hljs-function">(<span class="hljs-params">{ selectedFile, code, onChange }</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> [language, setLanguage] = useState&lt;<span class="hljs-built_in">string</span>&gt;(<span class="hljs-string">"javascript"</span>);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">if</span> (!selectedFile) <span class="hljs-keyword">return</span>;
    setLanguage(getLanguageForFile(selectedFile.name));
  }, [selectedFile]);

  <span class="hljs-keyword">const</span> getLanguageForFile = (filename: <span class="hljs-built_in">string</span>): <span class="hljs-function"><span class="hljs-params">string</span> =&gt;</span> {
    <span class="hljs-keyword">const</span> extension = filename.split(<span class="hljs-string">"."</span>).pop()?.toLowerCase();
    <span class="hljs-keyword">switch</span> (extension) {
      <span class="hljs-keyword">case</span> <span class="hljs-string">"js"</span>:
      <span class="hljs-keyword">case</span> <span class="hljs-string">"jsx"</span>:
        <span class="hljs-keyword">return</span> <span class="hljs-string">"javascript"</span>;
      <span class="hljs-keyword">case</span> <span class="hljs-string">"html"</span>:
        <span class="hljs-keyword">return</span> <span class="hljs-string">"html"</span>;
      <span class="hljs-keyword">case</span> <span class="hljs-string">"css"</span>:
        <span class="hljs-keyword">return</span> <span class="hljs-string">"css"</span>;
      <span class="hljs-keyword">case</span> <span class="hljs-string">"json"</span>:
        <span class="hljs-keyword">return</span> <span class="hljs-string">"json"</span>;
      <span class="hljs-keyword">default</span>:
        <span class="hljs-keyword">return</span> <span class="hljs-string">"plaintext"</span>;
    }
  };

  <span class="hljs-keyword">const</span> handleCodeChange = (newCode: <span class="hljs-built_in">string</span> | <span class="hljs-literal">undefined</span>): <span class="hljs-function"><span class="hljs-params">void</span> =&gt;</span> {
    onChange(newCode); <span class="hljs-comment">// Call the onChange prop to update the code in LivePreview</span>
  };

  <span class="hljs-keyword">return</span> (
    &lt;div className=<span class="hljs-string">"flex-1 flex flex-col bg-[#2d2d2d] text-white p-6 rounded-lg shadow-md"</span>&gt;
      &lt;div className=<span class="hljs-string">"flex items-center justify-between mb-4"</span>&gt;
        &lt;h2 className=<span class="hljs-string">"text-2xl font-semibold"</span>&gt;Code Editor&lt;/h2&gt;
        &lt;div className=<span class="hljs-string">"text-sm text-gray-400"</span>&gt;
          {selectedFile ? selectedFile.name : <span class="hljs-string">"No file selected"</span>}
        &lt;/div&gt;
      &lt;/div&gt;
      &lt;div className=<span class="hljs-string">"flex-grow bg-gray-800 rounded-lg shadow-inner"</span>&gt;
        &lt;Editor
          height=<span class="hljs-string">"calc(100vh - 160px)"</span>
          language={language}
          value={code}
          onChange={handleCodeChange} <span class="hljs-comment">// Update the code on change</span>
          theme=<span class="hljs-string">"vs-dark"</span>
          options={{
            minimap: { enabled: <span class="hljs-literal">false</span> },
            lineNumbers: <span class="hljs-string">"on"</span>,
            wordWrap: <span class="hljs-string">"on"</span>,
            scrollBeyondLastLine: <span class="hljs-literal">false</span>,
          }}
        /&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> ScreenOne;
</code></pre>
<h3 id="heading-code-explanation-4"><strong>Code Explanation</strong></h3>
<h3 id="heading-explanation-of-the-code">Explanation of the Code:</h3>
<p>This React component, <code>ScreenOne</code>, represents a code editor screen where users can edit files in a specified programming language. The editor dynamically adjusts its syntax highlighting based on the selected file's type. It uses the <code>@monaco-editor/react</code> library for the editor interface.</p>
<p>This code defines a ScreenOne React component, which is a code editor using the Monaco Editor (used in VS Code). Here's a brief explanation:</p>
<h3 id="heading-key-features-3"><strong>Key Features</strong>:</h3>
<ol>
<li><p><strong>Code Editor</strong>:</p>
<ul>
<li><p>Uses the <code>@monaco-editor/react</code> library to render a code editor.</p>
</li>
<li><p>Supports syntax highlighting for various languages (for example, JavaScript, HTML, CSS, JSON).</p>
</li>
</ul>
</li>
<li><p><strong>Dynamic Language Detection</strong>:</p>
<ul>
<li><p>Detects the programming language based on the selected file's extension (for example, <code>.js</code> → JavaScript).</p>
</li>
<li><p>Defaults to <code>plaintext</code> for unsupported file types.</p>
</li>
</ul>
</li>
<li><p><strong>Props</strong>:</p>
<ul>
<li><p><code>selectedFile</code>: The currently selected file (contains the file name).</p>
</li>
<li><p><code>code</code>: The current code content to display in the editor.</p>
</li>
<li><p><code>onChange</code>: A callback function to handle code changes.</p>
</li>
</ul>
</li>
<li><p><strong>UI</strong>:</p>
<ul>
<li><p>Displays the file name and a title ("Code Editor").</p>
</li>
<li><p>Styled with Tailwind CSS for a dark theme and rounded corners.</p>
</li>
</ul>
</li>
<li><p><strong>Editor Configuration</strong>:</p>
<ul>
<li><p>Uses the <code>vs-dark</code> theme.</p>
</li>
<li><p>Disables the mini-map and enables line numbers and word wrap.</p>
</li>
</ul>
</li>
</ol>
<h3 id="heading-livepreviewtsx"><strong>LivePreview.tsx</strong></h3>
<p>The <code>LivePreview</code> component dynamically generates a live code preview for either static projects (HTML, CSS, JS) or React-based projects. It detects the type of project, and sets up the required files (for example, <code>index.html</code>, <code>App.js</code>), and renders a real-time preview using CodeSandbox's Sandpack. The preview adapts to the selected file and updates as the code changes, providing a seamless coding experience.</p>
<pre><code class="lang-typescript">
<span class="hljs-keyword">import</span> React, { useEffect, useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> {
  SandpackProvider,
  SandpackLayout,
  SandpackCodeEditor,
  SandpackPreview,
  SandpackThemeProvider,
} <span class="hljs-keyword">from</span> <span class="hljs-string">"@codesandbox/sandpack-react"</span>;

<span class="hljs-keyword">interface</span> FileAccumulator {
[key: <span class="hljs-built_in">string</span>]: { code: <span class="hljs-built_in">string</span> };
}

<span class="hljs-keyword">interface</span> File {
  name: <span class="hljs-built_in">string</span>;
  content: <span class="hljs-built_in">string</span>;
}

<span class="hljs-keyword">interface</span> LivePreviewProps {
files: File[];
currentFile: File | <span class="hljs-literal">null</span>;
code: <span class="hljs-built_in">string</span>;
onCodeChange?: <span class="hljs-function">(<span class="hljs-params">value: <span class="hljs-built_in">string</span> | <span class="hljs-literal">undefined</span></span>) =&gt;</span> <span class="hljs-built_in">void</span>;
}
<span class="hljs-keyword">interface</span> SandpackFile {
  code: <span class="hljs-built_in">string</span>;
}

<span class="hljs-keyword">interface</span> SandpackFiles {
  [key: <span class="hljs-built_in">string</span>]: SandpackFile;
}

<span class="hljs-keyword">const</span> LivePreview: React.FC&lt;LivePreviewProps&gt; = <span class="hljs-function">(<span class="hljs-params">{ files, currentFile, code }</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> [sandboxFiles, setSandboxFiles] = useState&lt;Record&lt;<span class="hljs-built_in">string</span>, { code: <span class="hljs-built_in">string</span> }&gt;&gt;({});
  <span class="hljs-keyword">const</span> [template, setTemplate] = useState&lt;<span class="hljs-string">"vanilla"</span> | <span class="hljs-string">"react"</span>&gt;(<span class="hljs-string">"vanilla"</span>); <span class="hljs-comment">// Default to static</span>
  <span class="hljs-keyword">const</span> [loading, setLoading] = useState&lt;<span class="hljs-built_in">boolean</span>&gt;(<span class="hljs-literal">true</span>);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">if</span> (!currentFile || !files) <span class="hljs-keyword">return</span>;

    <span class="hljs-keyword">const</span> newFiles: SandpackFiles = files.reduce(<span class="hljs-function">(<span class="hljs-params">acc: FileAccumulator, file</span>) =&gt;</span> {
    acc[<span class="hljs-string">`/<span class="hljs-subst">${file.name}</span>`</span>] = { code: file.content };
    <span class="hljs-keyword">return</span> acc;
    }, {});

    <span class="hljs-comment">// Check if the project is React-based</span>
    <span class="hljs-keyword">const</span> isReactProject = files.some(
      <span class="hljs-function">(<span class="hljs-params">file</span>) =&gt;</span>
        file.name.endsWith(<span class="hljs-string">".jsx"</span>) ||
        (file.name.endsWith(<span class="hljs-string">".js"</span>) &amp;&amp; file.content.includes(<span class="hljs-string">"React"</span>))
    );

    <span class="hljs-keyword">if</span> (isReactProject) {
      setTemplate(<span class="hljs-string">"react"</span>);

      <span class="hljs-comment">// Ensure App.js exists</span>
      <span class="hljs-keyword">if</span> (!newFiles[<span class="hljs-string">"/App.js"</span>]) {
        newFiles[<span class="hljs-string">"/App.js"</span>] = {
          code: <span class="hljs-string">`
            import React from "react";
            function App() { return &lt;h1&gt;Hello, React!&lt;/h1&gt;; }
            export default App;
          `</span>,
        };
      }

      <span class="hljs-comment">// Ensure index.js exists</span>
      newFiles[<span class="hljs-string">"/index.js"</span>] = {
        code: <span class="hljs-string">`
          import React from "react";
          import ReactDOM from "react-dom/client";
          import App from "./App";

          const root = document.getElementById("root");
          if (root) {
            ReactDOM.createRoot(root).render(&lt;App /&gt;);
          } else {
            console.error("Root element not found!");
          }
        `</span>,
      };

      <span class="hljs-comment">// Ensure index.html exists</span>
      newFiles[<span class="hljs-string">"/index.html"</span>] = {
        code: <span class="hljs-string">`
          &lt;!DOCTYPE html&gt;
          &lt;html lang="en"&gt;
          &lt;head&gt;
            &lt;meta charset="UTF-8"&gt;
            &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&gt;
            &lt;title&gt;React App&lt;/title&gt;
          &lt;/head&gt;
          &lt;body&gt;
            &lt;div id="root"&gt;&lt;/div&gt;
          &lt;/body&gt;
          &lt;/html&gt;
        `</span>,
      };

      <span class="hljs-comment">// Ensure package.json exists</span>
      newFiles[<span class="hljs-string">"/package.json"</span>] = {
        code: <span class="hljs-built_in">JSON</span>.stringify(
          {
            main: <span class="hljs-string">"/index.js"</span>,
            dependencies: {
              react: <span class="hljs-string">"18.2.0"</span>,
              <span class="hljs-string">"react-dom"</span>: <span class="hljs-string">"18.2.0"</span>,
            },
          },
          <span class="hljs-literal">null</span>,
          <span class="hljs-number">2</span>
        ),
      };
    } <span class="hljs-keyword">else</span> {
      setTemplate(<span class="hljs-string">"vanilla"</span>);

      <span class="hljs-keyword">const</span> htmlFile = files.find(<span class="hljs-function">(<span class="hljs-params">f</span>) =&gt;</span> f.name.endsWith(<span class="hljs-string">".html"</span>));
      <span class="hljs-keyword">if</span> (htmlFile) {
        <span class="hljs-keyword">let</span> htmlContent = htmlFile.content;

        <span class="hljs-comment">// Inject CSS files</span>
        files
          .filter(<span class="hljs-function">(<span class="hljs-params">f</span>) =&gt;</span> f.name.endsWith(<span class="hljs-string">".css"</span>))
          .forEach(<span class="hljs-function">(<span class="hljs-params">cssFile</span>) =&gt;</span> {
            htmlContent = htmlContent.replace(
              <span class="hljs-string">"&lt;/head&gt;"</span>,
              <span class="hljs-string">`&lt;link rel="stylesheet" href="<span class="hljs-subst">${cssFile.name}</span>"&gt;&lt;/head&gt;`</span>
            );
          });

        <span class="hljs-comment">// Inject JS files</span>
        files
          .filter(<span class="hljs-function">(<span class="hljs-params">f</span>) =&gt;</span> f.name.endsWith(<span class="hljs-string">".js"</span>))
          .forEach(<span class="hljs-function">(<span class="hljs-params">jsFile</span>) =&gt;</span> {
            htmlContent = htmlContent.replace(
              <span class="hljs-string">"&lt;/body&gt;"</span>,
              <span class="hljs-string">`&lt;script src="<span class="hljs-subst">${jsFile.name}</span>"&gt;&lt;/script&gt;&lt;/body&gt;`</span>
            );
          });

        newFiles[<span class="hljs-string">"/index.html"</span>] = { code: htmlContent };
      }
    }

    <span class="hljs-comment">// Ensure the current file is included</span>
    newFiles[<span class="hljs-string">`/<span class="hljs-subst">${currentFile.name}</span>`</span>] = { code };
    setSandboxFiles(newFiles);
    setLoading(<span class="hljs-literal">false</span>);
  }, [files, currentFile, code]);

  <span class="hljs-keyword">return</span> (
    &lt;div className=<span class="hljs-string">"flex-1 bg-white border-l border-gray-300"</span>&gt;
      {loading ? (
        &lt;div className=<span class="hljs-string">"h-full flex items-center justify-center text-gray-500"</span>&gt;
          Loading...
        &lt;/div&gt;
      ) : currentFile ? (
        &lt;SandpackProvider
        template={template}
        files={sandboxFiles}
        options={{ activeFile: <span class="hljs-string">`/<span class="hljs-subst">${currentFile.name}</span>`</span> }}
        &gt;
        &lt;SandpackThemeProvider&gt;
            &lt;SandpackLayout&gt;
            &lt;SandpackCodeEditor showTabs={<span class="hljs-literal">false</span>}  /&gt;
            &lt;SandpackPreview style={{ height: <span class="hljs-string">"600px"</span>, border: <span class="hljs-string">"none"</span> }} /&gt;
            &lt;/SandpackLayout&gt;
        &lt;/SandpackThemeProvider&gt;
        &lt;/SandpackProvider&gt;
      ) : (
        &lt;div className=<span class="hljs-string">"h-full flex items-center justify-center text-gray-500"</span>&gt;
          Select a file to preview
        &lt;/div&gt;
      )}
    &lt;/div&gt;
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> LivePreview;
</code></pre>
<h3 id="heading-code-explanation-5">Code Explanation</h3>
<h3 id="heading-explanation-of-the-code-1">Explanation of the Code:</h3>
<p>The <code>LivePreview</code> component provides a real-time live preview environment for static HTML/CSS/JS files or React-based projects. It uses the CodeSandbox Sandpack library to dynamically render code files in a browser-like preview window. The component automatically adjusts its behavior based on the file types and content to determine if the project is static or React-based.</p>
<p>This code defines a LivePreview React component that uses Sandpack (from CodeSandbox) to provide a live code editor and preview environment. Here's a brief explanation:</p>
<h3 id="heading-key-features-4"><strong>Key Features</strong>:</h3>
<ol>
<li><p><strong>Sandpack Integration</strong>:</p>
<ul>
<li><p>Uses <code>@codesandbox/sandpack-react</code> to render a code editor and live preview.</p>
</li>
<li><p>Supports both React and vanilla JavaScript/HTML/CSS projects.</p>
</li>
</ul>
</li>
<li><p><strong>Dynamic File Handling</strong>:</p>
<ul>
<li><p>Converts a list of files (<code>files</code> prop) into a format compatible with Sandpack.</p>
</li>
<li><p>Automatically detects if the project is React-based (e.g., contains <code>.jsx</code> or React imports).</p>
</li>
<li><p>Ensures necessary files (for example, <code>App.js</code>, <code>index.js</code>, <code>index.html</code>, <code>package.json</code>) exist for React projects.</p>
</li>
</ul>
</li>
<li><p><strong>Template Switching</strong>:</p>
<ul>
<li>Sets the Sandpack template to <code>"react"</code> for React projects or <code>"vanilla"</code> for static HTML/CSS/JS projects.</li>
</ul>
</li>
<li><p><strong>Code Injection</strong>:</p>
<ul>
<li>For vanilla projects, injects linked CSS and JS files into the HTML file.</li>
</ul>
</li>
<li><p><strong>Loading State</strong>:</p>
<ul>
<li>Displays a loading message while processing files.</li>
</ul>
</li>
<li><p><strong>UI</strong>:</p>
<ul>
<li><p>Shows a code editor and live preview side by side.</p>
</li>
<li><p>Displays a message if no file is selected.</p>
</li>
</ul>
</li>
</ol>
<h3 id="heading-running-sockets-in-the-app">Running sockets in the app</h3>
<p>Now it is time to eat that big frog. As you know we are using sockets for real-time data communication so we need a <code>server.tsx</code> file in the root directory of the app (outside of the <code>src</code> folder) and paste this code:</p>
<pre><code class="lang-typescript">
<span class="hljs-keyword">import</span> { createServer, IncomingMessage, ServerResponse } <span class="hljs-keyword">from</span> <span class="hljs-string">"http"</span>;
<span class="hljs-keyword">import</span> { parse, UrlWithParsedQuery } <span class="hljs-keyword">from</span> <span class="hljs-string">"url"</span>;
<span class="hljs-keyword">import</span> next <span class="hljs-keyword">from</span> <span class="hljs-string">"next"</span>;
<span class="hljs-keyword">import</span> { Server, Socket } <span class="hljs-keyword">from</span> <span class="hljs-string">"socket.io"</span>;

<span class="hljs-keyword">const</span> dev: <span class="hljs-built_in">boolean</span> = process.env.NODE_ENV !== <span class="hljs-string">"production"</span>;
<span class="hljs-keyword">const</span> app = next({ dev });
<span class="hljs-keyword">const</span> handle = app.getRequestHandler();

app.prepare().then(<span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> httpServer = createServer(<span class="hljs-function">(<span class="hljs-params">req: IncomingMessage, res: ServerResponse</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> parsedUrl: UrlWithParsedQuery = parse(req.url || <span class="hljs-string">""</span>, <span class="hljs-literal">true</span>);
    handle(req, res, parsedUrl);
  });

  <span class="hljs-comment">// Determine the CORS origin dynamically</span>
  <span class="hljs-keyword">const</span> allowedOrigin: <span class="hljs-built_in">string</span> = dev
    ? <span class="hljs-string">"http://localhost:3000"</span> <span class="hljs-comment">// Local development</span>
    : <span class="hljs-string">"*"</span>; <span class="hljs-comment">// Vercel deployment</span>

  <span class="hljs-comment">// Initialize Socket.IO with dynamic CORS configuration</span>
  <span class="hljs-keyword">const</span> io = <span class="hljs-keyword">new</span> Server(httpServer, {
    cors: {
      origin: allowedOrigin,
      methods: [<span class="hljs-string">"GET"</span>, <span class="hljs-string">"POST"</span>],
      credentials: <span class="hljs-literal">true</span>,
    },
  });

  <span class="hljs-comment">// Socket.IO event handlers</span>
  io.on(<span class="hljs-string">"connection"</span>, <span class="hljs-function">(<span class="hljs-params">socket: Socket</span>) =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Client connected"</span>);

    <span class="hljs-comment">// Handle new file creation</span>
    socket.on(<span class="hljs-string">"new-file"</span>, <span class="hljs-function">(<span class="hljs-params">newFile: { id: <span class="hljs-built_in">string</span>; name: <span class="hljs-built_in">string</span>; content: <span class="hljs-built_in">string</span> }</span>) =&gt;</span> {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"New file created:"</span>, newFile);
      <span class="hljs-comment">// Broadcast to all clients except sender</span>
      socket.broadcast.emit(<span class="hljs-string">"new-file"</span>, newFile);
    });

    <span class="hljs-comment">// Handle file deletion</span>
    socket.on(<span class="hljs-string">"delete-file"</span>, <span class="hljs-function">(<span class="hljs-params">fileId: <span class="hljs-built_in">string</span></span>) =&gt;</span> {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"File deleted:"</span>, fileId);
      socket.broadcast.emit(<span class="hljs-string">"delete-file"</span>, fileId);
    });

    <span class="hljs-comment">// Handle file update</span>
    socket.on(<span class="hljs-string">"update-file"</span>, <span class="hljs-function">(<span class="hljs-params">updatedFile: { id: <span class="hljs-built_in">string</span>; name: <span class="hljs-built_in">string</span>; content: <span class="hljs-built_in">string</span> }</span>) =&gt;</span> {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"File updated:"</span>, updatedFile);
      socket.broadcast.emit(<span class="hljs-string">"update-file"</span>, updatedFile);
    });

    <span class="hljs-comment">// Handle client disconnect</span>
    socket.on(<span class="hljs-string">"disconnect"</span>, <span class="hljs-function">() =&gt;</span> {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Client disconnected"</span>);
    });
  });

  <span class="hljs-comment">// Start the server on the specified port</span>
  <span class="hljs-keyword">const</span> PORT: <span class="hljs-built_in">number</span> | <span class="hljs-built_in">string</span> = process.env.PORT || <span class="hljs-number">3000</span>;
  httpServer.listen(PORT, <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`&gt; Ready on <span class="hljs-subst">${dev ? <span class="hljs-string">"http://localhost:3000"</span> : allowedOrigin}</span>`</span>);
  });
});
</code></pre>
<h3 id="heading-code-explanation-6">Code Explanation</h3>
<p>This code sets up a <strong>Next.js server</strong> with <a target="_blank" href="http://Socket.IO"><strong>Socket.IO</strong></a> for real-time communication. It:</p>
<ol>
<li><p>Initializes a Next.js app and prepares it to handle HTTP requests.</p>
</li>
<li><p>Configures CORS dynamically for <a target="_blank" href="http://Socket.IO">Socket.IO</a>, allowing connections from <a target="_blank" href="http://localhost:3000"><code>localhost:3000</code></a> in development or all origins in production.</p>
</li>
<li><p><strong>Sets up</strong> <a target="_blank" href="http://Socket.IO"><strong>Socket.IO</strong></a> to handle real-time events like:</p>
<ul>
<li><p>New file creation</p>
</li>
<li><p>File deletion</p>
</li>
<li><p>File updates</p>
</li>
<li><p>Client disconnection</p>
</li>
</ul>
</li>
<li><p>Broadcasts events to all connected clients except the sender.</p>
</li>
<li><p>Starts the server on a specified port (default: 3000).</p>
</li>
</ol>
<p>It’s a basic real-time server for file management with Next.js and <a target="_blank" href="http://Socket.IO">Socket.IO</a>.</p>
<h3 id="heading-clubbing-all-components-together">Clubbing all components together</h3>
<p>To do this we will have to tweak the <code>page.tsx</code>. Just copy the given code and paste it into the <code>page.js</code></p>
<pre><code class="lang-typescript">
<span class="hljs-string">"use client"</span>;
<span class="hljs-keyword">import</span> React, { useState, useEffect } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { useCopilotAction, useCopilotReadable } <span class="hljs-keyword">from</span> <span class="hljs-string">"@copilotkit/react-core"</span>;
<span class="hljs-keyword">import</span> { CopilotPopup } <span class="hljs-keyword">from</span> <span class="hljs-string">"@copilotkit/react-ui"</span>;
<span class="hljs-keyword">import</span> ScreenOne <span class="hljs-keyword">from</span> <span class="hljs-string">"./components/ScreenOne"</span>;
<span class="hljs-keyword">import</span> FileExplorer <span class="hljs-keyword">from</span> <span class="hljs-string">"./components/FileExplorer"</span>;
<span class="hljs-keyword">import</span> LivePreview <span class="hljs-keyword">from</span> <span class="hljs-string">"./components/LivePreview"</span>;
<span class="hljs-keyword">import</span> io, { Socket } <span class="hljs-keyword">from</span> <span class="hljs-string">"socket.io-client"</span>;

<span class="hljs-keyword">interface</span> File {
  _id: <span class="hljs-built_in">string</span>;
  name: <span class="hljs-built_in">string</span>;
  content: <span class="hljs-built_in">string</span>;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Page</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [files, setFiles] = useState&lt;File[]&gt;([]);
  <span class="hljs-keyword">const</span> [currentFile, setCurrentFile] = useState&lt;File | <span class="hljs-literal">null</span>&gt;(<span class="hljs-literal">null</span>);
  <span class="hljs-keyword">const</span> [code, setCode] = useState&lt;<span class="hljs-built_in">string</span>&gt;(<span class="hljs-string">"// Select or create a file"</span>);
  <span class="hljs-keyword">const</span> [socket, setSocket] = useState&lt;Socket | <span class="hljs-literal">null</span>&gt;(<span class="hljs-literal">null</span>);
  <span class="hljs-keyword">const</span> [fileContents, setFileContents] = useState&lt;Record&lt;<span class="hljs-built_in">string</span>, <span class="hljs-built_in">string</span>&gt;&gt;({});

  <span class="hljs-comment">// Initialize socket connection</span>
  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> socketInstance = io(<span class="hljs-string">"http://localhost:3000"</span>, {
      reconnection: <span class="hljs-literal">true</span>,
      reconnectionAttempts: <span class="hljs-number">5</span>,
      reconnectionDelay: <span class="hljs-number">1000</span>,
    });

    socketInstance.on(<span class="hljs-string">"connect"</span>, <span class="hljs-function">() =&gt;</span> {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Connected to Socket.IO server"</span>);
    });

    <span class="hljs-comment">// Handle real-time file updates</span>
    socketInstance.on(
      <span class="hljs-string">"file-update"</span>,
      <span class="hljs-function">(<span class="hljs-params">{ fileId, content }: { fileId: <span class="hljs-built_in">string</span>; content: <span class="hljs-built_in">string</span> }</span>) =&gt;</span> {
        setFileContents(<span class="hljs-function">(<span class="hljs-params">prev</span>) =&gt;</span> ({
          ...prev,
          [fileId]: content,
        }));

        <span class="hljs-keyword">if</span> (currentFile &amp;&amp; currentFile._id === fileId) {
          setCode(content);
        }
      }
    );

    socketInstance.on(<span class="hljs-string">"new-file"</span>, <span class="hljs-function">(<span class="hljs-params">newFile: File</span>) =&gt;</span> {
      setFiles(<span class="hljs-function">(<span class="hljs-params">prev</span>) =&gt;</span> [...prev, newFile]);
      setFileContents(<span class="hljs-function">(<span class="hljs-params">prev</span>) =&gt;</span> ({
        ...prev,
        [newFile._id]: newFile.content,
      }));
    });

    socketInstance.on(<span class="hljs-string">"delete-file"</span>, <span class="hljs-function">(<span class="hljs-params">fileId: <span class="hljs-built_in">string</span></span>) =&gt;</span> {
      setFiles(<span class="hljs-function">(<span class="hljs-params">prev</span>) =&gt;</span> prev.filter(<span class="hljs-function">(<span class="hljs-params">file</span>) =&gt;</span> file._id !== fileId));
      setFileContents(<span class="hljs-function">(<span class="hljs-params">prev</span>) =&gt;</span> {
        <span class="hljs-keyword">const</span> updated = { ...prev };
        <span class="hljs-keyword">delete</span> updated[fileId];
        <span class="hljs-keyword">return</span> updated;
      });
    });

    setSocket(socketInstance);

    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
      <span class="hljs-keyword">if</span> (socketInstance) {
        socketInstance.disconnect();
      }
    };
  }, [currentFile]);

useCopilotReadable({
description: <span class="hljs-string">"Current state of the workspace"</span>,
value: {
    files: files.map(<span class="hljs-function">(<span class="hljs-params">f</span>) =&gt;</span> f.name),
    currentFile: currentFile?.name,
    currentCode: code,
},
});

  <span class="hljs-keyword">const</span> fetchFiles = <span class="hljs-keyword">async</span> () =&gt; {
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">"/api/files"</span>);
      <span class="hljs-keyword">if</span> (!response.ok) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Failed to fetch files"</span>);
      <span class="hljs-keyword">const</span> data: File[] = <span class="hljs-keyword">await</span> response.json();

      <span class="hljs-comment">// Store all file contents in state</span>
      <span class="hljs-keyword">const</span> contents: Record&lt;<span class="hljs-built_in">string</span>, <span class="hljs-built_in">string</span>&gt; = {};
      data.forEach(<span class="hljs-function">(<span class="hljs-params">file</span>) =&gt;</span> {
        contents[file._id] = file.content;
      });

      setFiles(data);
      setFileContents(contents);
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Error fetching files:"</span>, error);
    }
  };

  useEffect(<span class="hljs-function">() =&gt;</span> {
    fetchFiles();
  }, []);

  <span class="hljs-keyword">const</span> handleFileSelect = <span class="hljs-keyword">async</span> (file: File) =&gt; {
    setCurrentFile(file);

    <span class="hljs-comment">// Use cached content if available</span>
    <span class="hljs-keyword">if</span> (fileContents[file._id]) {
      setCode(fileContents[file._id]);
    } <span class="hljs-keyword">else</span> {
      <span class="hljs-keyword">try</span> {
        <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">`/api/files/<span class="hljs-subst">${file._id}</span>`</span>);
        <span class="hljs-keyword">if</span> (!response.ok) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Failed to fetch file content"</span>);
        <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> response.json();

        setFileContents(<span class="hljs-function">(<span class="hljs-params">prev</span>) =&gt;</span> ({
          ...prev,
          [file._id]: data.content,
        }));
        setCode(data.content);
      } <span class="hljs-keyword">catch</span> (error) {
        <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Error fetching file content:"</span>, error);
      }
    }
  };

  <span class="hljs-keyword">const</span> handleCodeChange = <span class="hljs-keyword">async</span> (value: <span class="hljs-built_in">string</span> | <span class="hljs-literal">undefined</span>) =&gt; {
    <span class="hljs-keyword">if</span> (!currentFile || !value) <span class="hljs-keyword">return</span>;

    <span class="hljs-comment">// Update local state immediately</span>
    setCode(value);
    setFileContents(<span class="hljs-function">(<span class="hljs-params">prev</span>) =&gt;</span> ({
      ...prev,
      [currentFile._id]: value,
    }));

    <span class="hljs-keyword">try</span> {
      <span class="hljs-comment">// Emit the change to other clients</span>
      <span class="hljs-keyword">if</span> (socket) {
        socket.emit(<span class="hljs-string">"file-update"</span>, {
          fileId: currentFile._id,
          content: value,
        });
      }

      <span class="hljs-comment">// Save to backend</span>
      <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">"/api/files"</span>, {
        method: <span class="hljs-string">"PUT"</span>,
        headers: { <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"application/json"</span> },
        body: <span class="hljs-built_in">JSON</span>.stringify({ id: currentFile._id, content: value }),
      });
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Error updating file:"</span>, error);
    }
  };

  <span class="hljs-keyword">const</span> processFiles = <span class="hljs-keyword">async</span> ({ response }: { response: <span class="hljs-built_in">string</span> }) =&gt; {
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">const</span> filePattern =
        <span class="hljs-regexp">/FILE:\s*([\w.\-\/]+)\s*\nCODE:\s*([\s\S]*?)(?=\nFILE:|$)/g</span>;
      <span class="hljs-keyword">let</span> match;
      <span class="hljs-keyword">const</span> newFiles: File[] = [];

      <span class="hljs-keyword">while</span> ((match = filePattern.exec(response)) !== <span class="hljs-literal">null</span>) {
        <span class="hljs-keyword">const</span> fileName = match[<span class="hljs-number">1</span>].trim();
        <span class="hljs-keyword">const</span> fileContent = match[<span class="hljs-number">2</span>].trim();

        <span class="hljs-keyword">if</span> (fileName &amp;&amp; fileContent) {
          <span class="hljs-keyword">const</span> res = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">"/api/files"</span>, {
            method: <span class="hljs-string">"POST"</span>,
            headers: { <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"application/json"</span> },
            body: <span class="hljs-built_in">JSON</span>.stringify({ name: fileName, content: fileContent }),
          });

          <span class="hljs-keyword">if</span> (res.ok) {
            <span class="hljs-keyword">const</span> savedFile: File = <span class="hljs-keyword">await</span> res.json();
            newFiles.push(savedFile);

            <span class="hljs-comment">// Update local state</span>
            setFileContents(<span class="hljs-function">(<span class="hljs-params">prev</span>) =&gt;</span> ({
              ...prev,
              [savedFile._id]: savedFile.content,
            }));

            <span class="hljs-comment">// Emit new file to other clients</span>
            <span class="hljs-keyword">if</span> (socket) {
              socket.emit(<span class="hljs-string">"new-file"</span>, savedFile);
            }
          }
        }
      }

      setFiles(<span class="hljs-function">(<span class="hljs-params">prevFiles</span>) =&gt;</span> [...prevFiles, ...newFiles]);
      <span class="hljs-keyword">return</span> <span class="hljs-string">`Files saved successfully: <span class="hljs-subst">${newFiles
        .map((f) =&gt; f.name)
        .join(<span class="hljs-string">", "</span>)}</span>`</span>;
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Error processing files:"</span>, error);
      <span class="hljs-keyword">return</span> <span class="hljs-string">"Failed to save files."</span>;
    }
  };

  useCopilotAction({
    name: <span class="hljs-string">"processFiles"</span>,
    description: <span class="hljs-string">"Processes AI-generated files and saves them to MongoDB"</span>,
    parameters: [{ name: <span class="hljs-string">"response"</span>, <span class="hljs-keyword">type</span>: <span class="hljs-string">"string"</span>, required: <span class="hljs-literal">true</span> }],
    handler: processFiles,
  });

  <span class="hljs-keyword">return</span> (
    &lt;div className=<span class="hljs-string">"h-screen flex bg-gray-100"</span>&gt;
      &lt;FileExplorer
        files={files}
        onFileSelect={handleFileSelect}
        currentFile={currentFile}
      /&gt;
      &lt;div className=<span class="hljs-string">"flex-1 flex flex-col p-4"</span>&gt;
        &lt;ScreenOne
          selectedFile={currentFile}
          code={code}
          onChange={handleCodeChange}
        /&gt;
      &lt;/div&gt;
      &lt;LivePreview
        files={files}
        currentFile={currentFile}
        code={code}
        onCodeChange={handleCodeChange}
      /&gt;
      &lt;CopilotPopup
        instructions={<span class="hljs-string">`
    You are an AI-powered code generator. Use the following actions:

    1. @processFiles - To create new files, use this format:
    @processFiles(response: \`
    FILE: filename.ext
    CODE:
    [file content]
    \`)

    - Store new files in MongoDB using /api/files.
    - Then immediately fetch the files from database and show the files to FileExplorer
    - Correctly classify and separate different file types:
      - Static: HTML, CSS, JS
      - React: JSX, JS (React components)
    - For React projects:
      - Ensure the presence of index.js as the entry point.
      - Ensure there is a App.css file for styling
      - Ensure index.html contains a root &lt;div id="root"&gt;&lt;/div&gt;.
      - Separate components correctly (e.g., App.js, Header.jsx).
      - Include a package.json file with necessary React dependencies.
      - Ensure all React files follow ES6+ syntax and React best practices.

    2. @updateFile - To update existing files:
    @updateFile(filename: "file.ext", content: "new content")

    - Maintain compatibility with React environment.
    - Ensure any updated files do not break existing imports.
  `</span>}
        labels={{
          title: <span class="hljs-string">"Project Assistant"</span>,
          initial: <span class="hljs-string">"What would you like to create?"</span>,
        }}
      /&gt;
    &lt;/div&gt;
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Page;
</code></pre>
<h3 id="heading-code-explanation-7">Code explanation</h3>
<ol>
<li><p><strong>State Management</strong>:</p>
<ul>
<li>Tracks files (<code>files</code>), the currently selected file (<code>currentFile</code>), code in the selected file (<code>code</code>), real-time file contents (<code>fileContents</code>), and a socket connection (<code>socket</code>).</li>
</ul>
</li>
<li><p><a target="_blank" href="http://Socket.IO"><strong>Socket.IO</strong></a>:</p>
<ul>
<li><p>Establishes a connection to a server using <a target="_blank" href="http://Socket.IO"><code>Socket.IO</code></a>, and handling real-time file updates like file creation, updates, and deletions.</p>
</li>
<li><p>Listens for events such as <code>file-update</code>, <code>new-file</code>, and <code>delete-file</code> to update the UI and propagate changes across users.</p>
</li>
</ul>
</li>
<li><p><strong>Fetching Files</strong>:</p>
<ul>
<li><p>On component mount, it fetches all files from an API and populates the state with the files and their contents.</p>
</li>
<li><p>Upon selecting a file, the content is either retrieved from the cached state or fetched from the server.</p>
</li>
</ul>
</li>
<li><p><strong>Code Changes</strong>:</p>
<ul>
<li>When code in the Monaco Editor is updated, the new content is saved locally and sent to the server and other connected clients via the socket.</li>
</ul>
</li>
<li><p><strong>File Processing by AI</strong>:</p>
<ul>
<li>When AI generates code, the <code>processFiles</code> function parses the generated content, creates files on the backend, and updates the frontend. These files are stored in MongoDB and synchronized with the client via <a target="_blank" href="http://Socket.IO">Socket.IO</a>.</li>
</ul>
</li>
<li><p><strong>CopilotKit Integration</strong>:</p>
<ul>
<li><p>Uses the <code>useCopilotAction</code> hook to integrate AI-driven file generation and updating functionality.</p>
</li>
<li><p>Provides instructions for creating and updating files via the <code>CopilotPopup</code>.</p>
</li>
<li><p>Always give detailed instructions to the <code>CopilotPopup</code> .</p>
</li>
</ul>
</li>
<li><p><strong>UI Components</strong>:</p>
<ul>
<li><p>The UI includes components like <code>FileExplorer</code>, <code>ScreenOne</code>, and <code>LivePreview</code>, which displays files, allows editing, and provides a live preview of the code.</p>
</li>
<li><p>The <code>CopilotPopup</code> acts as an assistant to guide the AI in generating or updating files.</p>
</li>
</ul>
</li>
</ol>
<p>This setup creates a collaborative, real-time code editing environment with support for both static and React-based projects.</p>
<h3 id="heading-configuring-copilotkit-for-the-whole-app"><strong>Configuring CopilotKit for the Whole App</strong></h3>
<p>This is going to be the last step of building the application. Navigate to the <code>layout.ts</code>x file and add this code:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { CopilotKit } <span class="hljs-keyword">from</span> <span class="hljs-string">"@copilotkit/react-core"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">"./globals.css"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">"@copilotkit/react-ui/styles.css"</span>;
<span class="hljs-keyword">import</span> { ReactNode } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> metadata = {
  <span class="hljs-attr">title</span>: <span class="hljs-string">"Replit Clone"</span>,
  <span class="hljs-attr">description</span>: <span class="hljs-string">"Copilotkit Replit Clone"</span>,
};

<span class="hljs-comment">// Define props type for RootLayout</span>
interface RootLayoutProps {
  <span class="hljs-attr">children</span>: ReactNode;
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">RootLayout</span>(<span class="hljs-params">{ children }: RootLayoutProps</span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">CopilotKit</span> <span class="hljs-attr">runtimeUrl</span>=<span class="hljs-string">"/api/copilotkit"</span>&gt;</span>{children}<span class="hljs-tag">&lt;/<span class="hljs-name">CopilotKit</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span></span>
  );
}
</code></pre>
<p>Here’s what’s going on in this code:</p>
<p>This code defines a <code>RootLayout</code> component, which serves as the root layout for a Next.js application. Here's a brief explanation:</p>
<h3 id="heading-key-features-5"><strong>Key Features</strong>:</h3>
<ol>
<li><p><strong>CopilotKit Integration</strong>:</p>
<ul>
<li><p>Wraps the entire application with the <code>CopilotKit</code> component from <code>@copilotkit/react-core</code>.</p>
</li>
<li><p>Configures the <code>runtimeUrl</code> to <code>/api/copilotkit</code>, which is the endpoint for handling Copilot-related functionality.</p>
</li>
</ul>
</li>
<li><p><strong>Global Styles</strong>:</p>
<ul>
<li>Imports global CSS styles (<code>globals.css</code>) and CopilotKit UI styles (<code>@copilotkit/react-ui/styles.css</code>).</li>
</ul>
</li>
<li><p><strong>Metadata</strong>:</p>
<ul>
<li>Sets metadata for the application (title: <code>"Replit Clone"</code>, description: <code>"Copilotkit Replit Clone"</code>).</li>
</ul>
</li>
<li><p><strong>Layout Structure</strong>:</p>
<ul>
<li><p>Uses the <code>html</code> and <code>body</code> tags to structure the document.</p>
</li>
<li><p>Renders <code>children</code> (the rest of the application) inside the <code>CopilotKit</code> wrapper.</p>
</li>
</ul>
</li>
</ol>
<h3 id="heading-some-important-notes"><strong>Some Important Notes</strong></h3>
<p>Designing and deploying a database can vary depending on the tools and requirements. For this project, I’ve chosen the simplest and most accessible approach.</p>
<h3 id="heading-why-copilotkit"><strong>Why CopilotKit?</strong></h3>
<p>CopilotKit is a powerful tool that converts natural language processing (NLP) queries into actionable backend code that runs on meta LLM. If you have an alternative that serves a similar purpose, feel free to use it. It effectively bridges the gap between natural language input and technical execution, making it an ideal choice for projects like this.</p>
<h3 id="heading-why-groqcloud"><strong>Why GroqCloud?</strong></h3>
<p>I selected GroqCloud because it’s free and offers access to multiple large language models (LLMs) with a single API key. While alternatives like ChatGPT are available, they may require paid plans. GroqCloud’s versatility and affordability make it the perfect fit for this tutorial.</p>
<h3 id="heading-security-best-practices"><strong>Security Best Practices</strong></h3>
<p>Never expose your credentials publicly. Always store sensitive information like API keys in an <code>.env</code> file to keep your project secure.</p>
<h3 id="heading-future-enhancements"><strong>Future Enhancements</strong></h3>
<p>While this tutorial focuses on setting up and working with React files, CopilotKit has a much broader range of capabilities that I will explain in the upcoming blog posts.</p>
<p>I aim to build at least 15 AI products in 2025.</p>
<p>Support for static files is coming soon.</p>
<p>As promised in the previous tutorial, I’ve implemented the CopilotKit CRUD feature in this tutorial as well.</p>
<p>In my next tutorial, I will demonstrate how to build something more cool with CopilotKit to create a more dynamic and functional application.</p>
<h2 id="heading-playing-with-the-replit-clone"><strong>Playing with the Replit Clone</strong></h2>
<p>You can explore the live project via the following link and ask the chatbot to build something in React. <a target="_blank" href="https://replit-mongodb.vercel.app/">Live Project Link</a>.</p>
<p>For a deeper understanding of the code, check out the GitHub repository here: <a target="_blank" href="https://github.com/prankurpandeyy/replit-mongodb">GitHub Repository</a>.</p>
<p>Also, here’s a screenshot showcasing its practical use. In this example, instead of manually creating project files, you can simply ask the <strong>CopilotKit</strong> chatbot to generate those files for you. You can then edit and play around with them.</p>
<p>For example, you can give the CopilotKit chatbot commands like: “Create a React app”.</p>
<h3 id="heading-handling-errors">Handling Errors</h3>
<ul>
<li><p><strong>File Explorer Delays</strong>: Occasionally, due to database or Vercel deployment issues, files may be generated but not immediately visible in the File Explorer. In such cases, simply refresh the page, and the missing components will appear. This applies to all CRUD operations on files and their content as well.</p>
</li>
<li><p><strong>Real-Time Saving</strong>: Any changes you make to files are saved to the database in real-time, ensuring that your work is never lost.</p>
</li>
<li><p><strong>Command Errors</strong>: If the chatbot shows an error when processing your commands, simply retry the command until you receive a response.</p>
</li>
<li><p><strong>Adding Extra Files:</strong>To add new files to the current project, simply ask the chatbot:<br>  <em>“Add a new file to the current project with the file name and extension.”</em></p>
<p>  For example: <em>“Add a new file named</em> <code>readme.md</code> in this project”</p>
</li>
</ul>
<h3 id="heading-video-demo">Video Demo</h3>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/AjnzEDmiu2Y" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>I hope you’ve enjoyed building this simple Replit AI clone. In this project, we used a MongoDB database, but the approach can easily be applied to other databases, as long as you can retrieve the data.</p>
<p>I plan to create many more projects involving AI and other cutting-edge tools. AI is truly a game-changer in the IT field, and I’m excited to share more insights and practical implementations of the latest technologies.</p>
<p>That’s all from my side. If you found this article helpful, feel free to share it and connect with me. I’m always open to new opportunities:</p>
<ul>
<li><p>Follow me on X: <a target="_blank" href="https://x.com/prankurpandeyy">Prankur's Twitter</a></p>
</li>
<li><p>Connect with me on LinkedIn: <a target="_blank" href="https://linkedin.com/in/prankurpandeyy">Prankur's LinkedIn</a></p>
</li>
<li><p>Follow me on Github: <a target="_blank" href="https://github.com/prankurpandeyy">Prankur’s Github</a></p>
</li>
<li><p>View my Portfolio: <a target="_blank" href="https://prankurpandeyy.netlify.app/">Prankur's Portfolio</a></p>
</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Talk to Any Database Using AI – Build Your Own SQL Query Data Extractor ]]>
                </title>
                <description>
                    <![CDATA[ Recently, I took a break from writing to focus on my exams. During this time, I had an interesting experience: I had the chance to explain SQL (Structured Query Language) to my peers. While exploring SQL in-depth, I encountered a common frustration: ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/talk-to-databases-using-ai-build-a-sql-query-data-extractor/</link>
                <guid isPermaLink="false">677ef38c05d7f213e7d2a766</guid>
                
                    <category>
                        <![CDATA[ AI ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Databases ]]>
                    </category>
                
                    <category>
                        <![CDATA[ SQL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ projects ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Prankur Pandey ]]>
                </dc:creator>
                <pubDate>Wed, 08 Jan 2025 21:52:12 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1733842504544/0e9da173-718c-454e-841c-15c148e0fe93.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Recently, I took a break from writing to focus on my exams. During this time, I had an interesting experience: I had the chance to explain SQL (Structured Query Language) to my peers. While exploring SQL in-depth, I encountered a common frustration: writing SQL queries to fetch specific data from a database.</p>
<p>This sparked an idea. What if I could build a tool where I didn’t have to write SQL queries manually? Instead, I could type in plain, natural English and let the database do the heavy lifting for me.</p>
<p>Given that we live in the era of AI, leveraging artificial intelligence was the only way to turn this vision into reality.</p>
<p>In this tutorial, I’ll walk you through creating an AI-powered SQL query data extractor. This tool will enable you to fetch data from a database effortlessly, without writing a single line of SQL code.</p>
<h3 id="heading-what-well-cover"><strong>What we’ll cover:</strong></h3>
<ul>
<li><p><a class="post-section-overview" href="#heading-prerequisiteshttpswwwfreecodecamporgnewsreact-best-practices-ever-developer-should-knowheading-prerequsites-amp-tools">Prerequisites &amp; Tools</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-does-the-app-work">How Does the App Work</a>?</p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-set-up-your-tools">How to Set Up Your Tools</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-set-up-the-database">How to Set Up the Database</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-structure-and-features-of-the-app">Structure and Features of the App</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-build-the-back-end">How to Build the Back End</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-build-the-front-end">How to Build the Front End</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-some-important-notes">Some Important Notes</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-playing-with-the-database">Playing with the Database</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-prerequisites-amp-tools">Prerequisites &amp; Tools</h2>
<p>In this tutorial, we’ll build an AI-powered SQL query data extractor tool. It’ll allow us to interact with a database using natural language, like plain English, and receive the same results as if we had written SQL queries.</p>
<p>Here’s an overview of the tools we’ll use to create this cool app:</p>
<h3 id="heading-database">Database</h3>
<p>The database is a critical component where we’ll store data and later extract it for our AI model to use when performing NLP operations. Instead of hosting a database locally, I chose a cloud-based free database that allows data extraction via REST APIs. For this project, I opted for <a target="_blank" href="http://restdb.io">restdb.io</a> because it offers seamless SQL database provisioning and supports REST APIs.</p>
<h3 id="heading-ai-agent">AI Agent</h3>
<p>An AI Agent will act as the intermediary between the database and the AI model. This agent will manage the AI model’s operations and facilitate seamless communication. For this, I am using <a target="_blank" href="https://www.copilotkit.ai/"><strong>CopilotKit</strong></a>, which simplifies the integration process.</p>
<h3 id="heading-ai-llm-model">AI (LLM) Model</h3>
<p>The AI model translates plain English queries into SQL queries. For this, I am using <a target="_blank" href="https://groq.com/"><strong>GroqAI</strong></a>, which supports various popular AI models and provides the flexibility needed for this project.</p>
<h3 id="heading-nextjs">Next.js</h3>
<p>To develop a web application that supports both frontend and backend functionalities, I chose <strong>Next.js</strong>. It’s an ideal framework for building robust, scalable web apps with server-side rendering capabilities.</p>
<h3 id="heading-deployment">Deployment</h3>
<p>For deployment, you can choose any service. I prefer <strong>Vercel</strong>, as it integrates seamlessly with Next.js and is free for hobby projects.</p>
<p>By combining these tools, we’ll build a powerful, user-friendly application that effortlessly bridges natural language and SQL databases.</p>
<h2 id="heading-what-well-do-here">What We’ll Do Here:</h2>
<p>These are the steps we’ll follow in this tutorial to build our app:</p>
<p><strong>Step 1 – Set Up the Database:</strong> Either set up the database locally, deploy it, and access it, or use an online database tool that allows data access and extraction via REST APIs.</p>
<p><strong>Step 2 – Obtain Cloud API Keys:</strong> Get the necessary API keys for your AI model to enable seamless integration.</p>
<p><strong>Step 3 – Build a Web App:</strong> Create a web application and set up the backend to integrate CopilotKit. Configure it within the app for optimal functionality.</p>
<p><strong>Step 4 – Train CopilotKit on Your Database:</strong> Provide your database’s data to CopilotKit. It will read and understand the data to facilitate natural language processing.</p>
<p><strong>Step 5 – Integrate CopilotKit Chat:</strong> Add the CopilotKit chat interface into your application and configure it to ensure smooth operation.</p>
<p><strong>Step 6 – Test Locally:</strong> Test the app on your local machine to identify and fix any issues.</p>
<p><strong>Step 7 – Deploy the App:</strong> Once everything is working as expected, deploy the application to a hosting platform.</p>
<h2 id="heading-how-does-the-app-work">How Does the App Work?</h2>
<p>Have you ever wondered how writing plain English could allow you to fetch data from a SQL database?</p>
<p>The magic lies in CopilotKit. It lets you create AI-powered copilots that can perform operations on your applications. Think of CopilotKit as your personal AI assistant or chatbot. So how does it work?</p>
<p>Well, first we have CopilotKit which serves as our chatbot powered by advanced AI models.</p>
<p>Then when you provide data to the chatbot, it uses that data to train itself, building an understanding of your database structure and content.</p>
<p>Finally, when a natural language query (like "Who is using this email address?") is inputted, the AI model processes it, translates it into a corresponding SQL query, and retrieves the desired data from the database.</p>
<p>With CopilotKit’s powerful AI capabilities, your application can seamlessly bridge natural language and SQL, making database interactions more intuitive.</p>
<h2 id="heading-how-to-set-up-your-tools">How to Set Up Your Tools</h2>
<p>Now we’ll go through everything you need to set up the project.</p>
<h3 id="heading-1-install-nextjs-and-dependencies"><strong>1. Install Next.js and dependencies</strong>:</h3>
<p>First, you’ll need to create a NextJS app. Go to the terminal and run the following command:</p>
<pre><code class="lang-plaintext">npx create-next-app@latest my-next-app
</code></pre>
<p>Replace <code>my-next-app</code> with your desired project name.</p>
<p>Navigate to the project folder:</p>
<pre><code class="lang-plaintext">cd my-next-app
</code></pre>
<p>Start the development server:</p>
<pre><code class="lang-plaintext">npm run dev
</code></pre>
<p>Open your browser and navigate to <a target="_blank" href="http://localhost:3000"><code>http://localhost:3000</code></a> to see your Next.js app in action.</p>
<h3 id="heading-2-install-copilotkit-and-dependencies"><strong>2. Install CopilotKit and dependencies</strong></h3>
<p>Go to the project root folder through the terminal and run the below command. It will install all the important CopilotKit dependencies and other important packages like dotenv and Axios.</p>
<pre><code class="lang-plaintext">npm install @copilotkit/react-ui @copilotkit/react-core dotenv axios
</code></pre>
<ul>
<li><p>The <strong>CopitlotKit</strong> dependency is solely for handling CopilotKit operations and configurations.</p>
</li>
<li><p>The <strong>Dotenv</strong> dependency is used to handle environment variables as we have to keep important keys in the project, such as environment variables.</p>
</li>
<li><p><strong>Axios</strong> is for handling the API calls.</p>
</li>
</ul>
<h3 id="heading-3-set-up-the-database"><strong>3. Set Up the</strong> <strong>Database</strong></h3>
<p>Visit <a target="_blank" href="http://RestDB.io">RestDB.io</a> and either login or create an account.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736349488854/435a5574-54b8-40b4-a1e5-f31aa79eeae8.png" alt="restdb.io login page " class="image--center mx-auto" width="1366" height="768" loading="lazy"></p>
<p>Above you can see the login page for RestDB.io you can either log in if you already have an account or create a new account .</p>
<p>Once logged in you will redirected to this page. There you’ll see the button to create a new database.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736349634003/840cc3d6-c7e0-474f-9335-eca750aeacc5.png" alt="restdb.io database creation page " class="image--center mx-auto" width="1366" height="768" loading="lazy"></p>
<p>When you click on the Create New button, a pop will appear. There, you’ll have to enter the database name as shown in the image below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736349886708/c9846627-4351-40e0-a4bd-8342b6b5bf25.png" alt="restdb.io database creation pop-up" class="image--center mx-auto" width="1366" height="768" loading="lazy"></p>
<p>When you enter the database name, then click “Go”. I have put <strong>demosql</strong> as the database name. At this point, you’ll get your newly created database link as shown in the image below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736350379651/27708c52-c8a0-405c-93d7-374833572007.png" alt="restdb.io database listing page" class="image--center mx-auto" width="1366" height="768" loading="lazy"></p>
<p>Now Click on the database URL it will take you to this page shown in the image :</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736350576835/87abd648-1b8d-4d07-b30a-6f1076abdf06.png" alt="restdb.io main database page " class="image--center mx-auto" width="1366" height="768" loading="lazy"></p>
<p>Now it is time to make an API Key for accessing the database. To do this, click on <strong>Settings</strong> and it will take you to a new page shown below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736352142460/d61be8ac-c78f-4c71-a1f0-dbc230496bc5.png" alt="restdb.io api settings page " class="image--center mx-auto" width="1366" height="768" loading="lazy"></p>
<p>On this page click on the <strong>Add New</strong> button it will open a pop up shown below in the image:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736352445417/b739b25d-e01d-4b72-b4a6-db3077866a60.png" alt="restdb.io api key creation popup" class="image--center mx-auto" width="1366" height="768" loading="lazy"></p>
<p>Now you can configure your API actions here like GET, POST, PUT, and DELETE, name it whatever you want, and save it. Your database is now ready to interact via the REST API.</p>
<p>Copy the database URL and API KEY and put it into the .env file.</p>
<p>You can add tables, define the schema with columns and data types (for example, VARCHAR, INTEGER), and populate data manually or via uploads (Excel, CSV, or JSON). For this project, we’ve added 21 records.</p>
<h3 id="heading-4-set-up-the-llm-for-action">4. Set Up the LLM for Action:</h3>
<p>This part is pivotal for the project, as we’re setting up the LLM (Large Language Model) to handle the conversion of NLP (plain English) queries into SQL queries.</p>
<p>Numerous LLMs are available in the market, each with its strengths. While some are free, others are paid, which made selecting the right one for this project a challenge.</p>
<p>After extensive experimentation, I chose the <strong>Groq Adapter</strong> because:</p>
<ul>
<li><p>It consolidates various LLMs under a single platform.</p>
</li>
<li><p>It provides access through a unified API key.</p>
</li>
<li><p>It’s compatible with CopilotKit.</p>
</li>
</ul>
<h4 id="heading-how-to-set-up-groq-cloud">How to Set Up Groq Cloud</h4>
<p>To get started with Groq Cloud, <a target="_blank" href="https://console.groq.com/login">visit its website</a> and either login if already have an account or create a new account if you’re new. Once logged in, navigate to the Groq Dashboard.</p>
<p>This is the homepage of groq cloud:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736352733541/92012af5-b3c4-4277-a50f-834c1900a2de.png" alt="groq cloud homepage" class="image--center mx-auto" width="1366" height="768" loading="lazy"></p>
<p>Once logged in, a new page will open that’ll look like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736353229314/67313c60-47b8-4f23-b3c0-e46fcdd5201a.png" alt="groq cloud dahsboard page " class="image--center mx-auto" width="1366" height="768" loading="lazy"></p>
<p>As you can see, the sidebar has an API Keys link. Click on it, and it will open a new page as shown in the image below. You can also select any LLM of your choice which is given at the top right before the view code option.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736353347970/3406fa54-ddc2-4a00-8b27-22536486fc64.png" alt="groqcloud api section" class="image--center mx-auto" width="1366" height="768" loading="lazy"></p>
<p>Here, click on the Create API Key button it will open a pop up like you see below. Just enter the name of your API key and click on Submit it will create a new API key for you. Then copy this API key and paste it inside your .env file.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736353563741/cd1a185a-2c77-470a-a5ce-eca564cf524a.png" alt="groq cloud api key creation page " class="image--center mx-auto" width="1366" height="768" loading="lazy"></p>
<p>To enable seamless access to various LLMs on Groq Cloud, generate an API key by going to the Groq API Keys section. Create a new API key specifically for the LLM, ensuring that it is properly configured.</p>
<p>With the LLM set-up and all components ready, you are now prepared to build the project.</p>
<h2 id="heading-structure-and-features-of-the-app">Structure and Features of the App</h2>
<p>We will approach this project in a straightforward way, focusing on simplicity and functionality. The primary goal is to create a basic webpage that allows us to:</p>
<ul>
<li><p>Verify if our API calls were successful.</p>
</li>
<li><p>View the data received from the API.</p>
</li>
<li><p>Interact with the CopilotKit chatbot integrated into the front end.</p>
</li>
</ul>
<h3 id="heading-webpage-structure">Webpage Structure</h3>
<p>Since we have already set up the <strong>Next.js app</strong>, the next step is to build a minimalistic webpage comprising:</p>
<ol>
<li><p><strong>Header Section:</strong> Displays the title of the application.</p>
</li>
<li><p><strong>Main Area:</strong></p>
<ul>
<li><p><strong>Tables:</strong> Show the data fetched from the database.</p>
</li>
<li><p><strong>Status Indicators:</strong> Show the status of API calls and database operations. If there are any issues, such as API or database failures, errors will be displayed in <strong>red text</strong> for clarity.</p>
</li>
</ul>
</li>
</ol>
<h3 id="heading-key-features">Key Features</h3>
<ul>
<li><p><strong>Error Handling:</strong> Any failures, such as API or database issues, will be clearly marked with red text for immediate visibility.</p>
</li>
<li><p><strong>Data Presentation:</strong> For demonstration purposes, the entire database will be displayed in neatly structured tables.</p>
</li>
<li><p><strong>CopilotKit Chatbot Integration:</strong> This chatbot will be configured to allow natural language interactions with the database. The <strong>blue-colored ball</strong> on the page represents the <strong>CopilotKit chatbot</strong>. This chatbot is the key interface for interacting with the database.</p>
<ul>
<li><p>Using natural language queries, we can ask questions about the database data.</p>
</li>
<li><p>The chatbot processes these queries, converts them into SQL queries, and fetches the results seamlessly.</p>
</li>
</ul>
</li>
</ul>
<p>The frontend will look something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734711368585/db3bd5fb-fee1-42a3-a638-b5b410c6fe69.png" alt="db3bd5fb-fee1-42a3-a638-b5b410c6fe69" class="image--center mx-auto" width="1366" height="768" loading="lazy"></p>
<h2 id="heading-how-to-build-the-back-end">How to Build the Back End</h2>
<p>Before we start building the back end, you’ll need to put all important credentials into your <strong>.env</strong> file which will look something like this:</p>
<pre><code class="lang-plaintext">NEXT_PUBLIC_COPILOTKIT_BACKEND_URL=http://localhost:3000/api/copilotkit
NEXT_PUBLIC_GROQ_CLOUD_API_KEY=
NEXT_PUBLIC_RESTDB_API_KEY=
NEXT_PUBLIC_RESTDB_BASE_URL=https://demosql-fdcb.restdb.io/rest/demo-data
</code></pre>
<p>So what are all these? Let’s go through them one by one:</p>
<ol>
<li><p><code>NEXT_PUBLIC_COPILOTKIT_BACKEND_URL=</code><a target="_blank" href="http://localhost:3000/api/copilotkit"><code>http://localhost:3000/api/copilotkit</code></a>: This specifies the base URL for the CopilotKit backend API.</p>
<ul>
<li><p>The <code>NEXT_PUBLIC_</code> prefix makes this variable accessible both on the server side and in the client-side code of a Next.js application.</p>
</li>
<li><p>The value <a target="_blank" href="http://localhost:3000/api/copilotkit"><code>http://localhost:3000/api/copilotkit</code></a> indicates the API is running locally during development.</p>
</li>
</ul>
</li>
<li><p><code>NEXT_PUBLIC_GROQ_CLOUD_API_KEY=</code>: This variable is intended to store an API key for a GROQ Cloud service. GROQ Cloud could be related to querying or data processing you will have to paste your own Groq API key.</p>
<ul>
<li>The variable is empty, indicating the API key is not set yet. It will likely need to be filled in with the appropriate value before the application can access the GROQ Cloud service.</li>
</ul>
</li>
<li><p><code>NEXT_PUBLIC_RESTDB_API_KEY=</code>: Intended to hold the API key for accessing a <strong>RESTdb</strong> service. You will have to paste your own Groq API key.</p>
<ul>
<li><p>RESTdb is a database service that provides APIs for database interactions.</p>
</li>
<li><p>The variable is also empty, meaning the key must be filled in with a valid API key for the application to authenticate and interact with the RESTdb service.</p>
</li>
</ul>
</li>
<li><p><code>NEXT_PUBLIC_RESTDB_BASE_URL=</code><a target="_blank" href="https://demosql-fdcb.restdb.io/rest/demo-data"><code>https://demosql-fdcb.restdb.io/rest/demo-data</code></a>: Defines the base URL for interacting with the RESTdb database. This URL will be created when you make your database. Here, I have given the URL of my database.</p>
<ul>
<li><p>The value <a target="_blank" href="https://demosql-fdcb.restdb.io/rest/demo-data"><code>https://demosql-fdcb.restdb.io/rest/demo-data</code></a> points to a specific RESTdb database endpoint called <code>demo-data</code>.</p>
</li>
<li><p>This could be the endpoint where the application fetches or manipulates demo data for testing or development.</p>
</li>
</ul>
</li>
</ol>
<p>We have successfully added the environment variables to our project. Now, it’s time to configure the CopilotKit API backed.</p>
<h3 id="heading-how-to-configure-the-copilotkit-back-end">How to Configure the CopilotKit Back End</h3>
<p>Open your Next.js app in any code editor – I prefer VSCode – and go to the root folder, which looks like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734968233629/f338c977-02dd-4ee1-ae66-7417f03e026b.png" alt="f338c977-02dd-4ee1-ae66-7417f03e026b" class="image--center mx-auto" width="349" height="597" loading="lazy"></p>
<p>Inside the app folder, make a new folder called <code>api</code>. Inside the API folder, make another folder called <code>copilotkit</code>. Then in there, make a new file called <code>route.js</code> and inside the file paste this code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> {
  CopilotRuntime,
  GroqAdapter,
  copilotRuntimeNextJSAppRouterEndpoint,
} <span class="hljs-keyword">from</span> <span class="hljs-string">"@copilotkit/runtime"</span>;

<span class="hljs-keyword">import</span> Groq <span class="hljs-keyword">from</span> <span class="hljs-string">"groq-sdk"</span>;

<span class="hljs-keyword">const</span> groq = <span class="hljs-keyword">new</span> Groq({ <span class="hljs-attr">apiKey</span>: process.env.NEXT_PUBLIC_GROQ_CLOUD_API_KEY });
<span class="hljs-built_in">console</span>.log(process.env.NEXT_PUBLIC_GROQ_CLOUD_API_KEY);
<span class="hljs-keyword">const</span> copilotKit = <span class="hljs-keyword">new</span> CopilotRuntime();

<span class="hljs-keyword">const</span> serviceAdapter = <span class="hljs-keyword">new</span> GroqAdapter({
  groq,
  <span class="hljs-attr">model</span>: <span class="hljs-string">"llama-3.1-70b-versatile"</span>,
});

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> POST = <span class="hljs-keyword">async</span> (req) =&gt; {
  <span class="hljs-keyword">const</span> { handleRequest } = copilotRuntimeNextJSAppRouterEndpoint({
    <span class="hljs-attr">runtime</span>: copilotKit,
    serviceAdapter,
    <span class="hljs-attr">endpoint</span>: <span class="hljs-string">"/api/copilotkit"</span>,
  });

  <span class="hljs-keyword">return</span> handleRequest(req);
};
</code></pre>
<p>Here’s a detailed explanation of each part:</p>
<p>This code defines a server-side handler for a Next.js API route using CopilotKit and Groq SDKs. It sets up a runtime environment to process requests to a specified endpoint.</p>
<p><strong>1. Imports:</strong></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> {
  CopilotRuntime,
  GroqAdapter,
  copilotRuntimeNextJSAppRouterEndpoint,
} <span class="hljs-keyword">from</span> <span class="hljs-string">"@copilotkit/runtime"</span>;

<span class="hljs-keyword">import</span> Groq <span class="hljs-keyword">from</span> <span class="hljs-string">"groq-sdk"</span>;
</code></pre>
<ul>
<li><p><code>CopilotRuntime</code> and <code>GroqAdapter</code>: These are classes from the CopilotKit library used to set up and configure the runtime environment and adapters for AI-based services.</p>
<ul>
<li><p><code>CopilotRuntime</code><strong>:</strong> A runtime environment to manage the CopilotKit operations.</p>
</li>
<li><p><code>GroqAdapter</code><strong>:</strong> Adapts and connects a Groq service (used for querying or data processing) with CopilotKit.</p>
</li>
</ul>
</li>
<li><p><code>copilotRuntimeNextJSAppRouterEndpoint</code>: A utility function to create a handler for a Next.js App Router API endpoint that integrates CopilotKit.</p>
</li>
<li><p><code>Groq</code> from <code>"groq-sdk"</code>: A library for interacting with Groq services is initialized here for querying or processing data.</p>
</li>
</ul>
<p><strong>2. Initialize Groq:</strong></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> groq = <span class="hljs-keyword">new</span> Groq({ <span class="hljs-attr">apiKey</span>: process.env.NEXT_PUBLIC_GROQ_CLOUD_API_KEY });
<span class="hljs-built_in">console</span>.log(process.env.NEXT_PUBLIC_GROQ_CLOUD_API_KEY);
</code></pre>
<ul>
<li><p><code>Groq</code> Initialization:</p>
<ul>
<li><p>The <code>Groq</code> an object is created with an API key (<code>NEXT_PUBLIC_GROQ_CLOUD_API_KEY</code>) fetched from environment variables.</p>
</li>
<li><p>This key authenticates the app with the Groq Cloud service.</p>
</li>
</ul>
</li>
<li><p><code>console.log(</code><a target="_blank" href="http://process.env.NEXT"><code>process.env.NEXT</code></a><code>_PUBLIC_GROQ_CLOUD_API_KEY)</code>: Logs the API key to the server console. <strong>Note:</strong> Avoid logging sensitive data in production to ensure security.</p>
</li>
</ul>
<p><strong>3. Initialize CopilotKit Runtime</strong></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> copilotKit = <span class="hljs-keyword">new</span> CopilotRuntime();
</code></pre>
<ul>
<li><code>CopilotRuntime</code> Initialization: Creates an instance of CopilotKit's runtime environment to manage CopilotKit's features and services.</li>
</ul>
<p><strong>4. Configure Service Adapter</strong></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> serviceAdapter = <span class="hljs-keyword">new</span> GroqAdapter({
  groq,
  <span class="hljs-attr">model</span>: <span class="hljs-string">"llama-3.1-70b-versatile"</span>,
});
</code></pre>
<ul>
<li><p><code>GroqAdapter</code>:</p>
<ul>
<li><p>Configures an adapter to connect CopilotKit with Groq.</p>
</li>
<li><p>The <code>model</code> parameter specifies the AI model to use. Here, it is <code>"llama-3.1-70b-versatile"</code>, a versatile language model with 70 billion parameters.</p>
</li>
</ul>
</li>
</ul>
<p><strong>5. Exported POST Handler</strong></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> POST = <span class="hljs-keyword">async</span> (req) =&gt; {
  <span class="hljs-keyword">const</span> { handleRequest } = copilotRuntimeNextJSAppRouterEndpoint({
    <span class="hljs-attr">runtime</span>: copilotKit,
    serviceAdapter,
    <span class="hljs-attr">endpoint</span>: <span class="hljs-string">"/api/copilotkit"</span>,
  });

  <span class="hljs-keyword">return</span> handleRequest(req);
};
</code></pre>
<ul>
<li><p>Defines a <code>POST</code> handler for a Next.js App Router API endpoint.</p>
</li>
<li><p><strong>Key Components:</strong></p>
<ol>
<li><p><code>copilotRuntimeNextJSAppRouterEndpoint</code>:</p>
<ul>
<li><p>Sets up the handler for the <code>/api/copilotkit</code> endpoint.</p>
</li>
<li><p>Takes <code>runtime</code> (CopilotKit) and <code>serviceAdapter</code> (GroqAdapter) as inputs to configure the endpoint's behaviour.</p>
</li>
</ul>
</li>
<li><p><code>handleRequest</code>:</p>
<ul>
<li><p>A function that processes incoming HTTP requests (in this case, <code>POST</code> requests).</p>
</li>
<li><p>This allows the CopilotKit runtime and service adapter to handle requests dynamically.</p>
</li>
</ul>
</li>
</ol>
</li>
<li><p><code>return handleRequest(req);</code>: Invokes the handler and processes the incoming request (<code>req</code>), returning the appropriate response.</p>
</li>
</ul>
<p>How it all works:</p>
<ol>
<li><p>The Groq SDK is initialized with an API key for authentication.</p>
</li>
<li><p>A CopilotKit runtime is set up.</p>
</li>
<li><p>A GroqAdapter connects the runtime to the Groq service with a specified AI model.</p>
</li>
<li><p>The <code>/api/copilotkit</code> endpoint is configured to handle POST requests, pass the requests to CopilotKit's runtime, and return the processed response.</p>
</li>
</ol>
<p>With this setup, you have successfully integrated CopilotKit into your Next.js application. The backend is now fully functional, enabling seamless communication with the database via REST APIs and the CopilotKit interface.</p>
<h2 id="heading-how-to-build-the-front-end">How to Build the Front End</h2>
<p>For the front end, we’ll keep it as simple as we can. We just need a few things to get this project done: we need a Header component and a Table component.</p>
<ol>
<li><p><strong>Header component</strong>: To display the title or description of the application.</p>
</li>
<li><p><strong>Table component</strong>: To visualize the data fetched from the database.</p>
</li>
</ol>
<p>To achieve this, we’ll use ShadCN, a popular frontend component library known for its clean design and ease of use.</p>
<p>ShadCN provides pre-built components that help speed up development without compromising on quality. By leveraging this library, we can focus on functionality while ensuring the UI looks polished and professional.</p>
<h3 id="heading-how-to-install-shadcn-in-a-next-project"><strong>How to Install ShadCN in a Next Project</strong></h3>
<p>Run the following command to install ShadCN components:</p>
<pre><code class="lang-javascript">npx shadcn@latest init
</code></pre>
<p>This command:</p>
<ul>
<li><p>Initialize ShadCN in your project.</p>
</li>
<li><p>Creates a <code>components</code> folder for storing ShadCN components.</p>
</li>
<li><p>Updates the <code>tailwind.config.js</code> file with required configurations.</p>
</li>
</ul>
<p>You will be asked a few questions to configure <code>components.json</code>:</p>
<pre><code class="lang-bash">Which style would you like to use? › New YorkWhich 
color would you like to use as base color? › Zinc
Do you want to use CSS variables <span class="hljs-keyword">for</span> colors? › no / yesadd components
</code></pre>
<p>To add specific components, use the following command:</p>
<pre><code class="lang-bash">npx shadcn@latest add &lt;component-name&gt;
</code></pre>
<p>For example, to add a table component:</p>
<pre><code class="lang-bash">npx shadcn@latest add table
</code></pre>
<p>The <code>components</code> folder now contains a ready-to-use <code>button</code> component.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734970231792/2e5ea193-f829-435e-b4dc-68bd8ce793ca.png" alt="2e5ea193-f829-435e-b4dc-68bd8ce793ca" class="image--center mx-auto" width="349" height="597" loading="lazy"></p>
<p>In the frontend, we have a <code>components</code> folder that contains the Table component. This component is responsible for displaying the database data in a structured tabular format.</p>
<p>Apart from the <code>Table</code> component, there are two additional files in the front end. These files serve different purposes and will be integrated later in the project for specific functionalities.</p>
<p>This modular structure ensures the front end remains clean and organized, making it easier to manage and expand as needed.</p>
<p>Let’s explore each file:</p>
<ol>
<li><p><strong>Table.jsx:</strong> This file is auto-generated by ShadCN when we installed the Table component. It contains the default configuration for the table component provided by the ShadCN library. <strong>Do not modify this file</strong>, as it is essential for the component’s proper functionality.</p>
</li>
<li><p><strong>Tabledata.jsx:</strong> This file is where we populate the table with data fetched from the database through API calls. The <code>Tabledata.jsx</code> file bridges the gap between the backend API and the frontend table display.</p>
</li>
</ol>
<p>Let’s take a closer look at the code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> {
  Table,
  TableBody,
  TableCaption,
  TableCell,
  TableFooter,
  TableHead,
  TableHeader,
  TableRow,
} <span class="hljs-keyword">from</span> <span class="hljs-string">"@/components/ui/table"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Tabledata</span>(<span class="hljs-params">{ data }</span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Table</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-center"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">TableCaption</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-sm text-green-600 font-bold ml-8"</span>&gt;</span>
        Live data from database.
      <span class="hljs-tag">&lt;/<span class="hljs-name">TableCaption</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">TableHeader</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">TableRow</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-center "</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">TableHead</span>&gt;</span>Id<span class="hljs-tag">&lt;/<span class="hljs-name">TableHead</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">TableHead</span>&gt;</span>name<span class="hljs-tag">&lt;/<span class="hljs-name">TableHead</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">TableHead</span>&gt;</span>email<span class="hljs-tag">&lt;/<span class="hljs-name">TableHead</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">TableHead</span>&gt;</span>phone_number<span class="hljs-tag">&lt;/<span class="hljs-name">TableHead</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">TableHead</span>&gt;</span>address<span class="hljs-tag">&lt;/<span class="hljs-name">TableHead</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">TableHead</span>&gt;</span>city<span class="hljs-tag">&lt;/<span class="hljs-name">TableHead</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">TableHead</span>&gt;</span>state<span class="hljs-tag">&lt;/<span class="hljs-name">TableHead</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">TableHead</span>&gt;</span>zip_code<span class="hljs-tag">&lt;/<span class="hljs-name">TableHead</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">TableHead</span>&gt;</span>country<span class="hljs-tag">&lt;/<span class="hljs-name">TableHead</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">TableHead</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-right"</span>&gt;</span>created at <span class="hljs-tag">&lt;/<span class="hljs-name">TableHead</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">TableRow</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">TableHeader</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">TableBody</span>&gt;</span>
        {data.map((db) =&gt; (
          <span class="hljs-tag">&lt;<span class="hljs-name">TableRow</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{db._id}</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">TableCell</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"font-medium text-wrap w-12"</span>&gt;</span>
              {db._id}
            <span class="hljs-tag">&lt;/<span class="hljs-name">TableCell</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">TableCell</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"font-medium"</span>&gt;</span>{db.name}<span class="hljs-tag">&lt;/<span class="hljs-name">TableCell</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">TableCell</span>&gt;</span>{db.email}<span class="hljs-tag">&lt;/<span class="hljs-name">TableCell</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">TableCell</span>&gt;</span>{db.phone_number}<span class="hljs-tag">&lt;/<span class="hljs-name">TableCell</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">TableCell</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-right"</span>&gt;</span>{db.address}<span class="hljs-tag">&lt;/<span class="hljs-name">TableCell</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">TableCell</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-right"</span>&gt;</span>{db.city}<span class="hljs-tag">&lt;/<span class="hljs-name">TableCell</span>&gt;</span>{" "}
            <span class="hljs-tag">&lt;<span class="hljs-name">TableCell</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-right"</span>&gt;</span>{db.state}<span class="hljs-tag">&lt;/<span class="hljs-name">TableCell</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">TableCell</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-right"</span>&gt;</span>{db.zip_code}<span class="hljs-tag">&lt;/<span class="hljs-name">TableCell</span>&gt;</span>{" "}
            <span class="hljs-tag">&lt;<span class="hljs-name">TableCell</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-right"</span>&gt;</span>{db.country}<span class="hljs-tag">&lt;/<span class="hljs-name">TableCell</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">TableCell</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-right"</span>&gt;</span>{db.created_at}<span class="hljs-tag">&lt;/<span class="hljs-name">TableCell</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">TableRow</span>&gt;</span>
        ))}
      <span class="hljs-tag">&lt;/<span class="hljs-name">TableBody</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Table</span>&gt;</span></span>
  );
}
</code></pre>
<p>This code renders a styled, dynamic table with data passed from a database or API.</p>
<ul>
<li><p><strong>Imports</strong>: Uses custom table components (<code>Table</code>, <code>TableRow</code>, <code>TableCell</code>, and so on) from <code>@/components/ui/table</code>.</p>
</li>
<li><p><strong>Props</strong>: Accepts a <code>data</code> prop, an array of objects representing table rows.</p>
</li>
<li><p><strong>Table Caption</strong>: Displays a caption, "Live data from database," styled with Tailwind CSS.</p>
</li>
<li><p><strong>Table Header</strong>: Defines column headers such as <code>Id</code>, <code>name</code>, <code>email</code>, and more.</p>
</li>
<li><p><strong>Dynamic Rows</strong>: Maps over the <code>data</code> array to generate <code>TableRow</code> elements dynamically, using <code>_id</code> as the unique key.</p>
</li>
<li><p><strong>Data Cells</strong>: Displays object fields (<code>_id</code>, <code>name</code>, <code>email</code>, and so on) in <code>TableCell</code> components with custom styles.</p>
</li>
<li><p><strong>Tailwind CSS</strong>: Styles applied for alignment, font weight, and spacing.</p>
</li>
</ul>
<h3 id="heading-nlqueryformjsx"><strong>NLQueryForm.jsx</strong></h3>
<p>In this file, we handle the API calls, define CopilotKit actions, and pass the fetched data to the Table component. This file acts as the central logic hub for connecting the backend API, AI actions, and the frontend display.</p>
<p>Key functionalities of <code>NLQueryForm.jsx</code>:</p>
<ol>
<li><p><strong>API integration</strong>: Fetches data from the database and handles errors or loading states.</p>
</li>
<li><p><strong>CopilotKit actions</strong>: Defines AI actions that allow querying and interacting with the database using natural language.</p>
</li>
<li><p><strong>Data passing</strong>: Sends the processed data to the <code>Table</code> component for display.</p>
</li>
</ol>
<p>Below is the code:</p>
<pre><code class="lang-javascript"><span class="hljs-string">"use client"</span>;
<span class="hljs-keyword">import</span> React, { useState, useEffect } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { useCopilotReadable, useCopilotAction } <span class="hljs-keyword">from</span> <span class="hljs-string">"@copilotkit/react-core"</span>;
<span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">"axios"</span>;
<span class="hljs-keyword">import</span> { Tabledata } <span class="hljs-keyword">from</span> <span class="hljs-string">"./Tabledata"</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">NLQueryForm</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [nlQuery, setNlQuery] = useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [data, setData] = useState([]);
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"🚀 ~ NLQueryForm ~ data:"</span>, data);
  <span class="hljs-keyword">const</span> [error, setError] = useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [loading, setLoading] = useState(<span class="hljs-literal">true</span>);

  <span class="hljs-keyword">const</span> API_KEY = process.env.NEXT_PUBLIC_RESTDB_API_KEY;
  <span class="hljs-keyword">const</span> BASE_URL = process.env.NEXT_PUBLIC_RESTDB_BASE_URL;
  <span class="hljs-built_in">console</span>.table({ API_KEY, BASE_URL });
  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fetchData</span>(<span class="hljs-params"></span>) </span>{
      <span class="hljs-keyword">if</span> (!API_KEY || !BASE_URL) {
        setError(<span class="hljs-string">"API configuration is missing"</span>);
        setLoading(<span class="hljs-literal">false</span>);
        <span class="hljs-keyword">return</span>;
      }
      <span class="hljs-keyword">try</span> {
        <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> axios.get(BASE_URL, {
          <span class="hljs-attr">headers</span>: {
            <span class="hljs-string">"x-apikey"</span>: API_KEY,
            <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"application/json"</span>,
          },
        });
        setData(response.data);
        setLoading(<span class="hljs-literal">false</span>);
      } <span class="hljs-keyword">catch</span> (error) {
        <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Error fetching data:"</span>, error);
        setError(
          error <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Error</span> ? error.message : <span class="hljs-string">"An unknown error occurred"</span>
        );
        setLoading(<span class="hljs-literal">false</span>);
      }
    }
    fetchData();
  }, [API_KEY, BASE_URL]);

  useCopilotReadable({
    <span class="hljs-attr">description</span>: <span class="hljs-string">"Query database with detailed information"</span>,
    <span class="hljs-attr">value</span>: <span class="hljs-built_in">JSON</span>.stringify(data.slice(<span class="hljs-number">0</span>, <span class="hljs-number">25</span>)),
  });
  useCopilotAction({
    <span class="hljs-attr">name</span>: <span class="hljs-string">"fetchData"</span>,
    <span class="hljs-attr">description</span>: <span class="hljs-string">"Search and filter data based on natural language query"</span>,
    <span class="hljs-attr">parameters</span>: [
      {
        <span class="hljs-attr">name</span>: <span class="hljs-string">"nlQuery"</span>,
        <span class="hljs-attr">type</span>: <span class="hljs-string">"string"</span>,
        <span class="hljs-attr">description</span>: <span class="hljs-string">"Natural language search term for database"</span>,
        <span class="hljs-attr">required</span>: <span class="hljs-literal">true</span>,
      },
    ],

    <span class="hljs-attr">handler</span>: <span class="hljs-keyword">async</span> ({ data }) =&gt; {
      setNlQuery(data);
      <span class="hljs-keyword">return</span> <span class="hljs-built_in">JSON</span>.stringify(data);
    },
  });

  <span class="hljs-keyword">if</span> (loading) <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      {error &amp;&amp; <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">color:</span> "<span class="hljs-attr">red</span>" }}&gt;</span>{error}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>}
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-sm text-green-600 font-bold text-center"</span>&gt;</span>
          Live data from database.
        <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-sm text-green-600 font-bold text-center"</span>&gt;</span>
          Total Records: {data.length}
        <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Tabledata</span> <span class="hljs-attr">data</span>=<span class="hljs-string">{data}</span> /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> NLQueryForm;
</code></pre>
<p>Here’s a detailed explanation of the <code>NLQueryForm</code> component:</p>
<p><strong>Imports and Dependencies:</strong></p>
<ul>
<li><p>Utilizes React for state management (<code>useState</code>) and side effects (<code>useEffect</code>).</p>
</li>
<li><p>Imports <code>axios</code> for HTTP requests.</p>
</li>
<li><p>Imports <code>useCopilotReadable</code> and <code>useCopilotAction</code> from <code>@copilotkit/react-core</code> to integrate CopilotKit functionality.</p>
</li>
<li><p>Imports a custom <code>Tabledata</code> component for rendering data.</p>
</li>
</ul>
<p><strong>Component Setup:</strong></p>
<ul>
<li><p>Defines a functional React component <code>NLQueryForm</code>.</p>
</li>
<li><p>Initializes state variables:</p>
<ul>
<li><p><code>nlQuery</code>: Holds the natural language query input.</p>
</li>
<li><p><code>data</code>: Stores fetched data from the API.</p>
</li>
<li><p><code>error</code>: Stores any errors that occur during data fetching.</p>
</li>
<li><p><code>loading</code>: Tracks the loading state of the component.</p>
</li>
</ul>
</li>
</ul>
<p><strong>API Configuration:</strong></p>
<ul>
<li><p>Fetches API keys and base URL from environment variables (<code>NEXT_PUBLIC_RESTDB_API_KEY</code> and <code>NEXT_PUBLIC_RESTDB_BASE_URL</code>).</p>
</li>
<li><p>Logs these values for debugging purposes using <code>console.table</code>.</p>
</li>
</ul>
<p><strong>Data Fetching:</strong></p>
<ul>
<li><p>Uses <code>useEffect</code> to fetch data from the API on the initial render.</p>
</li>
<li><p>Makes a GET request to the API using <code>axios</code> with required headers.</p>
</li>
<li><p>Updates <code>data</code> with the response and stops the loading state.</p>
</li>
<li><p>Handles errors by logging them and updating the <code>error</code> state.</p>
</li>
</ul>
<p><strong>CopilotKit Integration:</strong></p>
<ul>
<li><p><code>useCopilotReadable</code>: Exposes a readable description and a slice of the first 25 records of <code>data</code>.</p>
</li>
<li><p><code>useCopilotAction</code>: Defines a CopilotKit action named <code>fetchData</code> which:</p>
<ul>
<li><p>Accepts a natural language query (<code>nlQuery</code>) as input.</p>
</li>
<li><p>Updates the <code>nlQuery</code> state and returns it as a string.</p>
</li>
</ul>
</li>
</ul>
<p><strong>Conditional Rendering:</strong></p>
<ul>
<li><p>Displays a loading message (<code>Loading...</code>) if <code>loading</code> is true.</p>
</li>
<li><p>Displays an error message in red text if an error occurs.</p>
</li>
</ul>
<p><strong>Rendering:</strong></p>
<ul>
<li><p>Shows a message indicating live data and the total record count.</p>
</li>
<li><p>Passes the <code>data</code> state to the <code>Tabledata</code> component for rendering.</p>
</li>
</ul>
<p><strong>Export:</strong></p>
<ul>
<li>Exports the <code>NLQueryForm</code> component as the default export.</li>
</ul>
<h3 id="heading-pagejs"><strong>Page.js</strong></h3>
<p>Now go to the <code>page.js</code> file inside the app folder and add this code:</p>
<ul>
<li><pre><code class="lang-javascript">  <span class="hljs-string">"use client"</span>;

  <span class="hljs-keyword">import</span> NLQueryForm <span class="hljs-keyword">from</span> <span class="hljs-string">"@/components/ui/nl-query-form"</span>;
  <span class="hljs-keyword">import</span> { CopilotPopup } <span class="hljs-keyword">from</span> <span class="hljs-string">"@copilotkit/react-ui"</span>;

  <span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Home</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">return</span> (
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"min-h-screen bg-background"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">header</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"bg-primary text-primary-foreground py-6"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"container"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-3xl font-bold"</span>&gt;</span>
              Natural Language SQL Query Builder
            <span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">main</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"container py-8"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">NLQueryForm</span> /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">CopilotPopup</span>
          <span class="hljs-attr">instructions</span>=<span class="hljs-string">{</span>
            "<span class="hljs-attr">You</span> <span class="hljs-attr">are</span> <span class="hljs-attr">assisting</span> <span class="hljs-attr">the</span> <span class="hljs-attr">user</span> <span class="hljs-attr">as</span> <span class="hljs-attr">best</span> <span class="hljs-attr">as</span> <span class="hljs-attr">you</span> <span class="hljs-attr">can.</span> <span class="hljs-attr">Answer</span> <span class="hljs-attr">in</span> <span class="hljs-attr">the</span> <span class="hljs-attr">best</span> <span class="hljs-attr">way</span> <span class="hljs-attr">possible</span> <span class="hljs-attr">given</span> <span class="hljs-attr">the</span> <span class="hljs-attr">data</span> <span class="hljs-attr">you</span> <span class="hljs-attr">have.</span>"
          }
          <span class="hljs-attr">labels</span>=<span class="hljs-string">{{</span>
            <span class="hljs-attr">title:</span> "<span class="hljs-attr">Popup</span> <span class="hljs-attr">Assistant</span>",
            <span class="hljs-attr">initial:</span> "<span class="hljs-attr">Need</span> <span class="hljs-attr">any</span> <span class="hljs-attr">help</span>?",
          }}
        /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    );
  }
</code></pre>
</li>
</ul>
<p>Here’s a simple explanation of the code above:</p>
<ul>
<li><p><strong>Client-Side Rendering</strong>:</p>
<ul>
<li><code>"use client";</code> indicates the file is using React's client-side rendering.</li>
</ul>
</li>
<li><p><strong>Importing Components</strong>:</p>
<ul>
<li><p><code>NLQueryForm</code> is imported from a local component directory to be used in the app.</p>
</li>
<li><p><code>CopilotPopup</code> is imported from the <code>@copilotkit/react-ui</code> package for displaying an interactive popup.</p>
</li>
</ul>
</li>
<li><p><strong>Main Function</strong>:</p>
<ul>
<li><code>Home</code> is a React functional component that defines the UI for the home page.</li>
</ul>
</li>
<li><p><strong>Page Layout</strong>:</p>
<ul>
<li>A full-page container (<code>min-h-screen</code>) with a background color (<code>bg-background</code>) wraps all content.</li>
</ul>
</li>
<li><p><strong>Header</strong>:</p>
<ul>
<li><p>Contains a title with the text <strong>"Natural Language SQL Query Builder"</strong>.</p>
</li>
<li><p>Styled with a primary background and text colors (<code>bg-primary</code>, <code>text-primary-foreground</code>).</p>
</li>
</ul>
</li>
<li><p><strong>Main Content</strong>:</p>
<ul>
<li>Renders the <code>NLQueryForm</code> component inside a container with padding (<code>py-8</code>).</li>
</ul>
</li>
<li><p><strong>Popup Component</strong>:</p>
<ul>
<li><p>Adds a <code>CopilotPopup</code> at the bottom with:</p>
<ul>
<li><p><strong>Instructions</strong>: Describes the assistant's role.</p>
</li>
<li><p><strong>Labels</strong>: Includes a title and initial message for the popup.</p>
</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>Purpose</strong>:</p>
<ul>
<li>The page is designed to let users interact with a natural language SQL query builder and receive assistance via a popup.</li>
</ul>
</li>
</ul>
<h3 id="heading-configuring-copilotkit-for-the-whole-app"><strong>Configuring CopilotKit for the Whole App</strong></h3>
<p>This is going to be the last step of building the application. Navigate to the <code>layout.js</code> file and add this code:</p>
<pre><code class="lang-javascript">
<span class="hljs-keyword">import</span> <span class="hljs-string">"./globals.css"</span>;
<span class="hljs-keyword">import</span> { CopilotKit } <span class="hljs-keyword">from</span> <span class="hljs-string">"@copilotkit/react-core"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">"@copilotkit/react-ui/styles.css"</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> metadata = {
  <span class="hljs-attr">title</span>: <span class="hljs-string">"Create Next App"</span>,
  <span class="hljs-attr">description</span>: <span class="hljs-string">"Generated by create next app"</span>,
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">RootLayout</span>(<span class="hljs-params">{ children }</span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">CopilotKit</span> <span class="hljs-attr">runtimeUrl</span>=<span class="hljs-string">"/api/copilotkit"</span>&gt;</span>{children}<span class="hljs-tag">&lt;/<span class="hljs-name">CopilotKit</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span></span>
  );
</code></pre>
<p>Here’s what’s going on in this code:</p>
<ul>
<li><p><strong>Imports:</strong></p>
<ul>
<li><p><code>./globals.css</code>: Imports global CSS styles for the application.</p>
</li>
<li><p><code>@copilotkit/react-core</code>: Imports the core functionality of CopilotKit.</p>
</li>
<li><p><code>@copilotkit/react-ui/styles.css</code>: Includes predefined styles for the CopilotKit UI components.</p>
</li>
</ul>
</li>
<li><p><strong>Metadata:</strong></p>
<ul>
<li>The <code>metadata</code> object defines the app's title and description, which are useful for setting meta tags in the generated HTML for SEO and user information.</li>
</ul>
</li>
<li><p><strong>RootLayout function:</strong></p>
<ul>
<li>This function serves as the root layout wrapper for the application. It ensures consistent structure across all pages and integrates the CopilotKit runtime.</li>
</ul>
</li>
<li><p><strong>Structure:</strong></p>
<ul>
<li><p>The layout returns an <code>&lt;html&gt;</code> element with a <code>lang</code> attribute set to <code>en</code> for English.</p>
</li>
<li><p>Inside the <code>&lt;body&gt;</code> tag, the CopilotKit component is wrapped around the <code>children</code> prop.<br>  This setup:</p>
<ul>
<li><p>Connects the app to the CopilotKit runtime using the API endpoint <code>/api/copilotkit</code>.</p>
</li>
<li><p>Provides access to CopilotKit's functionality, such as handling natural language queries, throughout the application.</p>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="heading-some-important-notes">Some Important Notes</h2>
<p>Designing and deploying a database can take various forms, depending on the tools and requirements. For this project, I have chosen the simplest and most accessible approach.</p>
<h4 id="heading-why-copilotkit">Why CopilotKit?</h4>
<p>CopilotKit is a powerful tool that converts NLP queries into actionable backend code. If you have an alternative that works similarly, feel free to use it. It bridges the gap between natural language input and technical execution, making it ideal for projects like this.</p>
<h4 id="heading-why-groqcloud">Why GroqCloud?</h4>
<p>I selected <strong>GroqCloud</strong> because it’s free and provides access to multiple LLMs with a single API key. While you can opt for alternatives like ChatGPT, note that they may require paid plans. GroqCloud’s versatility and affordability make it perfect for this tutorial.</p>
<h4 id="heading-database-considerations">Database Considerations</h4>
<p>The size of your database can vary from very small to enormous. However, interacting with the database depends on the token limits of the LLM you’re using.</p>
<p>Since I’m working with free-tier tools, my focus is on a small database to ensure seamless interactions.</p>
<h4 id="heading-security-best-practices">Security Best Practices</h4>
<p>Never expose your credentials publicly. Always store sensitive information like API keys in an <code>.env</code> file to keep your project secure.</p>
<h4 id="heading-future-enhancements">Future Enhancements</h4>
<p>While this tutorial focuses on setting up and querying a database, the potential of CopilotKit extends to <strong>CRUD operations</strong> (Create, Read, Update, Delete). In my next tutorial, I will demonstrate how to implement full CRUD operations using CopilotKit for a more dynamic and functional application.</p>
<h2 id="heading-playing-with-the-database">Playing with the Database</h2>
<p>You can explore the live project via the following link and ask any questions related to the database data: <a target="_blank" href="https://talktodb-inky.vercel.app/">live link</a> .</p>
<p>For a deeper understanding of the code, here’s the GitHub repository link: <a target="_blank" href="https://github.com/prankurpandeyy/talktodb">github</a> .</p>
<p>Also, here’s a screenshot demonstrating its practical use. In this example, instead of writing a plain SQL query like <code>SELECT * FROM demo_data WHERE email = '</code><a target="_blank" href="mailto:riverashannon@lee.com"><code>riverashannon@lee.com</code></a><code>';</code> to extract the name of the person, we used an NLP query to achieve the exact same result.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735061714011/bec86e4a-bb7b-4d7f-97e9-284d54060db5.png" alt="bec86e4a-bb7b-4d7f-97e9-284d54060db5" class="image--center mx-auto" width="1366" height="768" loading="lazy"></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>I hope you’ve enjoyed building this simple AI chatbot to interact with the database. In this project, we’ve used a simple SQL database, but you can apply this approach to any database as long as you can retrieve the data.</p>
<p>In the future, I plan to implement many new projects involving AI and other tools. AI tools are truly game-changing in the IT field, and I look forward to providing you with more detailed insights and practical implementations of the latest tools emerging in the space.</p>
<p>So this is the end from my side. If you found this article useful, then do share it and connect with me – I am open to opportunities:</p>
<ul>
<li><p>Follow Me on X: <a target="_blank" href="https://x.com/prankurpandeyy">Prankur's Twitter</a></p>
</li>
<li><p>Follow me on LinkedIn: <a target="_blank" href="https://linkedin.com/in/prankurpandeyy">Prankur's Linkedin</a></p>
</li>
<li><p>Look at my Portfolio here: <a target="_blank" href="https://prankurpandeyy.netlify.app/">Prankur's Portfolio</a></p>
</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build a CSS Component Library and Improve Your Web Development Skills ]]>
                </title>
                <description>
                    <![CDATA[ Application development is a complex, multi-stage process, and it all begins with UI/UX design. Once the design phase is complete, the focus shifts to UI development, where tools like HTML, CSS, and JavaScript come into play. At a higher level, libra... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-a-css-component-library-step-by-step/</link>
                <guid isPermaLink="false">6709799c031bde0105c6130f</guid>
                
                    <category>
                        <![CDATA[ CSS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ components ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Prankur Pandey ]]>
                </dc:creator>
                <pubDate>Fri, 11 Oct 2024 19:16:44 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1728400677433/de06f432-0861-4ba4-ad7c-6e10157e2822.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Application development is a complex, multi-stage process, and it all begins with UI/UX design.</p>
<p>Once the design phase is complete, the focus shifts to <strong>UI development</strong>, where tools like <strong>HTML</strong>, <strong>CSS</strong>, and <strong>JavaScript</strong> come into play. At a higher level, libraries like <strong>React</strong> and <strong>Vue</strong> streamline the development process.</p>
<p>Regardless of the application type, your code can almost always be broken down into <strong>components</strong>.</p>
<p><em>“Repeated components are a nightmare to manage.”</em> – Every frustrated UI developer</p>
<p>Imagine having a component library where all commonly used elements are pre-built and responsive—how much easier and faster would that make development?</p>
<p>In this article, I’ll show you how to build your own component library, using a minimal tech stack, and then use it to build an application.</p>
<h3 id="heading-what-well-cover">What We’ll Cover</h3>
<ol>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-why-build-a-component-library">Why Build a Component Library</a>?</p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-build-the-component-library">How to Build the Component Library</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-lets-build-the-library">Let’s Build the Library</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-step-1-design-the-layout-using-pen-and-paper">Step 1: Design the Layout using Pen and Paper</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-2-design-the-components-in-html-and-css">Step 2: Design the Components in HTML and CSS</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-3-hosting-the-project-css-file">Step 3: Hosting the Project CSS File</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-faq">FAQ</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ol>
<h2 id="heading-prerequisites">Prerequisites</h2>
<ul>
<li><p><strong>Proficiency in HTML, CSS, and JavaScript</strong>: A solid understanding of front-end development fundamentals is essential.</p>
</li>
<li><p><strong>Basic Deployment Skills</strong>: Familiarity with deploying applications on platforms like <strong>Netlify</strong> or <strong>Vercel</strong> is required.</p>
</li>
<li><p><strong>Git/GitHub Knowledge</strong>: You should be comfortable with version control, including basic Git commands and managing repositories on GitHub.</p>
</li>
</ul>
<h2 id="heading-why-build-a-component-library">Why Build a Component Library?</h2>
<p>Every website is built from components, which are structured with <strong>HTML</strong> and styled using <strong>CSS</strong>.</p>
<p><strong>HTML</strong> and <strong>CSS</strong> are fundamental technologies for creating visually appealing web pages. However, mastering them can be challenging due to the wide array of HTML tags and CSS properties.</p>
<p>To simplify the process, developers often use <strong>component libraries</strong>, which deliver various benefits:</p>
<ol>
<li><p><strong>Faster Development</strong>: Pre-built components and responsive design features accelerate the development process.</p>
</li>
<li><p><strong>Consistency</strong>: Ensures uniform styling and cross-browser compatibility across the application.</p>
</li>
<li><p><strong>Maintainability</strong>: Encourages structured, modular code, making it easier to maintain and scale.</p>
</li>
<li><p><strong>Community Support</strong>: extensive documentation, plugins, and a strong community provide valuable resources.</p>
</li>
<li><p><strong>Customization and Accessibility</strong>: offers easy customization and accessibility-focused components for inclusive designs.</p>
</li>
</ol>
<h2 id="heading-how-to-build-the-component-library">How to Build the Component Library</h2>
<p>Building a component library involves several key steps. First, I’ll give you an overview of each step we’ll take to create the component library. After that, we’ll build it together.</p>
<h3 id="heading-1-design-the-layout-of-the-components">1. Design the Layout of the Components</h3>
<p>Before writing any code, it’s crucial to have a clear vision of what you want to build. Start by sketching the layout of your components on paper, or use design tools like <strong>Figma</strong> or <strong>Canva</strong> to create a visual representation.</p>
<p>Having a visual guide will streamline your coding process and help you stay focused as you translate designs into code.</p>
<h3 id="heading-2-write-the-component-structure-in-html">2. Write the Component Structure in HTML</h3>
<p>Once the design is ready, the next step is to structure your components in <strong>HTML</strong>. This creates the foundation of your webpage, as HTML is the backbone of any web project.</p>
<p><strong>Pro-tip</strong>: Use <strong>semantic HTML</strong> to improve user accessibility and SEO. For example, use <code>&lt;article&gt;</code>, <code>&lt;section&gt;</code>, or <code>&lt;header&gt;</code> tags instead of generic <code>&lt;div&gt;</code> elements when appropriate.</p>
<h3 id="heading-3-style-the-components-with-css">3. Style the Components with CSS</h3>
<p>With the HTML structure in place, you can begin styling the components using <strong>CSS</strong>. Apply styles like <strong>background colours</strong>, <strong>font sizes</strong>, <strong>link decorations</strong>, and <strong>button styles</strong> using <strong>CSS classes</strong> and <strong>IDs</strong>.</p>
<p>CSS is a powerful tool—you can even add beautiful animations. But in this tutorial, we’ll focus on utilizing the essential properties of CSS to create clean, functional designs.</p>
<h3 id="heading-4-host-the-projects-css-file">4. Host the Project's CSS File</h3>
<p>Once your component library is ready, you’ll want to make it accessible for future projects. Hosting your <strong>CSS file</strong> on platforms like <strong>Netlify</strong>, <strong>GitHub Pages</strong>, or <strong>Vercel</strong> allows you to use the components across different projects by simply linking to the global CSS file.</p>
<p>By following these four steps, you’ll create a reusable component library that helps you build beautiful websites efficiently and effectively.</p>
<h2 id="heading-lets-build-the-library">Let’s Build the Library</h2>
<p>I began my journey as a software developer by diving into <strong>HTML</strong> and <strong>CSS</strong> to design webpages. These foundational technologies are essential for any web developer, but mastering them can be challenging—HTML boasts 152 tags, while CSS has over 200 properties.</p>
<p>While you won’t need to use every single HTML tag or CSS property, knowing the core concepts requires significant time and effort. .</p>
<p>Now, let’s consider a scenario: if I asked you to create a small website or a landing page without using any component library, how would you approach it? My goal is to minimize the time spent on designing.</p>
<p>Imagine if there was a way to automate the design process, allowing you to achieve beautiful results without sacrificing flexibility. This is where a <strong>component library</strong> comes into play. By writing your components in pure vanilla CSS once, you can reuse them across any project.</p>
<p>I encourage you to pursue this approach because it will provide real-time experience with HTML and CSS while helping you learn a multitude of concepts simultaneously.</p>
<p>I developed a small library consisting of 10+ beautiful components, which you can explore here: <a class="post-section-overview" href="#"><strong>SlateUi</strong></a>. This library has helped deepen my understanding of web technologies.</p>
<p>My goal was to understand HTML and CSS thoroughly. After completing one project, I wanted to feel confident in all the critical aspects of web design, from UI to code.</p>
<p>By designing and developing these components, I gained greater control and customization options tailored to specific requirements.</p>
<p>The learning process was also incredibly rewarding. Creating each component took considerable time, but the exposure I gained to these two technologies significantly boosted my confidence.</p>
<p>Additionally, this approach helps avoid the redundancy of writing repetitive CSS code for similar elements.</p>
<h3 id="heading-step-1-design-the-layout-using-pen-and-paper">Step 1: Design the Layout using Pen and Paper</h3>
<p>First, you’ll want to create a basic layout for the webpage. This is just initial sketching so that you know what you have to build in your project</p>
<p>The layout consists of three key elements:</p>
<p>a) <strong>Header</strong><br>b) <strong>Card(s)</strong><br>c) <strong>Footer</strong></p>
<p>Each component includes distinct colours, text, and additional elements. Here’s what it looks like in our example:</p>
<p><a target="_blank" href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzrcqxm4mrnyx778sedui.png"><img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzrcqxm4mrnyx778sedui.png" alt="Illustration of the main components of the layout: header, card, footer" width="800" height="400" loading="lazy"></a></p>
<p>In an actual project, you typically start with prepared design models created in tools like <strong>Figma</strong> or other UI design software.</p>
<p>For this project, I used <strong>Canva</strong> to design the layout. This initial design phase is crucial as it lays the foundation for core feature development.</p>
<p>Then, you’ll write the structure of the component in HTML. At this level, I will simply put our HTML elements in such a way so that we can prepare a basic skeleton of the webpage as we have designed it. In the header I have a logo and some navigation links, in the cards I have a button and an image; and in the footer, I have some more links.</p>
<h3 id="heading-step-2-design-the-components-in-html-and-css">Step 2: Design the Components in HTML and CSS</h3>
<p>At this point<strong>,</strong> we’ll enhance the components we created with HTML by applying CSS properties to beautify them. This stage involves using CSS to set background colours, primary colours, link decorations, button styles, and more. We’ll do this by utilizing CSS classes and IDs.</p>
<p>So far, we’ve built three components:</p>
<p>a) <strong>Header</strong> with navigation links<br>b) <strong>Footer</strong><br>c) <strong>Horizontal Cards</strong> with action buttons</p>
<p>Now, let’s begin by building the first component: the <strong>Header</strong>.</p>
<h4 id="heading-the-header-component">The header component:</h4>
<p>The header is at the top of a page or a section. It usually contains a logo, search bar, navigational links, and so on.</p>
<div class="embed-wrapper"><iframe height="300" style="width:100%" src="https://codepen.io/iprankurpandey/embed/eYVzNPR?default-tab=html" title="Embedded content" loading="lazy">
  See the Pen <a href="https://codepen.io/iprankurpandey/pen/eYVzNPR">
  Header</a> by PRANKUR PANDEY (<a href="https://codepen.io/iprankurpandey">@iprankurpandey</a>)
  on <a href="https://codepen.io">CodePen</a>.
</iframe></div>

<h4 id="heading-the-footer-component">The footer component:</h4>
<p>The Footer defines the footer or bottom of a web page or a section. Usually, it contains copyright information, contact details, navigation links, and so on.</p>
<div class="embed-wrapper"><iframe height="300" style="width:100%" src="https://codepen.io/iprankurpandey/embed/poabJqN?default-tab=html" title="Embedded content" loading="lazy">
  See the Pen <a href="https://codepen.io/iprankurpandey/pen/poabJqN">
  Footer</a> by PRANKUR PANDEY (<a href="https://codepen.io/iprankurpandey">@iprankurpandey</a>)
  on <a href="https://codepen.io">CodePen</a>.
</iframe></div>

<h4 id="heading-the-card-component">The card component:</h4>
<p>The <strong>card component</strong> can house various types of content, including a heading, image, main content, and a footer that features a call-to-action button.</p>
<p>Cards are designed to serve specific purposes, such as showcasing e-commerce products, displaying news items, or serving multiple other functions across different contexts.</p>
<div class="embed-wrapper"><iframe height="300" style="width:100%" src="https://codepen.io/iprankurpandey/embed/KKQMpvd?default-tab=html" title="Embedded content" loading="lazy">
  See the Pen <a href="https://codepen.io/iprankurpandey/pen/KKQMpvd">
  Horizontal-Cards</a> by PRANKUR PANDEY (<a href="https://codepen.io/iprankurpandey">@iprankurpandey</a>)
  on <a href="https://codepen.io">CodePen</a>.
</iframe></div>

<h4 id="heading-combining-it-all-together">Combining it all together:</h4>
<div class="embed-wrapper"><iframe height="300" style="width:100%" src="https://codepen.io/iprankurpandey/embed/NWyrjGm?default-tab=html" title="Embedded content" loading="lazy">
  See the Pen <a href="https://codepen.io/iprankurpandey/pen/NWyrjGm">
  Demo-API</a> by PRANKUR PANDEY (<a href="https://codepen.io/iprankurpandey">@iprankurpandey</a>)
  on <a href="https://codepen.io">CodePen</a>.
</iframe></div>

<p>By clicking the button, the card data will update with random cat facts, along with the length of each fact.</p>
<p><strong>Note</strong>: I used an open-source API for this project. If the content does not update on the card, it may be due to an API outage.</p>
<p>Now, have you checked the CSS code?</p>
<p>You might be wondering why I’ve imported just a single line of code into my CSS file. Well, I have combined the CSS files of all three parts of the layout (<strong>header, footer, &amp; cards</strong> components) into one CSS file and hosted the file on Netlify. This is the URL that is holding all three CSS files:</p>
<p><code>@import url("</code><a target="_blank" href="https://hashnodeblogchallenge.netlify.app/index.css"><code>https://hashnodeblogchallenge.netlify.app/index.css</code></a><code>");</code></p>
<p>It serves the CSS in all three components and maintains the styles for all three components.</p>
<h3 id="heading-step-3-hosting-the-project-css-file">Step 3: Hosting the Project CSS File</h3>
<p>Finally, I’ve arrived at the most crucial part of this project, where all the magic happens.</p>
<p>Currently, I have three CSS files for each of the web components: <strong>header</strong>, <strong>cards</strong>, and <strong>footer</strong>.</p>
<p>Since our project is small, I will combine all CSS file code into one CSS file to get one CSS file which will work as a universal CSS file.</p>
<p>The process of hosting the CSS file is straightforward. Here's a detailed breakdown of what you need to do:</p>
<h4 id="heading-1-push-your-code-to-github">1. <strong>Push Your Code to GitHub</strong></h4>
<p>You need to push (upload) your project files, including the HTML, CSS, and other assets, to a GitHub repository. Here’s how you can do that:</p>
<ol>
<li><p>Initialize a Git repository in your project directory using <code>git init</code>.</p>
</li>
<li><p>Add all your files using <code>git add .</code>.</p>
</li>
<li><p>Commit the files with <code>git commit -m "Initial commit"</code>.</p>
</li>
<li><p>Link to a GitHub repository you’ve created using <code>git remote add origin &lt;repo-url&gt;</code>.</p>
</li>
<li><p>Finally, push your code using <code>git push -u origin main</code>.</p>
</li>
<li><p><strong>Result</strong>: Your project files will now be hosted in your GitHub repository.</p>
</li>
</ol>
<h4 id="heading-2-open-netlify-and-log-in-or-sign-up">2. <strong>Open Netlify and Log In or Sign Up</strong></h4>
<p>Then, visit <a target="_blank" href="https://www.netlify.com">Netlify</a> and either sign in if you already have an account or create a new one.</p>
<p>You can sign up using your GitHub credentials or a separate email. This step gives you access to Netlify's web hosting services, which will allow you to deploy your project directly from GitHub.</p>
<h4 id="heading-3-connect-your-github-repository-that-contains-your-code">3. <strong>Connect Your GitHub Repository That Contains Your Code</strong></h4>
<p>Once logged in, you'll connect your GitHub repository to Netlify.</p>
<ol>
<li><p>On Netlify, click on "New site from Git".</p>
</li>
<li><p>Choose <strong>GitHub</strong> as the source.</p>
</li>
<li><p>Authorize Netlify to access your GitHub account.</p>
</li>
<li><p>Select the repository that contains your project from the list.</p>
</li>
<li><p>Configure build settings if necessary (though for simple static sites, Netlify automatically detects them).</p>
</li>
</ol>
<h4 id="heading-4-click-deploy">4. <strong>Click "Deploy"</strong></h4>
<p>After connecting your repository, Netlify will display a "Deploy" button.</p>
<ol>
<li><p>Click "Deploy" to trigger the build and deployment process.</p>
</li>
<li><p>Netlify will pull your code from GitHub, build the site (if needed), and deploy it to a live URL.</p>
</li>
</ol>
<p>Your project is now live on the web, and you’ll be provided with a URL where you can access the deployed site.</p>
<h4 id="heading-5-access-the-deployed-url-and-append-the-css-file-url">5. <strong>Access the Deployed URL and Append the CSS File URL</strong></h4>
<p>You’ll access the deployed site by visiting the URL provided by Netlify and directly referencing the CSS file you uploaded.</p>
<ol>
<li><p>Once your site is deployed, note down the provided URL (for example, <a target="_blank" href="https://example.netlify.app"><code>https://example.netlify.app</code></a>).</p>
</li>
<li><p>To access a specific CSS file, append the file name to the URL, for example: <a target="_blank" href="https://example.netlify.app/styles.css"><code>https://example.netlify.app/styles.css</code></a>.</p>
</li>
<li><p>Here, <code>styles.css</code> is the name of your CSS file that you uploaded to GitHub and deployed via Netlify.</p>
</li>
</ol>
<p>This will allow you to view or reference the CSS file directly through a public URL.</p>
<p>This process essentially helps you host your project and its assets on Netlify, allowing easy access to any file (like <code>filename.css</code>) that you uploaded to GitHub. You can use these public links in your projects or share them.</p>
<p><strong>And that’s it! Link this URL to your project's CSS file.</strong></p>
<p>I have hosted the main CSS file on the Netlify app so that it can be accessed anywhere simply by importing it into your project. Here is the URL of my hosted CSS file: <code>https://hashnodeblogchallenge.netlify.app/index.css</code>.</p>
<p>The beauty of component libraries is that they allow you to focus on development rather than design.</p>
<h2 id="heading-faq">FAQ</h2>
<h3 id="heading-what-benefits-have-we-gained-from-this">What Benefits Have We Gained from This?</h3>
<p>Now, you simply need to copy the HTML code and import the CSS file into your project. Here are the key benefits:</p>
<ul>
<li><p><strong>Reduces time</strong> spent on repetitive CSS coding.</p>
</li>
<li><p>Provides <strong>greater control</strong> over components, allowing for customization based on your needs.</p>
</li>
<li><p>Offers <strong>real-time experience</strong> with HTML and CSS, enabling you to learn core concepts effectively.</p>
</li>
</ul>
<h3 id="heading-what-if-i-want-to-change-something">What if I Want to Change Something?</h3>
<p>This is straightforward. Just edit your CSS file and update the header colour from black to blue where you have declared that header class or ID.</p>
<h3 id="heading-what-if-i-want-to-create-more-components">What if I Want to Create More Components?</h3>
<p>You can create as many components as you need! Just store the style code in the same hosted CSS file, and everything will work seamlessly.</p>
<h3 id="heading-how-does-this-save-me-time">How Does This Save Me Time?</h3>
<p>Imagine you need to create 5 websites, each with 5 pages (that’s a total of 25 pages). If you identify common elements, such as headers and footers, that will be used across all 25 pages, you can avoid writing 25 separate components. Instead, you can simply use the components from your library—just copy and paste the HTML and add the CSS file.</p>
<h3 id="heading-what-lets-the-entire-app-function-with-just-one-line-of-css">What Lets the Entire App Function with Just One Line of CSS?</h3>
<p>The concept is quite simple and can be broken down into the following steps:</p>
<ol>
<li><p><strong>Create components</strong> based on your requirements.</p>
</li>
<li><p><strong>Control their design</strong> with CSS and apply the necessary properties.</p>
</li>
<li><p><strong>Host your main CSS file</strong> somewhere to obtain a new URL, which you can use to import your CSS styles in HTML.</p>
</li>
</ol>
<p><strong>Now you can calculate how much time you have saved.</strong></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Creating a component library using <strong>HTML</strong> and <strong>CSS</strong> allows you to build beautiful web pages quickly and effectively.</p>
<p>It also provides you with a deep understanding of HTML and CSS, which are essential skills for a successful software development career. With these skills, you'll be able to create engaging layouts without spending excessive time coding from scratch.</p>
<p>To help you get started, here’s an example of a component library I developed, which includes 10+ beautiful components: <a target="_blank" href="https://slateui.netlify.app">SlateUI</a>.</p>
<p>Now, you simply need to copy the HTML code and paste it where you want to display your components, along with importing your CSS file URL into that HTML file.</p>
<p>So guys this is the end from my side. If you find this article useful, then do share it and connect with me – I am open to opportunities:</p>
<ul>
<li><p>Follow Me on X: <a target="_blank" href="https://x.com/prankurpandeyy">Prankur's Twitter</a></p>
</li>
<li><p>Follow me on LinkedIn: <a target="_blank" href="https://linkedin.com/in/prankurpandeyy">Prankur's Linkedin</a></p>
</li>
<li><p>Look at my Portfolio here: <a target="_blank" href="https://prankurpandeyy.netlify.app/">Prankur's Portfolio</a></p>
</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ React Best Practices Ever Developer Should Know ]]>
                </title>
                <description>
                    <![CDATA[ The more I study React.js, the more I fall in love with it. No doubt that it’s one of the most useful and loved front-end JavaScript libraries out there. And the improvements that the React team have made lately don’t just affect developers, but also... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/react-best-practices-ever-developer-should-know/</link>
                <guid isPermaLink="false">66fecb8f0c5ac3f56463c16b</guid>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ best practices ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Prankur Pandey ]]>
                </dc:creator>
                <pubDate>Thu, 03 Oct 2024 16:51:27 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1727898200192/2b6b5882-f4e7-4cb5-9f97-4974669825fc.webp" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The more I study React.js, the more I fall in love with it. No doubt that it’s one of the most useful and loved front-end JavaScript libraries out there. And the improvements that the React team have made lately don’t just affect developers, but also those who use applications built with React.</p>
<p><a target="_blank" href="https://www.freecodecamp.org/news/learn-react-hooks-with-example-code/">In a previous article</a>, I talked about various React Hooks and how they work along with code samples and detailed explanations.</p>
<p>In this guide, I’m going to talk about some important things that I’ve learned while developing React apps. And these learnings are optimized based on using React Hooks. We’ll debunk some common myths, simplify common concepts, and optimize your code for the best performance.</p>
<h3 id="heading-what-well-cover">What we’ll cover:</h3>
<ul>
<li><p><a class="post-section-overview" href="#heading-how-will-this-guide-benefit-you">How Will This Guide Benefit You?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-prerequsites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-react-state-must-be-immutable">React State Must Be Immutable</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-dont-use-state-for-everything">Don't Use State for Everything</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-derive-values-without-state">Derive Values Without State</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-compute-values-without-effects">Compute Values Without Effects</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-keys-should-be-unique">Keys Should Be Unique</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-use-useeffect-last">Use useEffect Last</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion:</a></p>
</li>
</ul>
<h2 id="heading-how-will-this-guide-benefit-you">How Will This Guide Benefit You?</h2>
<p>Let’s say you have a knife and I ask you to cut out some shapes from a piece of cloth. You could do it, but it would take a while and be challenging using a knife. Instead, what if I gave you a pair of really sharp scissors and then asked you to cut out the patterns? It’d be much easier, right?</p>
<p>This guide is like that optimised approach of cutting cloth with scissors instead of a knife. I’ll teach you how to use React more easily, without as much struggle. We’ll discuss the important aspects of how React Hooks work, and we’ll also cover some do’s &amp; don’ts.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>There is only one main prerequisite for following this guide: you should have used React hooks at least once. And by this I mean developed an application with React that leverages the power of hooks.</p>
<p>This article is for everyone who wishes to use React hooks to their full potential.</p>
<h2 id="heading-react-state-must-be-immutable">React State Must Be Immutable</h2>
<p>Have you ever wondered why React makes such a fuss about immutability? 🤔 As a newbie, you might think that JavaScript's mutations are perfectly fine. After all, we add or remove properties from objects and manipulate arrays with ease.</p>
<p>But here's the twist: in React, immutability isn't about never changing state, it's about ensuring consistency.</p>
<p>When you mutate state directly, React can’t detect changes reliably. This means your UI might not update as expected. The trick? Replace old data with new copies.</p>
<p>For instance, if you need to add a user, you should create a new array with the new user included, rather than pushing directly into the existing array.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> updatedUsers = [...users, newUser];
</code></pre>
<p>The code <code>const updatedUsers = [...users, newUser];</code> uses the spread operator to create a new array, <code>updatedUsers</code>, which combines the existing <code>users</code> with <code>newUser</code>.</p>
<p>This approach maintains immutability in React by not modifying the original <code>users</code> array. Instead, it creates a new state representation, allowing React to optimize rendering and ensure predictable state changes. When you update the state using <code>setUsers(updatedUsers);</code>, React re-renders the component based on this new array, adhering to best practices for state management.</p>
<p>This ensures React detects the change and re-renders your component smoothly.</p>
<h2 id="heading-dont-use-usestate-for-everything">Don't Use <code>useState</code> for Everything</h2>
<p>Confession time: I used to throw everything into <code>useState</code> without thinking twice. 🚀 But here's the scoop: not everything needs to be in state. The state is powerful, but overusing it can lead to complex and inefficient code.</p>
<p>Consider alternatives like server state, URL state, or local storage. For server data, libraries like React Query are a game changer. They handle fetching and caching so you don’t have to manage it manually. For URL state, leverage hooks like <code>useLocation</code> from React Router or Next.js’s built-in methods.</p>
<p>Checklist before using useState:</p>
<ul>
<li><p>Is this value simple and derivable during render?</p>
</li>
<li><p>Does a library already manage this state?</p>
</li>
<li><p>Does it need to trigger a re-render?</p>
</li>
<li><p>If you answer “no” to all, you might not need <code>useState</code> at all.</p>
</li>
</ul>
<h2 id="heading-derive-values-without-state">Derive Values Without State</h2>
<p>Here’s a little-known trick: Derived values don't need to live in state. 🚀 If your data can be computed from existing states or props, calculate it directly during render.</p>
<p>For example, formatting a date can be done on the fly without additional hooks:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> formattedDate = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(date).toLocaleDateString();
</code></pre>
<p>The code <code>const formattedDate = new Date(date).toLocaleDateString();</code> derives a formatted date string from a given <code>date</code> input without storing it in the component's state. By creating <code>formattedDate</code> as a constant, it calculates the value on the fly each time it's called, reflecting the current state of <code>date</code>.</p>
<p>This approach avoids unnecessary state management, simplifies rendering logic, and keeps the component efficient, as derived values are recalculated only when the underlying data changes. Thus, it promotes a clean, functional style of programming in React</p>
<p>This keeps your components clean and avoids unnecessary state updates.</p>
<h2 id="heading-compute-values-without-effects">Compute Values Without Effects</h2>
<p>Stop using useEffect for simple computations! 🛑 If your value can be calculated directly from state or props and doesn’t involve side effects, do it during render. For expensive computations, wrap them in useMemo to optimize performance:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> expensiveValue = useMemo(<span class="hljs-function">() =&gt;</span> computeExpensiveValue(data), [data]);This reduces the complexity <span class="hljs-keyword">of</span> your code and keeps your components focused.
</code></pre>
<p>The code <code>const expensiveValue = useMemo(() =&gt; computeExpensiveValue(data), [data]);</code> uses the <code>useMemo</code> hook to compute a value (<code>expensiveValue</code>) based on the <code>data</code> input without triggering side effects.</p>
<p>It memoizes the result of <code>computeExpensiveValue(data)</code>, recalculating it only when <code>data</code> changes. This approach prevents unnecessary recalculations on every render, enhancing performance for expensive computations.</p>
<p>By relying on <code>useMemo</code>, the component efficiently derives the value based on its current props or state, keeping the rendering process efficient and focused on the latest data.</p>
<h2 id="heading-keys-should-be-unique">Keys Should Be Unique</h2>
<p>Guilty as charged: I’ve used array indexes as keys in lists before. 😅 But did you know this can lead to bugs? React relies on unique keys to identify items, and using non-unique values can mess things up.</p>
<p>Generate unique IDs using crypto.randomUUID() but make sure to do it only when your state updates, not on every render. For objects, consider adding an id property:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> itemWithId = items.map(<span class="hljs-function"><span class="hljs-params">item</span> =&gt;</span> ({ ...item, <span class="hljs-attr">id</span>: generateUniqueId() }));
</code></pre>
<p>The code <code>const itemWithId =</code> <a target="_blank" href="http://items.map"><code>items.map</code></a><code>(item =&gt; ({ ...item, id: generateUniqueId() }));</code> creates a new array, itemWithId, where each item in the items array is augmented with a unique id.</p>
<p>The spread operator (<code>...item</code>) copies the properties of each item, while <code>generateUniqueId()</code> generates a new, unique identifier. This ensures that each item has a distinct key, which is crucial for React components when rendering lists.</p>
<p>Unique keys help React efficiently manage updates, identify changes, and optimize rendering performance by distinguishing between different list items.</p>
<h2 id="heading-dont-leave-out-dependencies">Don't Leave Out Dependencies</h2>
<p>One of React’s cruel quirks: Forgetting dependencies in <code>useEffect</code> can lead to stale closures. 😱 For example, if you <code>useEffect</code> doesn’t include the dependencies it needs, it might not update as expected.</p>
<p>Always double-check your dependency arrays:</p>
<pre><code class="lang-javascript">useEffect(<span class="hljs-function">() =&gt;</span> {<span class="hljs-comment">// Effect logic}, [dependency]);</span>
</code></pre>
<p>The code <code>useEffect(() =&gt; { /* Effect logic */ }, [dependency]);</code> defines a side effect in a React component that runs when the specified <code>dependency</code> changes. It's essential to include all relevant dependencies in the dependency array to ensure that the effect behaves correctly.</p>
<p>Omitting dependencies can lead to stale or incorrect values being used in the effect, as React may not re-run it when needed. Including all dependencies helps maintain synchronization between the component's state and the effect, ensuring predictable behaviour and preventing potential bugs related to missed updates.</p>
<p>If your UI isn’t updating correctly, this is often the culprit.</p>
<h2 id="heading-use-useeffect-last">Use <code>useEffect</code> Last</h2>
<p>Here’s a pro tip: Don’t rush to use <code>useEffect</code>. 🙅‍♂️ It’s powerful but can lead to messy code if overused. React frameworks provide solutions to manage side effects more elegantly. For data fetching, consider libraries like TanStack Query or SWR that handle requests and caching efficiently, leading to a better user experience.</p>
<p>Alternative strategies:</p>
<ul>
<li><p>Derive values directly.</p>
</li>
<li><p>Respond to events with handlers.</p>
</li>
</ul>
<p>Fetch data on the server or with dedicated libraries.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>React is a robust library, but knowing how to use it effectively can make all the difference. These lessons are just the beginning.</p>
<p>Having an in-depth idea about in and outs of any technology helps you during development and optimization.</p>
<p>React Js is the perfect library for modern development it has everything to offer for development and optimization</p>
<p>Thanks for reading, and happy coding! 🎉</p>
<ul>
<li><p>Follow Me on X: <a target="_blank" href="https://x.com/prankurpandeyy">Prankur's Twitter</a></p>
</li>
<li><p>Follow me on LinkedIn: <a target="_blank" href="https://linkedin.com/in/prankurpandeyy">Prankur's Linkedin</a></p>
</li>
<li><p>Look at my Portfolio here: <a target="_blank" href="https://prankurpandeyy.netlify.app">Prankur's Portfolio</a></p>
</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ New React 19 Features You Should Know –  Explained with Code Examples ]]>
                </title>
                <description>
                    <![CDATA[ React.js is 11 years old, and it has become one of the most popular JavaScript libraries out there. And now, React is transitioning from version 18 to version 19. So hold onto your hats, React enthusiasts 🎩. React 19 has recently landed, and it’s a ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/new-react-19-features-you-should-know-with-code-examples/</link>
                <guid isPermaLink="false">66faefcb4098ec2dc4763c03</guid>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React 19 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Prankur Pandey ]]>
                </dc:creator>
                <pubDate>Mon, 30 Sep 2024 18:36:59 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1727367514092/a75164cd-1e2e-4b0d-8c2e-5d000cee01f0.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>React.js is 11 years old, and it has become one of the most popular JavaScript libraries out there.</p>
<p>And now, React is transitioning from version 18 to version 19. So hold onto your hats, React enthusiasts 🎩. React 19 has recently landed, and it’s a game-changer.</p>
<p>But before you start worrying about a steep learning curve, here’s some great news: React 19 isn’t about adding complexity – it’s about removing it.</p>
<p>In this guide, you’ll learn how this new version will simplify your coding life and turbocharge your React projects.</p>
<h2 id="heading-what-well-cover">What We’ll Cover:</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-introduction-to-react-19">Introduction to React 19</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-well-cover">What We’ll Cover:</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-react-19-features">React 19 Features</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-react-compiler-the-magic-behind-the-scenes">React Compiler: The Magic Behind the Scenes</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-no-more-memoization-hooks">No More Memoization Hooks</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-no-forwardref-simplified-ref-handling">No forwardRef: Simplified Ref Handling</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-new-use-hook-a-game-changer">The New use() Hook: A Game Changer</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-fetch-data-with-use-vs-useeffect">Fetch Data with use() vs. useEffect</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-use-context-with-use">Use Context with use()</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-directives-a-fresh-approach">Directives: A Fresh Approach</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-actions-streamlined-form-handling">Actions: Streamlined Form Handling</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-useformstatus-managing-form-state">useFormStatus(): Managing Form State</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-useformstate-stateful-form-actions">useFormState(): Stateful Form Actions</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-useoptimistic-enhancing-user-experience">useOptimistic(): Enhancing User Experience</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<p>Excited to try out React 19? 🤩 While it's still in the canary stage, you can start experimenting with it by installing the canary version today. This update promises a smoother experience by automating what used to be manual optimizations.</p>
<h2 id="heading-react-compiler-the-magic-behind-the-scenes"><strong>React Compiler: The Magic Behind the Scenes</strong></h2>
<p>The star of React 19 is its new compiler. 🎉 This compiler transforms your React code into plain JavaScript, which boosts performance and, even better, frees you from constantly tweaking performance manually.</p>
<p>To optimize our React applications, we use some inbuilt methods like <code>useMemo</code> or <code>useCallback</code>. This tells React not to compile the code again if the inputs don’t change.</p>
<p>But if you forget to apply memoization, it results in wasting React resources and computational power. To deal with this, React 19 introduced React Compiler.</p>
<p>Say goodbye to manual optimizations and hello to cleaner code:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// No need for useCallback/useMemo</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Component</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Optimized!<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
}
</code></pre>
<p><strong>Code explanation:</strong> The new compiler turns React code into optimized JavaScript, removing the need for manual optimizations like memoization.</p>
<h2 id="heading-no-more-memoization-hooks"><strong>No More Memoization Hooks</strong></h2>
<p>Remember the days of juggling between <code>useCallback</code>, <code>useMemo</code>, and <code>memo</code> to optimize performance? 😅 With React 19, those days are over. The new compiler optimizes your code behind the scenes, so you can drop these hooks and focus on writing beautiful, clean React components.</p>
<p>Memoization solves the complex calculation problems inside React, resulting in application optimization and performance improvements.</p>
<p>Previously, to apply Memoziation you had to use the <code>useMemo</code> hook. Here’s what that looked like in code:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">//React 18 </span>
<span class="hljs-keyword">import</span> React, { useState, useMemo } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">const</span> ExpensiveComponent = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-number">0</span>);
  <span class="hljs-keyword">const</span> [input, setInput] = useState(<span class="hljs-string">''</span>);

  <span class="hljs-comment">// Memoize expensive calculation</span>
  <span class="hljs-keyword">const</span> expensiveCalculation = useMemo(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Calculating..."</span>);
    <span class="hljs-keyword">let</span> sum = <span class="hljs-number">0</span>;
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">1000000000</span>; i++) {
      sum += i;
    }
    <span class="hljs-keyword">return</span> sum;
  }, [count]); <span class="hljs-comment">// Recalculate only when `count` changes</span>

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Expensive Calculation: {expensiveCalculation}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> setCount(count + 1)}&gt;Increment Count ({count})<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span> 
        <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> 
        <span class="hljs-attr">value</span>=<span class="hljs-string">{input}</span> 
        <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> setInput(e.target.value)} 
        placeholder="Type something"
      /&gt;
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> ExpensiveComponent;
</code></pre>
<p><strong>Code Explanation</strong>:</p>
<ul>
<li><p>The <code>expensiveCalculation</code> the function is computationally heavy, but using <code>useMemo</code>, it's only recalculated when <code>count</code> changes.</p>
</li>
<li><p>The input field can be updated without triggering a recalculation of <code>expensiveCalculation</code>, which optimizes performance.</p>
</li>
</ul>
<p>Now with the compiler in React 19, this is no longer required. You can just write your code and React will apply the memoziation.</p>
<p>Look at this code example:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// No need for manual memoization React 19</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Component</span>(<span class="hljs-params">{ children }</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>{children}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
}
</code></pre>
<p><strong>Code explanation:</strong> you no longer need to use <code>useCallback</code> or <code>useMemo</code> – React 19 automatically handles optimizations.</p>
<h2 id="heading-no-forwardref-simplified-ref-handling"><strong>No</strong> <code>forwardRef</code><strong>: Simplified Ref Handling</strong></h2>
<p>Using <code>forwardRef</code> to pass refs around used to be a bit of a chore. 😓 But in React 19, you can pass refs just like any other prop. This streamlines your component code and makes ref handling a breeze. 🧹</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Child</span>(<span class="hljs-params">{ innerRef }</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">{innerRef}</span> /&gt;</span></span>;
}
</code></pre>
<p><strong>Code explanation :</strong><code>forwardRef</code> is no longer required – instead, refs are passed like regular props.</p>
<h2 id="heading-the-new-use-hook-a-game-changer"><strong>The New</strong> <code>use()</code> Hook: A Game Changer</h2>
<p>The versatile new <code>use()</code> hook replaces multiple hooks, such as <code>useEffect</code> for data fetching as well as <code>useContext</code> and <code>useState</code> for consuming context data. It simplifies your code by handling promises and context with a single, elegant solution.</p>
<p>Look at this code example:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { useState, useEffect } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">const</span> DataFetchingComponent = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> [data, setData] = useState(<span class="hljs-literal">null</span>);
  <span class="hljs-keyword">const</span> [loading, setLoading] = useState(<span class="hljs-literal">true</span>);
  <span class="hljs-keyword">const</span> [error, setError] = useState(<span class="hljs-literal">null</span>);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> fetchData = <span class="hljs-keyword">async</span> () =&gt; {
      <span class="hljs-keyword">try</span> {
        <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">'https://api.example.com/data'</span>);
        <span class="hljs-keyword">const</span> result = <span class="hljs-keyword">await</span> response.json();
        setData(result);
      } <span class="hljs-keyword">catch</span> (err) {
        setError(err.message);
      } <span class="hljs-keyword">finally</span> {
        setLoading(<span class="hljs-literal">false</span>);
      }
    };

    fetchData();
  }, []);

  <span class="hljs-keyword">if</span> (loading) <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>;
  <span class="hljs-keyword">if</span> (error) <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Error: {error}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>;

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Data:<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">pre</span>&gt;</span>{JSON.stringify(data, null, 2)}<span class="hljs-tag">&lt;/<span class="hljs-name">pre</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> DataFetchingComponent;
</code></pre>
<p><strong>Code Explanation:</strong></p>
<ul>
<li><p><code>useEffect</code> is triggered after the component mounts to initiate data fetching.</p>
</li>
<li><p>We maintain <code>loading</code>, <code>data</code>, and <code>error</code> states to manage and display the appropriate UI.</p>
</li>
<li><p>Once the data is fetched, the state updates, triggering a re-render to display the data.</p>
</li>
</ul>
<p>Now with the help of the new <code>use()</code> hook in React 19, data fetching becomes easier and you don’t need to depend on state management hooks like <code>useState()</code> anymore.</p>
<p>Here is an example:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { use } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-comment">// Function to fetch data</span>
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fetchData</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">'https://api.example.com/data'</span>);
  <span class="hljs-keyword">if</span> (!response.ok) {
    <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'Failed to fetch data'</span>);
  }
  <span class="hljs-keyword">return</span> response.json();
}

<span class="hljs-keyword">const</span> DataFetchingComponent = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-comment">// `use()` suspends the component until the promise resolves</span>
  <span class="hljs-keyword">const</span> data = use(fetchData());

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Data:<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">pre</span>&gt;</span>{JSON.stringify(data, null, 2)}<span class="hljs-tag">&lt;/<span class="hljs-name">pre</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> DataFetchingComponent;
</code></pre>
<p><strong>Code explanation:</strong></p>
<ul>
<li><p><strong>Suspense and</strong> <code>use()</code>: When you use <code>use()</code>, it suspends the component rendering until the promise resolves. If an error occurs, it can also trigger a <code>Suspense</code> error boundary.</p>
</li>
<li><p><strong>No need for</strong> <code>useEffect</code>: There's no need to manually manage data fetching with side effects, as React handles it under the hood.</p>
</li>
<li><p><strong>Error and loading states</strong>: These can now be managed globally using <code>Suspense</code> error boundaries without manually tracking states like <code>loading</code> or <code>error</code>.</p>
</li>
</ul>
<h3 id="heading-fetch-data-with-use-vs-useeffect"><strong>Fetch Data with</strong> <code>use()</code> vs. <code>useEffect</code></h3>
<p>Fetching data used to require a bit of boilerplate with <code>useEffect</code>. With <code>use()</code>, you just resolve the promise and use React Suspense for a clean, easy data-fetching experience. 🧼 This means less code and more focus on what matters.</p>
<h3 id="heading-use-context-with-use"><strong>Use Context with</strong> <code>use()</code></h3>
<p>Handling context data has also become more straightforward. The new <code>use()</code> hook can now consume context directly, eliminating the need for <code>useContext</code> and making context management more intuitive. 🎯</p>
<h2 id="heading-directives-a-fresh-approach"><strong>Directives: A Fresh Approach</strong></h2>
<p>If you’ve been using Next.js, you might have seen directives already. 🌐 React 19 introduces directives to simplify component configuration. Use <code>use client</code> for client-side components and <code>use server</code> for server-side ones. It’s as easy as adding a string at the top of your file:</p>
<pre><code class="lang-javascript"><span class="hljs-string">"use client"</span>;
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ClientComponent</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Client Side<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
}
</code></pre>
<p><strong>Code explanation:</strong> Use <code>use client</code> and <code>use server</code> to declare client-side or server-side components.</p>
<h2 id="heading-actions-streamlined-form-handling"><strong>Actions: Streamlined Form Handling</strong></h2>
<p>Forms just got a major upgrade with actions. 💥 Actions are functions connected to form submissions that can run on either the server or client side. This means cleaner code and a smoother form-handling process.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">action</span>(<span class="hljs-params">formData</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> handleSubmit(formData);
}
</code></pre>
<p><strong>Code explanation:</strong> Actions handle form submissions, running on the client or server.</p>
<h4 id="heading-client-actions-a-practical-example"><strong>Client Actions: A Practical Example</strong></h4>
<p>Client actions are great for immediate feedback. For example, alerting users with their input values has never been simpler. Just use <code>use client</code> and connect the form action to the form’s action prop. Easy peasy! 🥳</p>
<h2 id="heading-useformstatus-managing-form-state"><code>useFormStatus()</code>: Managing Form State</h2>
<p>Keep track of your form submissions with the <code>useFormStatus()</code> hook. 🕒 It helps manage form states like disabling the submit button while the form is pending. This is a must-have for smooth user experiences.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> { pending } = useFormStatus();
<span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">disabled</span>=<span class="hljs-string">{pending}</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>;
</code></pre>
<p><strong>Code explanation:</strong> <code>useFormStatus()</code> tracks form submission states, like disabling a button during submission.</p>
<h2 id="heading-useformstate-stateful-form-actions"><code>useFormState()</code>: Stateful Form Actions</h2>
<p>We now have <code>useFormState()</code>, which is a new hook for managing form state. 🎛️ It’s similar to <code>useState</code> but works with form actions, allowing you to access both previous state and submitted data. It’s perfect for scenarios like adding items to a cart.</p>
<p>I feel <code>useFormState()</code> is closely associated with the features in the React Hook Form library, as its working features are mostly similar.</p>
<p>Here is a code example to help you understand it better:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> { useForm, useFormState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-hook-form'</span>;

<span class="hljs-keyword">const</span> MyForm = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> { register, handleSubmit, control } = useForm();
  <span class="hljs-keyword">const</span> { isSubmitting, isDirty, isValid } = useFormState({ control });

  <span class="hljs-keyword">const</span> onSubmit = <span class="hljs-function">(<span class="hljs-params">data</span>) =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(data);
  };

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">onSubmit</span>=<span class="hljs-string">{handleSubmit(onSubmit)}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">"firstName"</span>&gt;</span>First Name:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> {<span class="hljs-attr">...register</span>('<span class="hljs-attr">firstName</span>', { <span class="hljs-attr">required:</span> <span class="hljs-attr">true</span> })} /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">"lastName"</span>&gt;</span>Last Name:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> {<span class="hljs-attr">...register</span>('<span class="hljs-attr">lastName</span>', { <span class="hljs-attr">required:</span> <span class="hljs-attr">true</span> })} /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span> <span class="hljs-attr">disabled</span>=<span class="hljs-string">{isSubmitting</span> || !<span class="hljs-attr">isValid</span>}&gt;</span>
        Submit
      <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Form is {isDirty ? 'dirty' : 'pristine'}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Submitting: {isSubmitting ? 'Yes' : 'No'}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> MyForm;
</code></pre>
<p><strong>Code explanation:</strong></p>
<ol>
<li><p><strong>Import Hooks</strong>: We import <code>useForm</code> and <code>useFormState</code> from <code>react-hook-form</code>.</p>
</li>
<li><p><strong>Setup Form</strong>:</p>
<ul>
<li><p><code>useForm</code>: This hook initializes the form methods, including <code>register</code>, <code>handleSubmit</code>, and <code>control</code>.</p>
</li>
<li><p><code>useFormState</code>: We use this hook to extract form-state properties like <code>isSubmitting</code>, <code>isDirty</code>, and <code>isValid</code>.</p>
</li>
</ul>
</li>
<li><p><strong>Register Inputs</strong>: We register each input field using the <code>register</code> function, specifying any validation rules (for example <code>required</code>).</p>
</li>
<li><p><strong>Handle Submission</strong>: The <code>onSubmit</code> function handles the form submission, where you can perform your desired actions with the form data.</p>
</li>
<li><p><strong>Form State Info</strong>: We display the form's current state (whether it's dirty or submitted) below the form.</p>
</li>
</ol>
<h3 id="heading-key-features-of-useformstate">Key Features of <code>useFormState</code>:</h3>
<ul>
<li><p><strong>Performance</strong>: <code>useFormState</code> only re-renders when the specific fields it's monitoring change, making it efficient.</p>
</li>
<li><p><strong>Controlled State</strong>: You can easily manage and observe the form's state without writing boilerplate code for handling changes and validations.</p>
</li>
</ul>
<h2 id="heading-useoptimistic-enhancing-user-experience"><code>useOptimistic()</code>: Enhancing User Experience</h2>
<p>For real-time applications, the <code>useOptimistic()</code> hook is helpful. 💬 It allows for optimistic updates, making your app feel snappy by updating the UI instantly and syncing with the server in the background.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> [optimisticState, setOptimistic] = useOptimistic(initialState);
</code></pre>
<p><strong>Code explanation:</strong> Enables optimistic UI updates before syncing with the server.</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>React 19 is here to simplify your coding experience and enhance performance. 🎉 To dive deep into all these features and more, check out my recent <a target="_blank" href="https://www.freecodecamp.org/news/learn-react-hooks-with-example-code/">article</a> about React Hooks.</p>
<p>If you’re ready to streamline your React projects, embrace the future with React 19 and make your development experience smoother and more enjoyable. 🌟</p>
<ul>
<li><p>Follow Me on X: <a target="_blank" href="https://x.com/prankurpandeyy">Prankur's Twitter</a></p>
</li>
<li><p>Follow me on Linkedin: <a target="_blank" href="https://linkedin.com/in/prankurpandeyy">Prankur's Linkedin</a></p>
</li>
<li><p>Look at my Portfolio here: <a target="_blank" href="https://prankurpandeyy.netlify.app">Prankur's Portfolio</a></p>
</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Learn React Hooks – Common Hooks Explained with Code Examples ]]>
                </title>
                <description>
                    <![CDATA[ Web development is a popular field in the tech industry. It involves building web software using HTML, CSS, and JavaScript – sometimes with the help of various frameworks and libraries. Using libraries and frameworks allows developers to focus more o... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-react-hooks-with-example-code/</link>
                <guid isPermaLink="false">66f43493173ff3821d17571a</guid>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ReactHooks ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Prankur Pandey ]]>
                </dc:creator>
                <pubDate>Wed, 25 Sep 2024 16:04:35 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1727212733982/7c9b8ae3-e8ac-4e20-b154-7edc60a6985a.avif" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Web development is a popular field in the tech industry. It involves building web software using HTML, CSS, and JavaScript – sometimes with the help of various frameworks and libraries.</p>
<p>Using libraries and frameworks allows developers to focus more on the development while the tools take care of certain functionality in the background. And React.js is a popular JavaScript library for building front-end applications.</p>
<p>In this article, you’ll learn about the backbone of React which is <strong>Hooks,</strong> and how they can make your life easier as a developer.</p>
<h2 id="heading-what-well-cover">What We’ll Cover:</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites:</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-getting-started">Getting Started</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-are-hooks">What are Hooks?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-types-of-react-hooks">Types of React Hooks</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-state-management-hooks">State Management Hooks</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-effect-hooks">Effect Hooks</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-ref-hook">Ref Hook</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-performance-hooks">Performance Hooks</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-context-hook">Context Hook</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-transition-hook">Transition Hook</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-some-random-hooks">Some Random Hooks</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-prerequisites">Prerequisites:</h2>
<ul>
<li><p>You should know the basics of JavaScript.</p>
</li>
<li><p>You should also know the basics of React, like setting up an app, updating it, and using state.</p>
</li>
</ul>
<h2 id="heading-getting-started">Getting Started</h2>
<p>So you've decided to build a React app—congratulations! 🎉 But as you dive into the world of React hooks, you might find yourself feeling overwhelmed. With a plethora of hooks available, figuring out which ones to use and when can be a bit daunting.</p>
<p>Well, don’t worry – in this guide, I’ll break down every major hook so you can see how they fit together. We’ll also discuss which ones you'll use more frequently versus more rarely.</p>
<p>By the end of this article, you'll have a comprehensive map of React hooks and their practical applications.</p>
<h2 id="heading-what-are-hooks"><strong>What are Hooks?</strong></h2>
<p>In JavaScript, we use variables to store data and later perform operations on that data.</p>
<p>Hooks in React work similarly, but they are designed to manage state in <strong>functional components</strong>. Instead of manually declaring a single variable, hooks like <code>useState</code> give us a way to declare stateful values along with a setter function to update that state.</p>
<p>Here’s a simple example:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Counter</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-number">0</span>);  <span class="hljs-comment">// Initialize state and state updater</span>

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>You clicked {count} times<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> setCount(count + 1)}&gt;Click me<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>In this code, I use the <code>useState</code> hook to declare a piece of state called <code>count</code> and set its initial value to 0. The <code>setCount</code> function allows us to update this state. Every time the button is clicked, we use <code>setCount</code> to increase <code>count</code> by 1. When the state updates, React re-renders the component to reflect the change.</p>
<p>Unlike declaring <code>let count = 0</code>, using <code>useState</code> lets React remember the state across renders and ensures that the UI updates correctly.</p>
<h2 id="heading-types-of-react-hooks">Types of React Hooks</h2>
<p>To make things easier, you can think of React hooks as falling into eight major categories:</p>
<ul>
<li><p><strong>State Management Hooks</strong> – For handling state.</p>
</li>
<li><p><strong>Effect Hooks</strong> – For side effects.</p>
</li>
<li><p><strong>Ref Hooks</strong> – For referencing JavaScript values or DOM elements.</p>
</li>
<li><p><strong>Performance Hooks</strong> – For optimizing performance.</p>
</li>
<li><p><strong>Context Hooks</strong> – For accessing React context.</p>
</li>
<li><p><strong>Transition Hooks</strong> – For smoother user experiences.</p>
</li>
<li><p><strong>Some Random Hooks</strong> – Special-purpose hooks.</p>
</li>
<li><p><strong>New Hooks (React 19)</strong> – Cutting-edge tools introduced in the latest React version.</p>
</li>
</ul>
<p>In React, you can also build custom hooks for different use cases. Every hook starts with the <code>use</code> keyword – even custom hooks start with this structure. This keyword is reserved for Hooks in React.</p>
<p>Let’s explore these hooks in detail.</p>
<h3 id="heading-state-management-hooks"><strong>State Management Hooks</strong></h3>
<h4 id="heading-1-usestate"><strong>1.</strong> <code>useState</code></h4>
<p>The <code>useState</code> hook is the bread and butter of React. It’s the most commonly used hook, and it’s key for managing state in functional components. With <code>useState</code>, you can capture user inputs, show or hide components, and manage numbers, like in an ecommerce app with a shopping cart.</p>
<p><code>useState</code> is versatile and straightforward: you initialize it with a value, and it returns a state variable and an updater function.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React, { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Counter</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-number">0</span>);  <span class="hljs-comment">// Initialize state and state updater</span>

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>You clicked {count} times<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> setCount(count + 1)}&gt;Click me<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p><strong>Code explanation</strong>: <code>useState</code> initializes the state (count) and provides a function (<code>setCount</code>) to update that state.</p>
<h4 id="heading-2-usereducer"><strong>2.</strong> <code>useReducer</code></h4>
<p>When <code>useState</code> isn’t enough, <code>useReducer</code> comes into play. This hook is perfect for managing complex state logic.</p>
<p>It uses a reducer function to simplify state updates and is especially useful when multiple state variables are interdependent or when actions need to be dispatched.</p>
<p>Think of it as an upgrade for managing more complicated state scenarios. Here’s an example:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React, { useReducer } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">const</span> initialState = { <span class="hljs-attr">count</span>: <span class="hljs-number">0</span> };

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">reducer</span>(<span class="hljs-params">state, action</span>) </span>{
  <span class="hljs-keyword">switch</span> (action.type) {
    <span class="hljs-keyword">case</span> <span class="hljs-string">'increment'</span>:
      <span class="hljs-keyword">return</span> { <span class="hljs-attr">count</span>: state.count + <span class="hljs-number">1</span> };
    <span class="hljs-keyword">case</span> <span class="hljs-string">'decrement'</span>:
      <span class="hljs-keyword">return</span> { <span class="hljs-attr">count</span>: state.count - <span class="hljs-number">1</span> };
    <span class="hljs-keyword">default</span>:
      <span class="hljs-keyword">return</span> state;
  }
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Counter</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [state, dispatch] = useReducer(reducer, initialState);

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Count: {state.count}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> dispatch({ type: 'increment' })}&gt;+<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> dispatch({ type: 'decrement' })}&gt;-<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p><strong>Code explanation</strong>: <code>useReducer</code> is useful for managing complex state updates, like handling multiple related actions.</p>
<p><strong>3.</strong> <code>useSyncExternalStore</code><br><code>useSyncExternalStore</code> is a hook for integrating non-React state stores into your React components.</p>
<p>While not commonly used, it’s crucial if you’re building your own state management library from scratch.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React, { useSyncExternalStore } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">const</span> externalStore = {
  <span class="hljs-attr">subscribe</span>: <span class="hljs-function">(<span class="hljs-params">callback</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> interval = <span class="hljs-built_in">setInterval</span>(callback, <span class="hljs-number">1000</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">clearInterval</span>(interval);
  },
  <span class="hljs-attr">getSnapshot</span>: <span class="hljs-function">() =&gt;</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>().toLocaleTimeString(),
};

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Clock</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> time = useSyncExternalStore(externalStore.subscribe, externalStore.getSnapshot);
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>{time}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
}
</code></pre>
<p><strong>Code explanation</strong>: <code>useSyncExternalStore</code> lets you connect your React component to non-React data sources, like global stores.</p>
<h3 id="heading-effect-hooks"><strong>Effect Hooks</strong></h3>
<p><strong>1.</strong> <code>useEffect</code><br>The <code>useEffect</code> hook performs side effects on your components. Whether you’re interacting with the DOM or fetching data, <code>useEffect</code> is your go-to. It runs after each render by default, but you can customize its behavior using a dependency array.</p>
<p>But you should consider using more specialized tools or libraries like React Query for event-based or render-based side effects.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React, { useState, useEffect } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">DataFetcher</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [data, setData] = useState(<span class="hljs-literal">null</span>);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    fetch(<span class="hljs-string">'https://api.example.com/data'</span>)
      .then(<span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> response.json())
      .then(<span class="hljs-function">(<span class="hljs-params">data</span>) =&gt;</span> setData(data));
  }, []);  <span class="hljs-comment">// Empty dependency array means it runs once on mount</span>

  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>{data ? JSON.stringify(data) : 'Loading...'}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
}
</code></pre>
<p><strong>Code explanation</strong>: The <code>useEffect</code> hook fetches data when the component mounts. The effect will only run one time when the array is empty.</p>
<p><strong>2.</strong> <code>useLayoutEffect</code><br><code>useLayoutEffect</code> works similarly to <code>useEffect</code> but runs synchronously right after the DOM has been updated. It’s used for operations that need to happen before the browser paints the UI, like measuring elements.</p>
<p>Use it sparingly, as it runs less frequently than <code>useEffect</code>. Here’s an example:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React, { useLayoutEffect, useRef } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Measure</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> divRef = useRef();

  useLayoutEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(divRef.current.getBoundingClientRect());
  }, []);

  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">{divRef}</span>&gt;</span>Measure me!<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
}
</code></pre>
<p><strong>Code explanation</strong>: <code>useLayoutEffect</code> measures DOM elements before the browser repaints.</p>
<p><strong>3.</strong> <code>useInsertionEffect</code><br>Exclusively for CSS-in-JS library developers, <code>useInsertionEffect</code> runs before <code>useEffect</code> and <code>useLayoutEffect</code> to ensure that CSS styles are inserted properly. It’s niche, but crucial for maintaining style integrity in complex applications.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React, { useInsertionEffect, useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">StyledComponent</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [text, setText] = useState(<span class="hljs-string">'Hover over me!'</span>);

  useInsertionEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> style = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'style'</span>);
    style.textContent = <span class="hljs-string">`
      .hovered {
        color: red;
        font-size: 24px;
        transition: color 0.3s ease;
      }
    `</span>;
    <span class="hljs-built_in">document</span>.head.appendChild(style);

    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
      <span class="hljs-built_in">document</span>.head.removeChild(style);
    };
  }, []);

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>
      <span class="hljs-attr">className</span>=<span class="hljs-string">"hovered"</span>
      <span class="hljs-attr">onMouseEnter</span>=<span class="hljs-string">{()</span> =&gt;</span> setText('You hovered over me!')}
      onMouseLeave={() =&gt; setText('Hover over me!')}
    &gt;
      {text}
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p><strong>Code explanation</strong>: The <code>useInsertionEffect</code> hook is used to inject styles into the DOM at runtime, making the component’s styling dynamic and scoped only to that component.</p>
<h3 id="heading-ref-hook"><strong>Ref Hook</strong></h3>
<p>1. <code>useRef</code><br><code>useRef</code> allows you to persist values across renders without causing re-renders. It's perfect for storing mutable values or referencing DOM elements. Whether you’re handling intervals, storing a DOM node, or keeping track of the previous state, <code>useRef</code> has you covered.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React, { useRef } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">FocusInput</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> inputRef = useRef(<span class="hljs-literal">null</span>);

  <span class="hljs-keyword">const</span> handleFocus = <span class="hljs-function">() =&gt;</span> {
    inputRef.current.focus();
  };

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">{inputRef}</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{handleFocus}</span>&gt;</span>Focus Input<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p><strong>Code explanation:</strong> This React code uses <code>useRef</code> to create a reference to an input element. When the button is clicked, the <code>handleFocus</code> function triggers the input field to gain focus using <code>inputRef.current.focus()</code>.</p>
<h3 id="heading-performance-hooks"><strong>Performance Hooks</strong></h3>
<p><strong>1.</strong> <code>useMemo</code><br>For optimizing performance, <code>useMemo</code> is your friend. It caches the results of expensive computations and only recalculates when dependencies change. This can significantly improve performance, especially in scenarios involving heavy calculations.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React, { useState, useMemo } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ExpensiveCalculation</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-number">0</span>);

  <span class="hljs-keyword">const</span> expensiveComputation = useMemo(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">return</span> count * <span class="hljs-number">100</span>;
  }, [count]);

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Expensive Computation: {expensiveComputation}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> setCount(count + 1)}&gt;Increase Count<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p><strong>Code explanation:</strong>This React code uses <code>useMemo</code> to optimize an expensive calculation (<code>count * 100</code>). The calculation only re-runs when <code>count</code> changes. The button increments <code>count</code>, triggering a UI update with the new result.</p>
<p><strong>2.</strong> <code>useCallback</code><br><code>useCallback</code> is similar to <code>useMemo</code>, but it focuses on memoizing callback functions. This is useful for preventing unnecessary re-renders of child components by keeping functions stable across renders.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React, { useState, useCallback } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Child</span>(<span class="hljs-params">{ onClick }</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{onClick}</span>&gt;</span>Click me<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Parent</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-number">0</span>);

  <span class="hljs-keyword">const</span> handleClick = useCallback(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Clicked'</span>);
  }, []);

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Child</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{handleClick}</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Count: {count}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> setCount(count + 1)}&gt;Increase Count<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p><strong>Code explanation:</strong> This React code uses <code>useCallback</code> to memoize the <code>handleClick</code> function, preventing re-creation on every render. The <code>Child</code> component uses this function for its button. The parent updates <code>count</code> independently.</p>
<h3 id="heading-context-hook"><strong>Context Hook</strong></h3>
<p>1. <code>useContext</code><br>The <code>useContext</code> hook simplifies accessing context values. It reads the value from the nearest context provider and works seamlessly across nested components. This makes it easier to manage global states or themes.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React, { useContext, createContext } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">const</span> ThemeContext = createContext(<span class="hljs-string">'light'</span>);

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ThemedButton</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> theme = useContext(ThemeContext);
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span>{theme}<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">ThemeContext.Provider</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"dark"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">ThemedButton</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">ThemeContext.Provider</span>&gt;</span></span>
  );
}
</code></pre>
<p><strong>Code explanation</strong>: This React code uses <code>createContext</code> to create a <code>ThemeContext</code>. <code>useContext</code> accesses the context value, displaying it in the button. The <code>App</code> component provides "dark" as the theme to <code>ThemedButton</code>.</p>
<h3 id="heading-transition-hook"><strong>Transition Hook</strong></h3>
<p>1. <code>useTransition</code><br><code>useTransition</code> lets you mark specific state updates as low-priority, enhancing the user experience by keeping the app more responsive during intensive computations or transitions. This improves the user experience by making the app more responsive.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React, { useState, useTransition } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">TransitionComponent</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [count, setCount] = useState(<span class="hljs-number">0</span>);
  <span class="hljs-keyword">const</span> [isPending, startTransition] = useTransition();

  <span class="hljs-keyword">const</span> handleClick = <span class="hljs-function">() =&gt;</span> {
    startTransition(<span class="hljs-function">() =&gt;</span> {
      setCount(<span class="hljs-function">(<span class="hljs-params">prevCount</span>) =&gt;</span> prevCount + <span class="hljs-number">1</span>);
    });
  };

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{handleClick}</span>&gt;</span>Increase Count<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
      {isPending ? <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span> : <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Count: {count}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>}
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p><strong>Code explanation:</strong> This code uses <code>useTransition</code> to increment <code>count</code> without blocking the UI. While the state updates, <code>isPending</code> shows "Loading...". Clicking the button triggers a smooth, non-blocking state transition.</p>
<h3 id="heading-some-random-hooks"><strong>Some Random Hooks</strong></h3>
<p><strong>1.</strong> <code>useDeferredValue</code><br>Similar to <code>useTransition</code>, <code>useDeferredValue</code> helps in deferring state updates to keep the app responsive. It schedules updates to happen at an optimal time, enhancing the user experience without manual intervention.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React, { useState, useDeferredValue } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">DeferredComponent</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [value, setValue] = useState(<span class="hljs-string">''</span>);
  <span class="hljs-keyword">const</span> deferredValue = useDeferredValue(value);

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{value}</span> <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> setValue(e.target.value)} /&gt;
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Deferred Value: {deferredValue}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p><strong>Code explanation</strong>: <code>useDeferredValue</code> delays the update of <code>deferredValue</code> to ensure that the UI remains responsive.</p>
<p><strong>2.</strong> <code>useDebugValue</code><br><code>useDebugValue</code> is a hook primarily for debugging. It lets you label custom hooks in React DevTools, making it easier to track and debug your hooks.</p>
<pre><code class="lang-jsx">
<span class="hljs-keyword">import</span> React, { useDebugValue, useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">useCustomHook</span>(<span class="hljs-params">value</span>) </span>{
  useDebugValue(value ? <span class="hljs-string">"Has Value"</span> : <span class="hljs-string">"No Value"</span>); <span class="hljs-keyword">return</span> value; }
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">DebugComponent</span>(<span class="hljs-params"></span>) </span>{ <span class="hljs-keyword">const</span> [value, setValue] = useState(<span class="hljs-string">''</span>); <span class="hljs-keyword">const</span> customValue = useCustomHook(value);

<span class="hljs-keyword">return</span> (
 <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{value}</span> <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> setValue(e.target.value)} /&gt;</span>
Value: {customValue}
); }
</code></pre>
<p><strong>Code explanation:</strong> This code uses <code>useDebugValue</code> to show "Has Value" or "No Value" in React DevTools based on <code>value</code>. <code>useCustomHook</code> is used in <code>DebugComponent</code> to track the input state and display it dynamically.</p>
<p><strong>3.</strong> <code>useId</code><br><code>useId</code> generates unique IDs for elements, ensuring that form inputs and labels are properly linked without conflicts. It’s particularly useful when dealing with dynamically repeated elements.</p>
<pre><code class="lang-javascript">
<span class="hljs-keyword">import</span> React, { useId } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">FormComponent</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> id = useId();

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">{id}</span>&gt;</span>Name: <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">id</span>=<span class="hljs-string">{id}</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p><strong>Code explanation</strong>: <code>useId</code> ensures that form elements have unique IDs, avoiding potential conflicts.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>React hooks can seem overwhelming at first, but with this guide, you’re well-equipped to handle them. Mastering these hooks improves your React skills and makes your development process smoother and more efficient.</p>
<p>For a deeper dive and hands-on practice, check out my comprehensive React Bootcamp, where you’ll find interactive challenges, videos, and cheat sheets to reinforce your knowledge.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
