<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rajesh Singh</title>
    <description>The latest articles on DEV Community by Rajesh Singh (@rajinh24).</description>
    <link>https://dev.to/rajinh24</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1859865%2F8cab12d0-5343-4848-a927-b2867ce7bbb7.jpeg</url>
      <title>DEV Community: Rajesh Singh</title>
      <link>https://dev.to/rajinh24</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rajinh24"/>
    <language>en</language>
    <item>
      <title>SlimPDF - A Lightweight and Privacy-Friendly PDF Compressor</title>
      <dc:creator>Rajesh Singh</dc:creator>
      <pubDate>Mon, 17 Nov 2025 11:47:07 +0000</pubDate>
      <link>https://dev.to/rajinh24/slimpdf-a-lightweight-and-privacy-friendly-pdf-compressor-hnn</link>
      <guid>https://dev.to/rajinh24/slimpdf-a-lightweight-and-privacy-friendly-pdf-compressor-hnn</guid>
      <description>&lt;p&gt;If you’ve ever tried emailing a PDF only to see the dreaded “File size too large” popup, welcome to the club.&lt;br&gt;
And if you’ve ever uploaded a suspiciously important PDF to an online “FREE PDF COMPRESSOR 🔥” website, only to worry whether your passport is now the newest NFT on the dark web… welcome to the club’s VIP lounge. 😅&lt;/p&gt;

&lt;p&gt;At some point, I got tired of choosing between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Bloated PDFs, or&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sending sensitive documents to random cloud services&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, like any developer on a mission, I built my own solution.&lt;/p&gt;

&lt;p&gt;Meet SlimPDF: a tiny, elegant, local-first PDF compressor app built using Flask and Ghostscript, designed to shrink your PDFs safely and privately, everything stays on your machine.&lt;/p&gt;

&lt;p&gt;🔗 GitHub Repo: &lt;a href="https://github.com/rajks24/SlimPDF" rel="noopener noreferrer"&gt;https://github.com/rajks24/SlimPDF&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🎯 Why I Built SlimPDF&lt;/p&gt;

&lt;p&gt;Most PDF compression tools are convenient — but they run on someone else’s server.&lt;br&gt;
That’s fine for a holiday brochure… but not so fine for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Passport scans&lt;/li&gt;
&lt;li&gt;Visa documents&lt;/li&gt;
&lt;li&gt;Work contracts&lt;/li&gt;
&lt;li&gt;Medical files&lt;/li&gt;
&lt;li&gt;Bank statements&lt;/li&gt;
&lt;li&gt;School forms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Anything that makes your anxiety go up when uploading it online 😬&lt;/p&gt;

&lt;p&gt;I needed a tool that:&lt;/p&gt;

&lt;p&gt;✔ Works offline&lt;br&gt;
✔ Compresses PDFs instantly&lt;br&gt;
✔ Never uploads anything anywhere&lt;br&gt;
✔ Is simple enough for anyone to use&lt;br&gt;
✔ And customizable enough for any dev to extend&lt;/p&gt;

&lt;p&gt;Thus, SlimPDF was born.&lt;/p&gt;

&lt;p&gt;⚡ What SlimPDF Does&lt;/p&gt;

&lt;p&gt;SlimPDF is a minimalistic web app (built with Flask) where you:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Upload a PDF&lt;/li&gt;
&lt;li&gt;Click “Compress”&lt;/li&gt;
&lt;li&gt;Instantly download a lighter version of it&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It quietly uses Ghostscript under the hood, a battle-tested tool that the industry has trusted for decades for PDF processing.&lt;/p&gt;

&lt;p&gt;No ads.&lt;br&gt;
No tracking.&lt;br&gt;
No server logs.&lt;br&gt;
No hidden “your files will be deleted in 24 hours” promises.&lt;br&gt;
Just pure, local PDF slimming.&lt;/p&gt;

&lt;p&gt;🚀 Quick Start to run it locally&lt;/p&gt;

&lt;p&gt;If you want to try the app yourself:&lt;/p&gt;

&lt;p&gt;Clone the repo&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/rajks24/SlimPDF
cd SlimPDF
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install dependencies&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install -r requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install Ghostscript&lt;/p&gt;

&lt;p&gt;macOS (brew):&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Ubuntu/Debian:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install ghostscript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Windows:&lt;br&gt;
Download the Ghostscript installer:&lt;br&gt;
&lt;a href="https://ghostscript.com/releases/index.html" rel="noopener noreferrer"&gt;https://ghostscript.com/releases/index.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Run the app&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Visit:&lt;br&gt;
➡️ &lt;a href="http://localhost:5000" rel="noopener noreferrer"&gt;http://localhost:5000&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now you can compress PDFs right from your machine.&lt;/p&gt;

&lt;p&gt;🎉 Final Thoughts&lt;/p&gt;

&lt;p&gt;SlimPDF started as a weekend project… but quickly became something I personally use regularly.&lt;br&gt;
We all deal with PDFs, and we all care about privacy, so building a tool that combines both felt meaningful.&lt;/p&gt;

&lt;p&gt;If you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Have ever been anxious uploading personal PDFs online&lt;/li&gt;
&lt;li&gt;Want a lightweight, open-source, local PDF compressor&lt;/li&gt;
&lt;li&gt;Or want to learn Flask through a practical example
…then SlimPDF might be worth checking out.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🔗 GitHub Repo: &lt;a href="https://github.com/rajks24/SlimPDF" rel="noopener noreferrer"&gt;https://github.com/rajks24/SlimPDF&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;⭐ If you like it, consider "like" the repo, it helps others find it too!&lt;/p&gt;

&lt;p&gt;Thanks for reading, and may your PDFs stay slim and your stress stay low. 😄&lt;/p&gt;

</description>
      <category>python</category>
      <category>productivity</category>
      <category>webdev</category>
      <category>opensource</category>
    </item>
    <item>
      <title>RAG Chunking Strategies That Actually Work (and Why Most Don’t)</title>
      <dc:creator>Rajesh Singh</dc:creator>
      <pubDate>Tue, 07 Oct 2025 09:11:35 +0000</pubDate>
      <link>https://dev.to/rajinh24/rag-chunking-strategies-that-actually-work-and-why-most-dont-49n2</link>
      <guid>https://dev.to/rajinh24/rag-chunking-strategies-that-actually-work-and-why-most-dont-49n2</guid>
      <description>&lt;p&gt;So, you’ve decided to build a RAG (&lt;a href="https://en.wikipedia.org/wiki/Retrieval-augmented_generation" rel="noopener noreferrer"&gt;Retrieval-Augmented Generation&lt;/a&gt;) system. Congrats! 🎉&lt;br&gt;
You’ve just volunteered for one of AI’s most underrated challenges: &lt;strong&gt;getting your data to play nice with your LLM&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Let me paint a picture.&lt;/p&gt;

&lt;p&gt;You’ve got your fancy LLM humming, the vector DB is ready, and you excitedly upload your first PDF.&lt;br&gt;
Then you ask something innocent like:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“What’s the company policy on remote work?”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;…and your LLM replies with:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“The company policy regarding quantum physics states that Schrödinger’s cat may work remotely on Tuesdays.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Wait, what?!&lt;br&gt;
Welcome to the wild world of RAG data ingestion, where your biggest enemy isn’t the model, but your &lt;strong&gt;chunking strategy&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  The “Just Chunk It” Fallacy (a.k.a. Fixed-Size Chunking)
&lt;/h2&gt;

&lt;p&gt;Maybe it’s your first day building RAG. You think,How hard can this be?&lt;/p&gt;

&lt;p&gt;“I’ll split my text every 500 characters.”&lt;/p&gt;

&lt;p&gt;Here’s what happens next:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;text = "The Python Global Interpreter Lock (GIL) is a mutex that protects..."
chunks = [text[i:i+50] for i in range(0, len(text), 50)]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chunks[0] = "The Python Global Interpreter Lock (GIL) is a mu"
chunks[1] = "tex that protects access to Python objects, pre"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Congratulations — you just dissected the word “mutex.”&lt;br&gt;
Your LLM now thinks you’re talking about Egyptian relics or LaTeX syntax.&lt;/p&gt;
&lt;h3&gt;
  
  
  ✅ The Fix: Smart Chunking (Recursive Character Text Splitting)
&lt;/h3&gt;

&lt;p&gt;You wouldn’t interrupt someone mid-word, right?&lt;/p&gt;

&lt;p&gt;Do the same for your text. Use recursive splitting that respects natural boundaries:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from langchain.text_splitter import RecursiveCharacterTextSplitter

splitter = RecursiveCharacterTextSplitter(
    chunk_size=500,
    chunk_overlap=50,
    separators=["\n\n", "\n", ". ", " ", ""]
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tells your splitter:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“Start with paragraphs. If that fails, try sentences. Still too long? Fine, use spaces. But please, don’t butcher words.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Different documents deserve different chunking styles:&lt;/p&gt;

&lt;p&gt;🧠 &lt;strong&gt;Technical docs&lt;/strong&gt;: 800–1000 chars — context matters. (Semantic chunking)&lt;br&gt;
🧑‍💻 &lt;strong&gt;Code&lt;/strong&gt;: Keep functions intact. (Syntax-aware chunking)&lt;br&gt;
📊 &lt;strong&gt;Tables&lt;/strong&gt;: Don’t split them at all. (Structure-preserving chunking)&lt;/p&gt;
&lt;h2&gt;
  
  
  Metadata Amnesia - The Context Killer
&lt;/h2&gt;

&lt;p&gt;You’ve ingested 500 documents.&lt;br&gt;
A user asks about “&lt;em&gt;Q2 2024 sales strategy&lt;/em&gt;,” and your RAG confidently answers using… Q2 2019 data. 🤦‍♂️&lt;/p&gt;

&lt;p&gt;Why? Because you chunked text with no metadata &amp;amp; no context.&lt;/p&gt;
&lt;h3&gt;
  
  
  ✅ The Fix: Metadata-Enriched Chunking
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chunk_metadata = {
    "source": "Q2_2024_Sales_Strategy.pdf",
    "document_type": "strategic_plan",
    "date": "2024-04-01",
    "department": "Sales",
    "author": "Jane Smith",
    "page": 5,
    "section": "Market Analysis",
    "quarter": "Q2",
    "year": 2024,
    "tags": ["sales", "strategy", "B2B"]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now your vector DB can do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;results = vectordb.search(
    query="sales strategy",
    filter={"year": 2024, "quarter": "Q2"}
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Boom, the context restored.&lt;/p&gt;

&lt;h2&gt;
  
  
  “PDF Is Just Text” - The Great Delusion
&lt;/h2&gt;

&lt;p&gt;PDFs are not just text. They can be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scanned images (OCR required)&lt;/li&gt;
&lt;li&gt;Multi-column layouts&lt;/li&gt;
&lt;li&gt;Tables of doom&lt;/li&gt;
&lt;li&gt;Pages full of header/footer noise&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Naïve parsing gives you this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Product Q1 Sales Q2 Sales Widget $100K $150K"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your LLM now believes “Q1 Sales Q2 Sales Widget” is a product line. 💀&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ The Fix: Format-Specific Parsing
&lt;/h3&gt;

&lt;p&gt;For normal PDFs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import pdfplumber
with pdfplumber.open("document.pdf") as pdf:
    for page in pdf.pages:
        text = page.extract_text()
        tables = page.extract_tables()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For scanned PDFs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import pytesseract
from pdf2image import convert_from_path

images = convert_from_path('scanned.pdf')
text = "".join(pytesseract.image_to_string(img) for img in images)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Want to know if OCR is needed?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def is_scanned_pdf(pdf_path):
    with pdfplumber.open(pdf_path) as pdf:
        text = pdf.pages[0].extract_text()
        return len(text.strip()) &amp;lt; 50
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  “Tables Are Just Text” - No, They’re Not.
&lt;/h2&gt;

&lt;p&gt;Without structure, your tables turn into gibberish.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;| Metric  | Q1    | Q2     | Q3    |
|---------|-------|--------|-------|
| Revenue | $1M   | $1.5M  | $2M   |
| Costs   | $600K | $700K  | $800K |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Parsed (naïve):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Metric Q1 Q2 Q3 Revenue $1M $1.5M $2M Costs $600K $700K $800K"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ✅ The Fix:
&lt;/h3&gt;

&lt;p&gt;Use Structured-to-Unstructured Transformation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 1&lt;/strong&gt; - Markdown Table Serialization&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def table_to_markdown(table):
    headers = table[0]
    md = "| " + " | ".join(headers) + " |\n"
    md += "| " + " | ".join(["---"] * len(headers)) + " |\n"
    for row in table[1:]:
        md += "| " + " | ".join(str(cell) for cell in row) + " |\n"
    return md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Option 2&lt;/strong&gt; - Natural Language Linearization&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def table_to_context(table):
    headers = table[0]
    return "\n".join(
        f"{row[0]}: " + ", ".join(f"{headers[i]} is {row[i]}" for i in range(1, len(row)))
        for row in table[1:]
    )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;💡 Pro tip: Do both! Store markdown for humans, and natural language for the LLM.&lt;/p&gt;

&lt;h2&gt;
  
  
  “One Size Fits All” Myth (Chunk Size Disaster)
&lt;/h2&gt;

&lt;p&gt;If you believe “500 characters is the magic chunk size,” brace for chaos.&lt;br&gt;
Every document type is a snowflake.&lt;/p&gt;
&lt;h3&gt;
  
  
  ✅ The Fix: Domain-Adaptive Chunking
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CHUNK_CONFIGS = {
    "code": {"size": 300, "overlap": 30},
    "legal": {"size": 1000, "overlap": 200},
    "technical_manual": {"size": 800, "overlap": 100},
    "chat_logs": {"size": 200, "overlap": 20},
    "general": {"size": 500, "overlap": 50}
}

def get_chunker(document_type):
    config = CHUNK_CONFIGS.get(document_type, CHUNK_CONFIGS["general"])
    return RecursiveCharacterTextSplitter(
        chunk_size=config["size"],
        chunk_overlap=config["overlap"]
    )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Pick your chunker wisely.&lt;/p&gt;
&lt;h2&gt;
  
  
  Duplicate Content Problem
&lt;/h2&gt;

&lt;p&gt;Ingest from multiple sources, and soon your system starts echoing itself — five identical answers, all slightly different.&lt;/p&gt;
&lt;h3&gt;
  
  
  ✅ The Fix: Semantic Deduplication
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Approach 1&lt;/strong&gt; - Fuzzy Matching&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from difflib import SequenceMatcher

def are_chunks_similar(c1, c2, threshold=0.85):
    return SequenceMatcher(None, c1, c2).ratio() &amp;gt;= threshold
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Approach 2&lt;/strong&gt; - Hash-Based Deduplication&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import hashlib

def hash_chunk(text):
    normalized = ' '.join(text.lower().split())
    return hashlib.sha256(normalized.encode()).hexdigest()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because no one likes that “I’ve heard this before” vibe.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing Thoughts
&lt;/h2&gt;

&lt;p&gt;RAG ingestion is hard. Documents are messy. And there’s always that one PDF that breaks everything.&lt;/p&gt;

&lt;p&gt;But here’s the truth:&lt;br&gt;
Everyone’s RAG system is held together with duct tape and prayer.&lt;br&gt;
Knowing where to apply the duct tape is the trick.&lt;/p&gt;

&lt;p&gt;Start simple, then&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get basic chunking working&lt;/li&gt;
&lt;li&gt;Add metadata&lt;/li&gt;
&lt;li&gt;Test with real documents&lt;/li&gt;
&lt;li&gt;Iterate based on failure&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The best RAG system isn’t the one with fancy tech - it’s the one that actually answers user questions correctly.&lt;/p&gt;

&lt;p&gt;So go forth, and chunk responsibly.&lt;/p&gt;

&lt;p&gt;Got your own RAG horror story? Drop it in the comments😅&lt;br&gt;
If you found this helpful, smash that ❤️ and follow me for more dev adventures!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>rag</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>From Sheets to Quizzes: Automating Google Forms Like a Pro</title>
      <dc:creator>Rajesh Singh</dc:creator>
      <pubDate>Mon, 29 Sep 2025 11:01:01 +0000</pubDate>
      <link>https://dev.to/rajinh24/from-sheets-to-quizzes-automating-google-forms-like-a-pro-5gbj</link>
      <guid>https://dev.to/rajinh24/from-sheets-to-quizzes-automating-google-forms-like-a-pro-5gbj</guid>
      <description>&lt;h2&gt;
  
  
  The Problem: Quizzes are Fun, Making Them is Not
&lt;/h2&gt;

&lt;p&gt;Let’s be real, creating quizzes in Google Forms is fine the first time. But after we’ve clicked that purple “+” button a hundred times, added multiple choice answers manually, and squinted at points for each question, the fun evaporates very soon.&lt;/p&gt;

&lt;p&gt;Teachers, trainers, even techies - we all love quizzes. But nobody loves repetitive data entry.&lt;/p&gt;

&lt;p&gt;So, why not automate the Google Sheets to do the boring stuff?&lt;/p&gt;

&lt;h2&gt;
  
  
  The Idea: Sheet In, Quiz Out
&lt;/h2&gt;

&lt;p&gt;The concept is simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Write the quiz questions in a Google Sheet.&lt;/li&gt;
&lt;li&gt;Click a shiny new menu option called &lt;strong&gt;Form Builder&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Watch as a fully published Google Forms Quiz appears - sections, points, correct answers, everything.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So simple, that’s right! ✨&lt;/p&gt;

&lt;h2&gt;
  
  
  The Stack
&lt;/h2&gt;

&lt;p&gt;This project builds on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Google Sheets (where the questions live)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developers.google.com/apps-script" rel="noopener noreferrer"&gt;Google Apps Script&lt;/a&gt; (the automation brains)&lt;/li&gt;
&lt;li&gt;Google Forms (the end product: quizzes!)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And of course, it’s all open-source on GitHub: 👉 &lt;a href="https://github.com/rajks24/google-forms-quiz-builder" rel="noopener noreferrer"&gt;Google Forms Quiz Builder Repo&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Sheet Format (Where the Magic Begins)
&lt;/h2&gt;

&lt;p&gt;The sheet starts with a few metadata rows:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Key&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;FormTitle&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Math Assignment 1&lt;/td&gt;
&lt;td&gt;Quiz title&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;FormDescription&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Maths quiz for beginner&lt;/td&gt;
&lt;td&gt;Optional&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;LimitOneResponse&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;FALSE&lt;/td&gt;
&lt;td&gt;TRUE/FALSE&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Then we add a blank row, followed by the question table:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Section&lt;/th&gt;
&lt;th&gt;Question&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Points&lt;/th&gt;
&lt;th&gt;AnswerA&lt;/th&gt;
&lt;th&gt;AnswerB&lt;/th&gt;
&lt;th&gt;AnswerC&lt;/th&gt;
&lt;th&gt;AnswerD&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Easy&lt;/td&gt;
&lt;td&gt;Which is larger: 0.3 or 0.25?&lt;/td&gt;
&lt;td&gt;MCQ&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;0.3&lt;/td&gt;
&lt;td&gt;0.25&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Easy&lt;/td&gt;
&lt;td&gt;Explain steps to get 25% as a decimal&lt;/td&gt;
&lt;td&gt;SA&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Mark all that equal 2/3.&lt;/td&gt;
&lt;td&gt;MSQ&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;*2/3&lt;/td&gt;
&lt;td&gt;*0.6667&lt;/td&gt;
&lt;td&gt;0.65&lt;/td&gt;
&lt;td&gt;*0.666...&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;👉 See the full format guide here: &lt;a href="https://github.com/rajks24/google-forms-quiz-builder/blob/main/sample/Questions.sheet-format.md" rel="noopener noreferrer"&gt;Questions.sheet-format.md&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉 The sample quiz sheet data can be found at &lt;a href="https://github.com/rajks24/google-forms-quiz-builder/blob/main/sample/math_assignment1_questions.csv" rel="noopener noreferrer"&gt;sample_questions.csv&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Oh, and notice the &lt;code&gt;*&lt;/code&gt; before some answers? That’s how you mark the correct ones for MSQs. Sneaky but simple.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  The Script
&lt;/h2&gt;

&lt;p&gt;At the heart of this project is a neat Apps Script file (&lt;strong&gt;Code.gs&lt;/strong&gt;).&lt;/p&gt;

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

&lt;h3&gt;
  
  
  What it does:
&lt;/h3&gt;

&lt;p&gt;Reads the Sheet data.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creates a Google Form (from the forms template with settings or freshly generated).&lt;/li&gt;
&lt;li&gt;Adds sections with total points.&lt;/li&gt;
&lt;li&gt;Supports SA, PARA, MCQ, MSQ question types.&lt;/li&gt;
&lt;li&gt;Publishes the quiz automatically so students don’t get the dreaded &lt;code&gt;We’re sorry, this document is not published&lt;/code&gt; error.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Full code here: &lt;a href="https://github.com/rajks24/google-forms-quiz-builder/blob/main/src/Code.js" rel="noopener noreferrer"&gt;src/Code.js&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Output
&lt;/h2&gt;

&lt;p&gt;Run the script and boom 💥 a new Google Form quiz is ready to go:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sections clearly separated with total points.&lt;/li&gt;
&lt;li&gt;Auto-collected emails.&lt;/li&gt;
&lt;li&gt;A required “Student Name” field.&lt;/li&gt;
&lt;li&gt;MCQs and MSQs shuffled for fairness.&lt;/li&gt;
&lt;li&gt;Linked responses back into the same spreadsheet.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;h2&gt;
  
  
  The Demo Video
&lt;/h2&gt;

&lt;p&gt;Why read when you can watch?&lt;br&gt;
I recorded a full walkthrough of the project&lt;br&gt;


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


&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup in 3 Steps
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Copy the quiz data into then google Sheet.&lt;/li&gt;
&lt;li&gt;Open Extensions → Apps Script, paste the code from the repo.&lt;/li&gt;
&lt;li&gt;Reload the sheet, click &lt;code&gt;Form Builder&lt;/code&gt; → &lt;code&gt;Create Form (Confirm)&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the detailed step-by-step process follow: &lt;a href="https://github.com/rajks24/google-forms-quiz-builder/blob/main/docs/SETUP.md" rel="noopener noreferrer"&gt;SETUP.md&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Matters
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;For &lt;strong&gt;teachers&lt;/strong&gt;: less manual and smart automation.&lt;/li&gt;
&lt;li&gt;For &lt;strong&gt;devs&lt;/strong&gt;: a nice Apps Script case study.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🎉 Wrap Up
&lt;/h2&gt;

&lt;p&gt;This was one of those projects where a tiny bit of scripting makes a huge difference.&lt;br&gt;
From “ugh, more manual quiz creation” to “click and done”.&lt;/p&gt;

&lt;p&gt;If you liked this, do me a favor:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⭐ Star the repo&lt;/li&gt;
&lt;li&gt;📺 Watch the demo&lt;/li&gt;
&lt;li&gt;🔗 Share it with someone who still builds Google Forms by hand (and save them some pain!)&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>googleforms</category>
      <category>automation</category>
      <category>productivity</category>
      <category>googleappsscript</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Rajesh Singh</dc:creator>
      <pubDate>Thu, 24 Apr 2025 00:05:53 +0000</pubDate>
      <link>https://dev.to/rajinh24/trying-to-get-vagrant-working-smoothly-on-a-mac-with-the-new-m4-chip-this-post-breaks-down-whats-2ojf</link>
      <guid>https://dev.to/rajinh24/trying-to-get-vagrant-working-smoothly-on-a-mac-with-the-new-m4-chip-this-post-breaks-down-whats-2ojf</guid>
      <description></description>
      <category>programming</category>
    </item>
    <item>
      <title>Vagrant on Apple Silicon M4: KVM vs QEMU vs Libvirt – What Works Best?</title>
      <dc:creator>Rajesh Singh</dc:creator>
      <pubDate>Wed, 23 Apr 2025 09:08:46 +0000</pubDate>
      <link>https://dev.to/rajinh24/vagrant-on-apple-silicon-m4-kvm-vs-qemu-vs-libvirt-what-works-best-7n8</link>
      <guid>https://dev.to/rajinh24/vagrant-on-apple-silicon-m4-kvm-vs-qemu-vs-libvirt-what-works-best-7n8</guid>
      <description>&lt;p&gt;If we’re diving into Vagrant and working on a shiny new M4 Mac (or any other Apple Silicon M series), we’ve probably stumbled across terms like &lt;strong&gt;KVM&lt;/strong&gt;, &lt;strong&gt;QEMU&lt;/strong&gt;, and &lt;strong&gt;Libvirt&lt;/strong&gt; as providers. But which one fits our workflow best - especially when dealing with Apple Silicon?&lt;/p&gt;

&lt;p&gt;Here’s a simple, real-world comparison.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Intro: The options
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;KVM&lt;/strong&gt; – A Linux-native virtualization technology that’s lightning fast, but strictly tied to Linux kernels.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;QEMU&lt;/strong&gt; – A powerful emulator and virtualizer, supports cross-architecture (e.g., x86 VMs on ARM). It’s highly versatile and works well for testing and development across different architectures.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;VMware Fusion&lt;/strong&gt; – Another commercial option, providing robust virtualization capabilities on macOS, though its support for Apple Silicon is still evolving.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Libvirt&lt;/strong&gt; – A management layer that works on top of KVM or QEMU to provide better VM orchestration (snapshots, port forwarding, etc.).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Apple Silicon Challenge
&lt;/h2&gt;

&lt;p&gt;Here’s where things get tricky on the Mac — especially with Apple Silicon:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;❌ KVM is a no-go&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;KVM requires /dev/kvm, a kernel module only available on Linux, and not supported on macOS.&lt;/li&gt;
&lt;li&gt;Apple Silicon (M1–M4) doesn’t allow KVM passthrough even via emulation layers. &lt;a href="https://www.linux-kvm.org/page/FAQ#Is_KVM_available_on_macOS.3F" rel="noopener noreferrer"&gt;See here&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;⚠️ Libvirt adds complexity on macOS&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Libvirt doesn’t run natively on macOS. To use it, we would need to spin up a Linux VM (via Colima, Lima, or UTM) just to run QEMU and Libvirt.&lt;/li&gt;
&lt;li&gt;While doable, it’s like building a tower to launch a paper airplane - overkill for most development use cases.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;QEMU: Your Friendly Option on Apple M4&lt;/strong&gt;&lt;br&gt;
Thankfully, QEMU works directly on macOS, supports ARM64 (native for M1–M4), and integrates with Vagrant using &lt;a href="https://github.com/ppggff/vagrant-qemu" rel="noopener noreferrer"&gt;vagrant-qemu&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It’s:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Native to Apple Silicon&lt;/li&gt;
&lt;li&gt;✅ Great for cross-architecture testing&lt;/li&gt;
&lt;li&gt;✅ Easy to set up with brew install qemu vagrant + plugin&lt;/li&gt;
&lt;li&gt;✅ Ideal for lightweight VMs and multi-purpose dev&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can pair QEMU with ARM-based boxes like generic/ubuntu2204-arm64 or &lt;a href="https://portal.cloud.hashicorp.com/vagrant/discover?architectures=arm64&amp;amp;providers=qemu" rel="noopener noreferrer"&gt;others&lt;/a&gt; from Vagrant Cloud.&lt;/p&gt;

&lt;p&gt;💡 Want to get started fast? Try:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;qemu
vagrant plugin &lt;span class="nb"&gt;install &lt;/span&gt;vagrant-qemu

vagrant init perk/ubuntu-2204-arm64
vagrant up &lt;span class="nt"&gt;--provider&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;qemu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Comparing the Providers
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Provider&lt;/th&gt;
&lt;th&gt;macOS Native&lt;/th&gt;
&lt;th&gt;M4 Compatible&lt;/th&gt;
&lt;th&gt;Performance&lt;/th&gt;
&lt;th&gt;Complexity&lt;/th&gt;
&lt;th&gt;Best Use Case&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;KVM&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Simple (on Linux only)&lt;/td&gt;
&lt;td&gt;Linux-based dev servers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;QEMU&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Easy on Mac&lt;/td&gt;
&lt;td&gt;Local multi-arch dev&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Libvirt&lt;/td&gt;
&lt;td&gt;No (indirect)&lt;/td&gt;
&lt;td&gt;Only with Linux VM&lt;/td&gt;
&lt;td&gt;(via KVM/QEMU)&lt;/td&gt;
&lt;td&gt;Complex on macOS&lt;/td&gt;
&lt;td&gt;Advanced VM orchestration (on Linux)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  So Which One to choose on Apple M4?
&lt;/h2&gt;

&lt;p&gt;For macOS Silicon chip users:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ &lt;strong&gt;QEMU is your best bet&lt;/strong&gt;: It runs natively on Apple Silicon, supports ARM64 architecture, and integrates seamlessly with Vagrant using the &lt;code&gt;vagrant-qemu&lt;/code&gt; plugin. This makes it an excellent choice for lightweight virtual machines and cross-architecture development.&lt;/li&gt;
&lt;li&gt;⚠️ &lt;strong&gt;Consider Libvirt only if necessary&lt;/strong&gt;: While Libvirt offers advanced VM management features, it requires running a Linux VM on macOS, adding unnecessary complexity for most use cases.&lt;/li&gt;
&lt;li&gt;❌ &lt;strong&gt;Avoid KVM&lt;/strong&gt;: Since KVM relies on Linux-specific kernel modules, it’s not an option for macOS.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In summary, QEMU provides the most straightforward and efficient solution for virtualization on Apple M4.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-World References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.linux-kvm.org/page/FAQ#Is_KVM_available_on_macOS.3F" rel="noopener noreferrer"&gt;KVM FAQ – Not supported on macOS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/ppggff/vagrant-qemu" rel="noopener noreferrer"&gt;vagrant-qemu GitHub project&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://libvirt.org/" rel="noopener noreferrer"&gt;Libvirt: Why it's great on Linux, not macOS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/abiosoft/colima" rel="noopener noreferrer"&gt;Running Linux VMs on Apple Silicon (Colima, Lima, UTM)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>vagrant</category>
      <category>qemu</category>
      <category>linux</category>
      <category>virtualization</category>
    </item>
    <item>
      <title>🚀 Excited to share my latest blog exploring GitHub Copilot - the game-changing AI pair programmer that's transforming how developers write code! 🖥️💡</title>
      <dc:creator>Rajesh Singh</dc:creator>
      <pubDate>Fri, 06 Dec 2024 20:42:05 +0000</pubDate>
      <link>https://dev.to/rajinh24/excited-to-share-my-latest-blog-exploring-github-copilot-the-game-changing-ai-pair-programmer-3g7b</link>
      <guid>https://dev.to/rajinh24/excited-to-share-my-latest-blog-exploring-github-copilot-the-game-changing-ai-pair-programmer-3g7b</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/rajinh24" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1859865%2F8cab12d0-5343-4848-a927-b2867ce7bbb7.jpeg" alt="rajinh24"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/rajinh24/github-copilot-supercharge-your-coding-with-ai-pair-programmer-17nf" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;GitHub Copilot: Supercharge Your Coding with AI Pair Programmer&lt;/h2&gt;
      &lt;h3&gt;Rajesh Singh ・ Nov 30&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#githubcopilot&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#ai&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#coding&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
    </item>
    <item>
      <title>GitHub Copilot: Supercharge Your Coding with AI Pair Programmer</title>
      <dc:creator>Rajesh Singh</dc:creator>
      <pubDate>Sat, 30 Nov 2024 04:24:40 +0000</pubDate>
      <link>https://dev.to/rajinh24/github-copilot-supercharge-your-coding-with-ai-pair-programmer-17nf</link>
      <guid>https://dev.to/rajinh24/github-copilot-supercharge-your-coding-with-ai-pair-programmer-17nf</guid>
      <description>&lt;p&gt;Recently, a shiny new add-on hit the marketplace: GitHub Copilot. Naturally, I had to dive in and see what all the buzz was about. As a tech enthusiast who dabbles in React for frontend and Python for backend and scripting, I couldn’t resist the allure of this AI-powered coding assistant.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExNHQyb3BkOGdpMWFxcnkxMGF4Z3B0b3lzNG9nZHAydmhpajRub2liNSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/rDbelKPujYEBq/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExNHQyb3BkOGdpMWFxcnkxMGF4Z3B0b3lzNG9nZHAydmhpajRub2liNSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/rDbelKPujYEBq/giphy.gif" width="260" height="188"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  But why use GitHub Copilot ?
&lt;/h2&gt;

&lt;p&gt;GitHub Copilot is like having a supercharged assistant right inside your code editor. It suggests entire lines or blocks of code as we type code.., making coding faster and more efficient. It supports a wide range of languages and frameworks ( 🤔 almost every one ), understands the coding context, and even helps with documenting and writing tests. Imagine having a tool that not only speeds up coding but also helps learn new coding patterns and best practices along the way. Now, that’s amazing !!&lt;/p&gt;

&lt;p&gt;For developers, time is precious. GitHub Copilot helps save time by automating repetitive tasks, reducing need to search for code snippets online, and minimizing coding errors. &lt;/p&gt;

&lt;p&gt;Whether you’re a seasoned developer or just starting out, Copilot can enhance your productivity and make coding more enjoyable. It’s like having a knowledgeable coding buddy who’s always ready to help, without the need for coffee breaks!&lt;/p&gt;

&lt;h2&gt;
  
  
  My GitHub Copilot adventure
&lt;/h2&gt;

&lt;p&gt;To start my journey, I signed up for a &lt;strong&gt;30-day trial of GitHub Copilot&lt;/strong&gt;. The setup process was a breeze—seriously 🙂, it was smoother than a freshly buttered scone. I found the extension for VS Code, clicked "Install," and voilà! Most of the configurations were handled automatically.&lt;/p&gt;

&lt;p&gt;After logging into my GitHub account, the &lt;strong&gt;happy little robot&lt;/strong&gt; icon popped up in the status bar, eager to help. It was like having a coding buddy at my fingertips, ready for action.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  First Impressions
&lt;/h2&gt;

&lt;p&gt;To spice things up, I decided to build a &lt;code&gt;trivia API&lt;/code&gt; project. This API would challenge users with questions, offer multiple-choice answers, and deliver the results. &lt;/p&gt;

&lt;p&gt;Eager to test Copilot's capabilities, I prompted it to create a template for a Python-based API app using Flask.&lt;/p&gt;

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

&lt;p&gt;Within seconds, it generated boilerplate files with helpful content. With just one click, my project setup was complete. It felt like witnessing coding magic 💫 unfold before my eyes.&lt;/p&gt;

&lt;p&gt;The template included all the necessary project files, complete with relevant code and configurations to jumpstart the project.&lt;/p&gt;

&lt;p&gt;I appreciated how it allowed me to review each file's template code before accepting and creating the workspace—a thoughtful touch that gave me control over the setup process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Coding time
&lt;/h2&gt;

&lt;p&gt;With the boilerplate files in place, I jumped on filling the gaps and putting the logic to build the API services. During all the time, the coding assistant by my side helping me follow best practices, and handing errors and code refactoring.&lt;/p&gt;

&lt;p&gt;Copilot helped me &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;set up the endpoints,&lt;/li&gt;
&lt;li&gt;handle user inputs, and&lt;/li&gt;
&lt;li&gt;manage the scoring logic.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It was like having a trivia game helper engine at my fingertips&lt;/p&gt;

&lt;h2&gt;
  
  
  The Debugging Companion
&lt;/h2&gt;

&lt;p&gt;For most of the actions, we can just right click on the editor to get the copilot options to start an inline chat for cursor position or with code selection. For users to be very specific, can use the built-in copilot commands &lt;code&gt;explain&lt;/code&gt; , &lt;code&gt;fix&lt;/code&gt; , &lt;code&gt;generate docs&lt;/code&gt;  or &lt;code&gt;generate tests&lt;/code&gt;  for the file or selected code.&lt;/p&gt;

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

&lt;p&gt;Fixing errors and debugging with GitHub Copilot is a breeze. Simply select the code or error, then choose the &lt;code&gt;explain&lt;/code&gt; command from the IDE's right-click context menu in the editor or terminal. Copilot then scans your workspace's source code to provide the most likely explanation for the error and offers code snippets to clarify the issue or fix the problem.&lt;/p&gt;

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

&lt;p&gt;I made a few minor adjustments using the inline chat feature. It was fast, smooth, and incredibly convenient—a real game-changer for quick edits.&lt;/p&gt;

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

&lt;p&gt;To enhance the app's user-friendliness, I decided to add an HTML template with a home page to display the questions and allow users to answer them.&lt;/p&gt;

&lt;p&gt;A great feature of GitHub Copilot is that it allows users to review code changes before applying them. It also scans the entire code file to identify the snippet that needs modification, reassuring developers that it won't disrupt the existing code logic.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Finishing the project
&lt;/h2&gt;

&lt;p&gt;Testing is usually my least favorite part of development, so I handed the task over to my AI pair programmer. Copilot suggested performing a test setup for the app.&lt;/p&gt;

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

&lt;p&gt;I chose to go with the &lt;code&gt;pytest&lt;/code&gt; framework for my app and then followed Copilot's prompts and suggestions. In no time, I was able to configure and write tests for all my API routes, adhering to testing best practices.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Containerizing the Application
&lt;/h2&gt;

&lt;p&gt;To finish the app build, I decided to containerize my application. I asked GitHub Copilot to create a Dockerfile for my app, preparing it for a Docker build and deployment in cloud-native environments.&lt;/p&gt;

&lt;p&gt;Copilot generated a Dockerfile following best practices. I then tested the containerized app locally to ensure everything was working correctly.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;With both the backend and frontend complete, my full-fledged app was ready for sharing with my team. A big shout-out to Copilot, my AI pair programmer, for making the process swift and enjoyable.&lt;/p&gt;

&lt;p&gt;If you're a developer or DevOps engineer looking to supercharge your coding experience, I wholeheartedly recommend giving GitHub Copilot a spin. It's like having a tireless, supercharged assistant at your fingertips.&lt;/p&gt;

&lt;p&gt;Now, go forth and code with gusto!&lt;/p&gt;

</description>
      <category>githubcopilot</category>
      <category>ai</category>
      <category>coding</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Merging Local and Remote Git Repos: Fixing Unrelated Histories</title>
      <dc:creator>Rajesh Singh</dc:creator>
      <pubDate>Mon, 11 Nov 2024 09:59:25 +0000</pubDate>
      <link>https://dev.to/rajinh24/merging-local-and-remote-git-repos-fixing-unrelated-histories-aai</link>
      <guid>https://dev.to/rajinh24/merging-local-and-remote-git-repos-fixing-unrelated-histories-aai</guid>
      <description>&lt;p&gt;Let's explore the context of merging files from a remote repository with a local source code branch.&lt;/p&gt;

&lt;p&gt;We often encounter a scenario where we have a local Git repository with source code and create a remote Git repository with a &lt;a href="http://README.md" rel="noopener noreferrer"&gt;README.md&lt;/a&gt; and/or .gitignore file. We then want our local repo to seamlessly merge these files in preparation for &lt;code&gt;git push -u origin main&lt;/code&gt;. However, we sometimes face those pesky merge notifications locally during the merging process.&lt;/p&gt;

&lt;p&gt;Let me give an example.&lt;/p&gt;

&lt;p&gt;Usually we perform the git remote add origin &lt;a href="https://github.com/rajks24/projectname.git" rel="noopener noreferrer"&gt;https://github.com/rajks24/projectname.git&lt;/a&gt; , and perform git pull to merge the remote files to local git branch, before final git push , but we get errors like below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ git pull                                     
hint: You have divergent branches and need to specify how to reconcile them.
hint: You can &lt;span class="k"&gt;do &lt;/span&gt;so by running one of the following commands sometime before
hint: your next pull:
hint: 
hint:   git config pull.rebase &lt;span class="nb"&gt;false&lt;/span&gt;  &lt;span class="c"&gt;# merge&lt;/span&gt;
hint:   git config pull.rebase &lt;span class="nb"&gt;true&lt;/span&gt;   &lt;span class="c"&gt;# rebase&lt;/span&gt;
hint:   git config pull.ff only       &lt;span class="c"&gt;# fast-forward only&lt;/span&gt;
hint: 
hint: You can replace &lt;span class="s2"&gt;"git config"&lt;/span&gt; with &lt;span class="s2"&gt;"git config --global"&lt;/span&gt; to &lt;span class="nb"&gt;set &lt;/span&gt;a default
hint: preference &lt;span class="k"&gt;for &lt;/span&gt;all repositories. You can also pass &lt;span class="nt"&gt;--rebase&lt;/span&gt;, &lt;span class="nt"&gt;--no-rebase&lt;/span&gt;,
hint: or &lt;span class="nt"&gt;--ff-only&lt;/span&gt; on the &lt;span class="nb"&gt;command &lt;/span&gt;line to override the configured default per
hint: invocation.
fatal: Need to specify how to reconcile divergent branches.

❯ git pull hint: You have divergent branches and need to specify how to reconcile them. 
hint: You can &lt;span class="k"&gt;do &lt;/span&gt;so by running one of the following commands sometime before hint: your next pull: hint: hint: git confi g pull.rebase &lt;span class="nb"&gt;false&lt;/span&gt; &lt;span class="c"&gt;# merge hint: git confi g pull.rebasetrue # rebase hint: git confi g pull.ff only # fast-forward only hint: hint: You can replace “git confi g” with “gitconfi g --global” to set a default hint: preference for all repositories. You can also pass --rebase, --no-rebase,hint: or --ff-only on the command line to override the confi gured default per hint: invocation. fatal: Need tospecify how to reconcile divergent branches.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To start with the resolution, we need to configure local git to merge by default with &lt;code&gt;git config pull.rebase false&lt;/code&gt; .&lt;/p&gt;

&lt;p&gt;Even with above settings, for &lt;code&gt;git pull&lt;/code&gt; or  &lt;code&gt;git merge&lt;/code&gt;, we might also get an error as &lt;code&gt;From https://github.com/rajks24/projectname branch main -&amp;gt; FETCH_HEAD fatal: refusing to merge unrelated histories&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So, to get through above error, we can perform following actions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pull and Merge with Unrelated Histories
&lt;/h2&gt;

&lt;p&gt;Since the remote repo has some initial files, we will need to pull and merge with the&lt;br&gt;
&lt;code&gt;--allow-unrelated-histories&lt;/code&gt; flag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ git pull origin main &lt;span class="nt"&gt;--allow-unrelated-histories&lt;/span&gt; 
From https://github.com/rajks24/projectname
 &lt;span class="k"&gt;*&lt;/span&gt; branch            main       -&amp;gt; FETCH_HEAD
Merge made by the &lt;span class="s1"&gt;'ort'&lt;/span&gt; strategy.
 LICENSE | 21 +++++++++++++++++++++
 1 file changed, 21 insertions&lt;span class="o"&gt;(&lt;/span&gt;+&lt;span class="o"&gt;)&lt;/span&gt;
 create mode 100644 LICENSE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Resolve Merge Conflicts (If Any)
&lt;/h2&gt;

&lt;p&gt;If we encounter any merge conflicts, Git will prompt us to resolve them. Open the conflicting files, fix the conflicts, and then stage the changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add &amp;lt;conflicting_file&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Commit the Merge
&lt;/h2&gt;

&lt;p&gt;Once you’ve resolved the conflicts, commit the merge:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git commit &lt;span class="nt"&gt;-m&lt;/span&gt;&lt;span class="s2"&gt;"Merge remote-tracking branch 'origin/main' into main"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Push the Main Branch
&lt;/h2&gt;

&lt;p&gt;Now, push the &lt;code&gt;main&lt;/code&gt; branch to the remote repository with &lt;code&gt;git push -u origin main&lt;/code&gt; .&lt;/p&gt;

&lt;h2&gt;
  
  
  Push All Other Branches (optional)
&lt;/h2&gt;

&lt;p&gt;Push all your other branches to the remote repository with &lt;code&gt;git push --all origin&lt;/code&gt; .&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Merging repositories might seem daunting at first, but it's an essential skill for any developer working in a collaborative environment. By understanding these concepts and techniques, you're not just solving immediate problems – you're building a foundation for smoother, more efficient workflow in all your future projects.&lt;/p&gt;

&lt;p&gt;Keep experimenting, keep learning, and most importantly, keep Git-ing it together!&lt;/p&gt;

</description>
      <category>git</category>
      <category>devops</category>
    </item>
    <item>
      <title>Fixing vite error for reactjs - global is not defined and process is not defined</title>
      <dc:creator>Rajesh Singh</dc:creator>
      <pubDate>Wed, 18 Sep 2024 12:52:27 +0000</pubDate>
      <link>https://dev.to/rajinh24/fixing-vite-error-for-reactjs-global-is-not-defined-and-process-is-not-defined-4ffo</link>
      <guid>https://dev.to/rajinh24/fixing-vite-error-for-reactjs-global-is-not-defined-and-process-is-not-defined-4ffo</guid>
      <description>&lt;p&gt;In a scenario where you are running a vite app with reactjs template for a project and trying to fetch the environment variable from &lt;code&gt;.env&lt;/code&gt; file. As the popular way to fetch the environment variables from .env is to use &lt;code&gt;process.env.SOMETHING&lt;/code&gt; for the variable as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SOMETHING=SECRETSAUCE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point the &lt;code&gt;vite.config.ts&lt;/code&gt; would look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
})

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

&lt;/div&gt;



&lt;p&gt;But fetching variable does not work right away in vite, and there are lots of way to solve the issue. I tried most of them and I felt to stick to the simple and straight forward way.&lt;/p&gt;

&lt;p&gt;Probably with above definition and default fetching logic with &lt;code&gt;process.env.*&lt;/code&gt;, you would have got error &lt;code&gt;Uncaught ReferenceError: global is not defined&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I find lots of references in stackoverflow and I get confused. &lt;/p&gt;

&lt;p&gt;The fix for error is to define global in the config as below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  define: {
    global: {},
  },
})

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

&lt;/div&gt;



&lt;p&gt;Now, this would probably lead to another more common error &lt;code&gt;Uncaught ReferenceError: process is not defined&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Again, there are many solutions on web and some are outdated. I find the most relevant and easy to implement is to import &lt;code&gt;loadEnv&lt;/code&gt; from vite library and build the custom logic as below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { defineConfig, loadEnv } from 'vite'
import react from '@vitejs/plugin-react'

// https://vitejs.dev/config/
export default defineConfig(({ mode }) =&amp;gt; {
  const env = loadEnv(mode, process.cwd(), '');
  return {
    define: {
      global: {},
      'process.env': env
    },
    plugins: [react()],
  }
})

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

&lt;/div&gt;



&lt;p&gt;And the magic happens right away!! &lt;/p&gt;

&lt;p&gt;Also to mention, we need not use the &lt;code&gt;dotenv&lt;/code&gt; dependency as environment variable fetching in code with &lt;code&gt;process.env.*&lt;/code&gt; works well without it.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>react</category>
      <category>vite</category>
      <category>javascript</category>
      <category>node</category>
    </item>
    <item>
      <title>How to Fix Shadcn UI Adding Wrong Folder for Components</title>
      <dc:creator>Rajesh Singh</dc:creator>
      <pubDate>Sun, 04 Aug 2024 08:55:14 +0000</pubDate>
      <link>https://dev.to/rajinh24/how-to-fix-shadcn-ui-adding-wrong-folder-for-components-4p3o</link>
      <guid>https://dev.to/rajinh24/how-to-fix-shadcn-ui-adding-wrong-folder-for-components-4p3o</guid>
      <description>&lt;p&gt;I wish to share the observation and simple fix for Shadcn UI components folder issue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Issue
&lt;/h2&gt;

&lt;p&gt;When I run &lt;code&gt;shadcn-ui@latest&lt;/code&gt; to add any other the UI components, then it adds the file to a new directory: &lt;code&gt;@/components/ui/&lt;/code&gt; under &lt;code&gt;/src&lt;/code&gt; rather than the existing &lt;code&gt;components/ui&lt;/code&gt; directory which I have created and updated in the &lt;code&gt;tsconfig.json&lt;/code&gt; along with next app setup.&lt;/p&gt;

&lt;p&gt;Below is the config which I have in the &lt;code&gt;tsconfig.json&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;baseUrl&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;src&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;paths&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/app/*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;app/*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/components/*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;components/*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/lib/*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lib/*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/styles/*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;styles/*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="c1"&gt;// "@/*": ["./src/*"]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and the auto generated &lt;code&gt;components.json&lt;/code&gt; by &lt;code&gt;shadcn-ui@latest&lt;/code&gt; is as below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$schema&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://ui.shadcn.com/schema.json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;style&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;default&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rsc&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tsx&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tailwind&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;config&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tailwind.config.ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;src/styles/globals.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;baseColor&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;slate&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cssVariables&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;prefix&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aliases&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;components&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/components&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;utils&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/lib/utils&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we invoke the CLI command to add a Button with &lt;code&gt;npx shadcn-ui@latest add button&lt;/code&gt; then it adds a new folder below &lt;code&gt;/src&lt;/code&gt; as &lt;code&gt;@&lt;/code&gt; and then &lt;code&gt;components/ui&lt;/code&gt; and then putting the &lt;code&gt;button.tsx&lt;/code&gt;. &lt;br&gt;
Thus, it's not able to view the existing &lt;code&gt;/src/components&lt;/code&gt; folder.&lt;/p&gt;

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

&lt;p&gt;I noticed that the default &lt;code&gt;components.json&lt;/code&gt; looks at the alias in &lt;code&gt;tsconfig.json&lt;/code&gt; so the key should match in the &lt;code&gt;components.json&lt;/code&gt;.&lt;br&gt;
Hence, we need to change in &lt;code&gt;components.json&lt;/code&gt; as below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "$schema": "https://ui.shadcn.com/schema.json",
  "style": "default",
  "rsc": true,
  "tsx": true,
  "tailwind": {
    "config": "tailwind.config.ts",
    "css": "src/styles/globals.css",
    "baseColor": "slate",
    "cssVariables": true,
    "prefix": ""
  },
  "aliases": {
    "components": "@/components/*",
    "utils": "@/lib/utils"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can notice that in aliases, we have added &lt;code&gt;/*&lt;/code&gt; for components to match the key in &lt;code&gt;tsconfig.json&lt;/code&gt;. &lt;br&gt;
Thats it !!, it was simple!&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>shadcn</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
