<?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: Ayoub Abidi</title>
    <description>The latest articles on DEV Community by Ayoub Abidi (@ayoub3bidi).</description>
    <link>https://dev.to/ayoub3bidi</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%2F517791%2Feb4ee3f5-2abb-45e2-b271-c23e1ac1cade.jpg</url>
      <title>DEV Community: Ayoub Abidi</title>
      <link>https://dev.to/ayoub3bidi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ayoub3bidi"/>
    <language>en</language>
    <item>
      <title>Bayan Flow 0.3.0: From 6 to +20 Algorithms</title>
      <dc:creator>Ayoub Abidi</dc:creator>
      <pubDate>Sun, 29 Mar 2026 17:07:19 +0000</pubDate>
      <link>https://dev.to/ayoub3bidi/bayan-flow-030-from-6-to-20-algorithms-df0</link>
      <guid>https://dev.to/ayoub3bidi/bayan-flow-030-from-6-to-20-algorithms-df0</guid>
      <description>&lt;p&gt;I shipped 0.3.0 of &lt;a href="https://bayanflow.netlify.app" rel="noopener noreferrer"&gt;Bayan Flow&lt;/a&gt; last week. This one was mostly about filling things out.&lt;/p&gt;

&lt;p&gt;Quick background, if you haven't seen it before: &lt;a href="https://bayanflow.netlify.app" rel="noopener noreferrer"&gt;Bayan Flow&lt;/a&gt; is an interactive algorithm visualizer. Sorting algorithms rearranging arrays, pathfinding algorithms crawling across grids, step by step, in real time. English, French, and Arabic, with full RTL support. Built with React 19, Vite, Tailwind, and Framer Motion.&lt;/p&gt;

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

&lt;p&gt;0.2.0 was the infrastructure release: i18n, landing page, fullscreen, sound, tests, CI/CD. 0.3.0 is the "okay, now add the actual algorithms" release.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sorting: 3 → 14
&lt;/h2&gt;

&lt;p&gt;The original three were Bubble, Quick, and Merge. Fine for a start, but those are also the three that show up in every tutorial. I wanted the fuller picture.&lt;/p&gt;

&lt;p&gt;So I added eleven more. The classics that somehow didn't make the first cut: &lt;strong&gt;Selection Sort, Insertion Sort, Heap Sort&lt;/strong&gt;. Then &lt;strong&gt;Shell Sort&lt;/strong&gt; (insertion sort with shrinking gaps, better average-case). Then the non-comparison group: &lt;strong&gt;Radix Sort, Counting Sort, Bucket Sort&lt;/strong&gt;: these work on a completely different principle than the comparison-based algorithms, and I wanted that contrast visible in the visualizer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cycle Sort&lt;/strong&gt; was an interesting one to add. It minimizes writes, which sounds academic until you think about flash memory or anything with write-cycle limits. &lt;strong&gt;Comb Sort&lt;/strong&gt; is bubble sort, but with shrinking gap sizes instead of always comparing adjacent elements: a small tweak with a real impact on performance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tim Sort&lt;/strong&gt; is the one Python and Java actually use in production. It's a hybrid of merge and insertion sort, optimized for real-world data patterns that tend to have already-sorted subsequences. Writing the step descriptions for it in three languages was genuinely tedious.&lt;/p&gt;

&lt;p&gt;And then there's &lt;strong&gt;Bogo Sort&lt;/strong&gt;. Randomly shuffles the array until it happens to be sorted. Technically, a sorting algorithm. Worst-case runtime is unbounded. I included it because it's funny, and also because it's a surprisingly clean way to explain what "sorting" actually means. If you can tell when it's done, you have a sorting algorithm.&lt;/p&gt;

&lt;p&gt;Each one has its own step descriptions, color states, and a Python implementation in the code panel.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pathfinding: 3 → 9
&lt;/h2&gt;

&lt;p&gt;The original three were BFS, Dijkstra, and A*. Standard algorithm curriculum. Not the whole story.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bidirectional Search&lt;/strong&gt; runs from both endpoints simultaneously and meets in the middle, cutting the search space roughly in half. &lt;strong&gt;Greedy Best-First&lt;/strong&gt; uses a heuristic to aim toward the goal without caring about path cost, which makes it faster than A* on some inputs but non-optimal. &lt;strong&gt;Jump Point Search&lt;/strong&gt; prunes symmetric paths on uniform-cost grids and is noticeably faster than A* on open grids.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bellman-Ford&lt;/strong&gt; handles negative edge weights, which Dijkstra can't. &lt;strong&gt;IDA*&lt;/strong&gt; is memory-efficient A* via iterative deepening. &lt;strong&gt;D* Lite&lt;/strong&gt; does incremental replanning when the environment changes after the initial search. It's the kind of algorithm that shows up in robotics.&lt;/p&gt;

&lt;p&gt;All nine support walls, variable grid sizes, and localized step descriptions across English, French, and Arabic.&lt;/p&gt;

&lt;h2&gt;
  
  
  A couple of perf fixes
&lt;/h2&gt;

&lt;p&gt;I wrapped &lt;code&gt;ArrayBar&lt;/code&gt; and &lt;code&gt;GridCell&lt;/code&gt; with &lt;code&gt;React.memo&lt;/code&gt;. When you've got dozens of elements animating at once, you don't want them re-rendering on every tick. I also fixed the FAB disabled state, which was only checking the selected sorting algorithm and ignoring whether a pathfinding algorithm was selected. And some pathfinding implementations weren't consistently checking &lt;code&gt;grid[row][col] === 1&lt;/code&gt; before processing neighbors, fixed across BFS, Dijkstra, A*, and Greedy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tests
&lt;/h2&gt;

&lt;p&gt;925 tests now. I added step-structure assertions for the sorting visualizations, so you can verify the algorithm generates the right &lt;em&gt;sequence&lt;/em&gt; of steps, not just the right final output. For pathfinding, I extracted a shared helper &lt;code&gt;assertPathfindingStepStructure&lt;/code&gt;. Having one assertion to maintain instead of nine copies made a real difference when adding new algorithms.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;0.4.0 will have new algorithm family categories beyond sorting and pathfinding. I'm also planning video export, an educational panel with some historical context, and an interactive code panel where you can edit the implementation and run it against tests.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>algorithms</category>
      <category>opensource</category>
      <category>learning</category>
    </item>
    <item>
      <title>Bayan Flow 0.2.0: finishing the foundations (i18n, RTL, tests, and small UX wins)</title>
      <dc:creator>Ayoub Abidi</dc:creator>
      <pubDate>Sat, 20 Dec 2025 11:57:47 +0000</pubDate>
      <link>https://dev.to/ayoub3bidi/bayan-flow-020-finishing-the-foundations-i18n-rtl-tests-and-small-ux-wins-4lb7</link>
      <guid>https://dev.to/ayoub3bidi/bayan-flow-020-finishing-the-foundations-i18n-rtl-tests-and-small-ux-wins-4lb7</guid>
      <description>&lt;p&gt;A few weeks after shipping version 0.1.0, I realized the hard part wasn’t new algorithms, it was the stuff that makes an app feel usable and maintainable. Version 0.2.0 isn’t flashy. It’s the set of changes that stop future work from turning into a refactor nightmare.&lt;/p&gt;

&lt;p&gt;This DevLog covers what I actually did: why I prioritized internationalization and RTL, what I added to make the UI feel finished, and the infrastructure work that lets me iterate safely.&lt;/p&gt;

&lt;p&gt;

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


&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick recap
&lt;/h2&gt;

&lt;p&gt;If you’re new: &lt;strong&gt;Bayan Flow&lt;/strong&gt; is an interactive algorithm visualizer built with &lt;strong&gt;React 19&lt;/strong&gt;, &lt;strong&gt;Vite&lt;/strong&gt;, &lt;strong&gt;Tailwind&lt;/strong&gt;, and &lt;strong&gt;Framer Motion&lt;/strong&gt;. The goal is to make algorithms feel intuitive, not just correct.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this release exists
&lt;/h2&gt;

&lt;p&gt;Three drivers for 0.2.0:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Accessibility/i18n&lt;/strong&gt;: English-only felt wrong for an educational tool; added French and Arabic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Polish/UX&lt;/strong&gt;: Landing page, onboarding, sound, fullscreen, and finer UI behavior so it doesn’t feel like a dev toy.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintainability/infrastructure&lt;/strong&gt;: tests, CI/CD, dependency automation, so future features don’t break everything.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Internationalization and RTL
&lt;/h2&gt;

&lt;p&gt;I used &lt;strong&gt;i18next&lt;/strong&gt; for English, French, and Arabic. Extracting strings into JSON was the easy part. Arabic introduced the real challenge: layout direction.&lt;/p&gt;

&lt;p&gt;Tailwind 4 supports RTL, but the work was in being intentional:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Replace directional classes (&lt;code&gt;ml-4&lt;/code&gt;, &lt;code&gt;pl-2&lt;/code&gt;) with logical ones (&lt;code&gt;ms-4&lt;/code&gt;, &lt;code&gt;ps-2&lt;/code&gt;) where appropriate.&lt;/li&gt;
&lt;li&gt;Audit components for animation direction: things like slide-in need to invert when text direction flips.&lt;/li&gt;
&lt;li&gt;Make language detection automatic (browser locale) but allow manual overrides.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Result: the app flips cleanly. It’s not obvious when it’s right, but painfully obvious when it’s not, so doing this now saves pain later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sound effects (experimental)
&lt;/h2&gt;

&lt;p&gt;I added opt-in audio feedback with &lt;strong&gt;Tone.js&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Beeps on comparisons during sorts.&lt;/li&gt;
&lt;li&gt;Grid-based tones for pathfinding exploration.&lt;/li&gt;
&lt;li&gt;A small chord when the path completes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Totally optional, labeled experimental. It adds a tactile layer to the visuals. If you’re a sound nerd and it’s janky, please open an issue or send a PR.&lt;/p&gt;

&lt;h2&gt;
  
  
  Landing page, routing, and onboarding
&lt;/h2&gt;

&lt;p&gt;Version 0.1.0 dropped users straight into the visualizer. That’s fine for devs, not for learners.&lt;/p&gt;

&lt;p&gt;Now there’s:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A simple landing hero and features section.&lt;/li&gt;
&lt;li&gt;A roadmap preview and basic onboarding copy.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;React Router&lt;/strong&gt; for landing, visualizer app, and roadmap pages.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This basic structure makes the project approachable for first-time visitors and teachers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fullscreen mode and UI refinements
&lt;/h2&gt;

&lt;p&gt;Small UX changes that matter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fullscreen mode to hide other components and focus on the visualization.&lt;/li&gt;
&lt;li&gt;Auto-hiding legend panel: shows when needed, fades when idle.&lt;/li&gt;
&lt;li&gt;Control panel layout fixes (Windows and non-Linux screen ratios).&lt;/li&gt;
&lt;li&gt;Little accessibility touches that improve discoverability and clarity.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Testing and infrastructure
&lt;/h2&gt;

&lt;p&gt;The boring-but-critical work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using &lt;strong&gt;Vitest&lt;/strong&gt;, we now have 31 test files (666 tests in total). Component tests, hooks, and utilities.&lt;/li&gt;
&lt;li&gt;CI/CD overhaul: Netlify branch deployments, PR protections, Codecov for coverage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Renovate&lt;/strong&gt; to automate dependency updates.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not 100% coverage yet (but really, who arrived there in the first place), but enough to refactor confidently without breaking core flows.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I didn’t do
&lt;/h2&gt;

&lt;p&gt;I didn’t add a ton of new algorithms. Why? Because adding algorithms on top of shaky foundations becomes a maintenance tax. Fixing RTL, wiring tests, and adding routing now makes future feature work simple and low-risk.&lt;/p&gt;

&lt;p&gt;Also, I got distracted and shipped a beta of another side project called &lt;a href="https://pypi.org/project/swiss-knife-py/" rel="noopener noreferrer"&gt;Swiss Knife&lt;/a&gt;. Story of every dev, I guess.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Thinking in start/end vs left/right&lt;/strong&gt; is surprisingly hard. One missed class breaks the whole RTL layout.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vitest + Vite module resolution&lt;/strong&gt; caused longer debugging sessions than expected.&lt;/li&gt;
&lt;li&gt;The sound effects system is fun but subjective; user feedback will decide whether it stays or not.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What’s next
&lt;/h2&gt;

&lt;p&gt;Now that the foundation exists, I’ll return to the core feature set:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More sorting and pathfinding algorithms.&lt;/li&gt;
&lt;li&gt;Better complexity analytics.&lt;/li&gt;
&lt;li&gt;Side-by-side Python code integration so you can see visualization and implementation together.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Version 0.2.0 wasn’t about new algorithms. It was about making Bayan Flow reliable, accessible, and maintainable. Those are boring changes on paper, but they pay off when you want to ship features fast and keep contributors sane.&lt;/p&gt;

&lt;p&gt;If you try it, tell me what you think, especially about the audio and the mobile experience. I’ll keep logging progress; next episode should be algorithm-heavy again.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;App:&lt;/strong&gt; &lt;a href="https://bayanflow.netlify.app" rel="noopener noreferrer"&gt;https://bayanflow.netlify.app&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Repo:&lt;/strong&gt; &lt;a href="https://github.com/ayoub3bidi/bayan-flow" rel="noopener noreferrer"&gt;https://github.com/ayoub3bidi/bayan-flow&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Product Hunt:&lt;/strong&gt; &lt;a href="https://www.producthunt.com/products/bayan-flow" rel="noopener noreferrer"&gt;https://www.producthunt.com/products/bayan-flow&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading, and if you’re into projects like this, feel free to check out the video or subscribe on YouTube. More devlogs and experiments are coming soon.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>algorithms</category>
      <category>testing</category>
      <category>cicd</category>
    </item>
    <item>
      <title>I Built an App That Makes Learning Algorithms Way Easier</title>
      <dc:creator>Ayoub Abidi</dc:creator>
      <pubDate>Mon, 10 Nov 2025 18:55:16 +0000</pubDate>
      <link>https://dev.to/ayoub3bidi/i-built-an-app-that-makes-learning-algorithms-way-easier-nce</link>
      <guid>https://dev.to/ayoub3bidi/i-built-an-app-that-makes-learning-algorithms-way-easier-nce</guid>
      <description>&lt;p&gt;For the longest time, I’ve always felt that learning algorithms was harder than it needed to be.&lt;br&gt;&lt;br&gt;
Not because the concepts were too complicated, but because they were always presented in such a "dry" way.&lt;/p&gt;

&lt;p&gt;Slides, PDFs, snippets of pseudocode… they explain what’s happening, sure, but they don’t really make it &lt;em&gt;click&lt;/em&gt; in your head. At least, not for me.&lt;/p&gt;

&lt;p&gt;So I decided to build something that would.&lt;/p&gt;

&lt;p&gt;A few days ago, I quietly released a small project called &lt;strong&gt;Bayan Flow&lt;/strong&gt;, an interactive visualizer that helps you see how algorithms actually work, step by step. Honestly, it’s one of those “I wish I had this when I was learning” projects. But then it started to grow into something that others might actually find useful.&lt;/p&gt;

&lt;p&gt;The name “Bayan” comes from Arabic; it literally means &lt;em&gt;clarity&lt;/em&gt;. That’s the main goal here: to make learning algorithms more intuitive and less abstract.&lt;/p&gt;

&lt;p&gt;

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


&lt;/p&gt;

&lt;h2&gt;
  
  
  What It Actually Does
&lt;/h2&gt;

&lt;p&gt;Right now, Bayan Flow focuses on two main algorithm types: &lt;strong&gt;Sorting&lt;/strong&gt; and &lt;strong&gt;Pathfinding&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;In &lt;strong&gt;Sorting Mode&lt;/strong&gt;, you can visualize Bubble Sort, Quick Sort, and Merge Sort as they rearrange arrays in real time. You can watch comparisons, swaps, and the final order forming right in front of you. Each element changes color to reflect what’s happening, and you can even control playback speed or step manually.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In &lt;strong&gt;Pathfinding Mode&lt;/strong&gt;, you can watch algorithms like BFS, Dijkstra, and A* as they search for the shortest path on a grid. It’s almost like watching the algorithm think, expanding, checking cells, and finding the route.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And when everything’s done, there’s a &lt;strong&gt;Complexity Panel&lt;/strong&gt; that shows you time complexity, graphs, and performance metrics.&lt;/p&gt;

&lt;h2&gt;
  
  
  Under the Hood
&lt;/h2&gt;

&lt;p&gt;Bayan Flow is built with &lt;strong&gt;React 19&lt;/strong&gt;, &lt;strong&gt;Vite&lt;/strong&gt;, &lt;strong&gt;Tailwind CSS&lt;/strong&gt;, and &lt;strong&gt;Framer Motion&lt;/strong&gt; for smooth animations. Everything’s designed to feel lightweight, fast, and responsive. You can even use it on mobile.&lt;/p&gt;

&lt;p&gt;For developers who want to explore the codebase, the project is &lt;strong&gt;open-source&lt;/strong&gt; on GitHub. Each algorithm is split into two parts: one version handles visualization, and the other is a pure implementation for testing. If you want to contribute, you can literally just define your algorithm and plug it in.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bigger Goal
&lt;/h2&gt;

&lt;p&gt;I didn’t want this to just be another “algorithm visualizer”&lt;br&gt;&lt;br&gt;
The goal is to make it a small &lt;strong&gt;learning platform&lt;/strong&gt;, something that blends visualization, explanation, and interactivity.  &lt;/p&gt;

&lt;p&gt;Future updates will include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More sorting and pathfinding algorithms
&lt;/li&gt;
&lt;li&gt;A deeper &lt;strong&gt;Complexity Analyzer&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Python integration for code + visuals learning
&lt;/li&gt;
&lt;li&gt;Possibly, small challenges where users can tweak logic live&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s still early, but I’m happy with how it’s shaping up. And that’s what this whole thing is about: sharing that experience.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;App:&lt;/strong&gt; &lt;a href="https://bayanflow.netlify.app" rel="noopener noreferrer"&gt;https://bayanflow.netlify.app&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Repo:&lt;/strong&gt; &lt;a href="https://github.com/ayoub3bidi/bayan-flow" rel="noopener noreferrer"&gt;https://github.com/ayoub3bidi/bayan-flow&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Product Hunt:&lt;/strong&gt; &lt;a href="https://www.producthunt.com/products/bayan-flow" rel="noopener noreferrer"&gt;https://www.producthunt.com/products/bayan-flow&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading, and if you’re into projects like this, feel free to check out the video or subscribe on YouTube. More devlogs and experiments are coming soon.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>algorithms</category>
      <category>programming</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Quick Tutorial: Implementing Google OAuth2 in FastAPI (Callback Method)</title>
      <dc:creator>Ayoub Abidi</dc:creator>
      <pubDate>Wed, 30 Apr 2025 13:05:51 +0000</pubDate>
      <link>https://dev.to/ayoub3bidi/quick-tutorial-implementing-google-oauth2-in-fastapi-callback-method-ba4</link>
      <guid>https://dev.to/ayoub3bidi/quick-tutorial-implementing-google-oauth2-in-fastapi-callback-method-ba4</guid>
      <description>&lt;p&gt;Hey there! 👋 Let's learn how to get user information from Google using the OAuth2 callback method in FastAPI. We'll keep it super simple and focused!&lt;/p&gt;

&lt;h2&gt;
  
  
  What We're Building
&lt;/h2&gt;

&lt;p&gt;We'll create two endpoints:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;One that gives us a Google login URL&lt;/li&gt;
&lt;li&gt;Another that receives Google's callback and gets user info&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's it! No complicated stuff, just the basics to get rolling.&lt;/p&gt;

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



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;fastapi requests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 1: Set Up Your Environment Variables
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OIDC_GOOGLE_CLIENT_ID=your-client-id
OIDC_GOOGLE_CLIENT_SECRET=your-client-secret
OIDC_GOOGLE_REDIRECT_URI=http://localhost:8000/auth/google
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Create Your Google Handler
&lt;/h2&gt;

&lt;p&gt;Create a file called &lt;code&gt;google.py&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_user_infos_from_google_token_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Exchange the code for tokens
&lt;/span&gt;    &lt;span class="n"&gt;token_response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://oauth2.googleapis.com/token&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;code&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;client_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;OIDC_GOOGLE_CLIENT_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;client_secret&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;OIDC_GOOGLE_CLIENT_SECRET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;redirect_uri&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;OIDC_GOOGLE_REDIRECT_URI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;grant_type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;authorization_code&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Get the access token
&lt;/span&gt;    &lt;span class="n"&gt;access_token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;token_response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;access_token&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Use the access token to get user info
&lt;/span&gt;    &lt;span class="n"&gt;user_info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://www.googleapis.com/oauth2/v2/userinfo&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Authorization&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bearer &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;access_token&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_info&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user_infos&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;user_info&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Create Your FastAPI Routes
&lt;/h2&gt;

&lt;p&gt;Create your routes file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fastapi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;APIRouter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HTTPException&lt;/span&gt;

&lt;span class="n"&gt;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;APIRouter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nd"&gt;@router.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/google/login&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;login_google&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="c1"&gt;# Build the Google login URL
&lt;/span&gt;    &lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;response_type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;code&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;client_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;OIDC_GOOGLE_CLIENT_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;redirect_uri&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;OIDC_GOOGLE_REDIRECT_URI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;scope&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;openid email profile&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;# Create the query string
&lt;/span&gt;    &lt;span class="n"&gt;query_string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;amp;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

    &lt;span class="c1"&gt;# Return the full auth URL
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;url&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://accounts.google.com/o/oauth2/v2/auth?&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;query_string&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;@router.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/google&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;auth_google&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;HTTPException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;detail&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;No code provided&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Get user info using the code
&lt;/span&gt;    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_user_infos_from_google_token_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;HTTPException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;detail&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Couldn&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;t get user info&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Return the user info!
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;user_infos&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How to Use It
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Hit &lt;code&gt;/google/login&lt;/code&gt; to get your Google login URL:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:8000/auth/google/login&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;login_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;url&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Open that URL in a browser. After login, Google will redirect to your callback URL with a code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Your callback endpoint will automatically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Grab the code from the URL&lt;/li&gt;
&lt;li&gt;Exchange it for an access token&lt;/li&gt;
&lt;li&gt;Use the token to get user info&lt;/li&gt;
&lt;li&gt;Return the user info to you!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The user info you get back will look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1234567890"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"user@example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"verified_email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"John Doe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"picture"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://lh3.googleusercontent.com/..."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's all there is to it! Now you can use this user info however you want - create accounts, log people in, whatever you need! 🚀&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing It Out
&lt;/h2&gt;

&lt;p&gt;The easiest way to test:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start your FastAPI server&lt;/li&gt;
&lt;li&gt;Visit &lt;code&gt;/docs&lt;/code&gt; in your browser&lt;/li&gt;
&lt;li&gt;Try the &lt;code&gt;/google/login&lt;/code&gt; endpoint&lt;/li&gt;
&lt;li&gt;Click the URL it gives you&lt;/li&gt;
&lt;li&gt;Watch the magic happen!&lt;/li&gt;
&lt;/ol&gt;

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

</description>
      <category>webdev</category>
      <category>python</category>
      <category>fastapi</category>
      <category>googlecloud</category>
    </item>
    <item>
      <title>Quick Tutorial: Adding Google Auth to FastAPI (Token Method)</title>
      <dc:creator>Ayoub Abidi</dc:creator>
      <pubDate>Wed, 30 Apr 2025 13:05:14 +0000</pubDate>
      <link>https://dev.to/ayoub3bidi/quick-tutorial-adding-google-auth-to-fastapi-token-method-1ggg</link>
      <guid>https://dev.to/ayoub3bidi/quick-tutorial-adding-google-auth-to-fastapi-token-method-1ggg</guid>
      <description>&lt;p&gt;Hey there! 👋 Let's dive into implementing Google authentication in your FastAPI application using the token method. This is perfect when you're working with frontend frameworks like React and want to handle Google Sign-In without dealing with complex OAuth2 flows.&lt;/p&gt;

&lt;h2&gt;
  
  
  What We'll Cover
&lt;/h2&gt;

&lt;p&gt;We'll focus specifically on verifying Google tokens and extracting user information on the backend. This approach works great with frontend libraries like &lt;code&gt;@react-oauth/google&lt;/code&gt; that handle the Google Sign-In button and initial authentication flow.&lt;/p&gt;

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

&lt;p&gt;Before we start, make sure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A FastAPI application set up&lt;/li&gt;
&lt;li&gt;A Google Cloud Project with OAuth2 credentials&lt;/li&gt;
&lt;li&gt;The following Python packages installed:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  pip &lt;span class="nb"&gt;install &lt;/span&gt;fastapi google-auth requests python-jose
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Code
&lt;/h2&gt;

&lt;p&gt;First, let's create a utility function to verify Google tokens and extract user information. Create a file called &lt;code&gt;google.py&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;google.auth.transport&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;google_requests&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;google.oauth2&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;id_token&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_user_infos_from_google_token&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id_token_str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Verify the token and get user info
&lt;/span&gt;    &lt;span class="n"&gt;id_info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;id_token&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verify_oauth2_token&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;id_token_str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="n"&gt;google_requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; 
        &lt;span class="n"&gt;OIDC_GOOGLE_CLIENT_ID&lt;/span&gt;  &lt;span class="c1"&gt;# Your Google Client ID from env variables
&lt;/span&gt;    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;user_infos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;id_info&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;sub&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;  &lt;span class="c1"&gt;# Google's unique identifier for the user
&lt;/span&gt;        &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;email&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;id_info&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;email&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;user_infos&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user_infos&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;user_infos&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user_infos&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;user_infos&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let's create the endpoint that will handle the Google authentication. This goes in your routes file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fastapi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;APIRouter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HTTPException&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;timedelta&lt;/span&gt;

&lt;span class="n"&gt;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;APIRouter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nd"&gt;@router.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/google&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;auth_google&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;credential&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;credential&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;HTTPException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HTTP_400_BAD_REQUEST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
            &lt;span class="n"&gt;detail&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;No credential provided.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Verify the Google token
&lt;/span&gt;    &lt;span class="n"&gt;check&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_user_infos_from_google_token&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;credential&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;check&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;HTTPException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HTTP_400_BAD_REQUEST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
            &lt;span class="n"&gt;detail&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Invalid credential&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;user_infos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;check&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;user_infos&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="c1"&gt;# Here you would typically:
&lt;/span&gt;    &lt;span class="c1"&gt;# 1. Check if the user exists in your database
&lt;/span&gt;    &lt;span class="c1"&gt;# 2. Create a new user if they don't exist
&lt;/span&gt;    &lt;span class="c1"&gt;# 3. Generate your application's JWT token
&lt;/span&gt;
    &lt;span class="c1"&gt;# For example:
&lt;/span&gt;    &lt;span class="n"&gt;access_token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_access_token&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sub&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;user_infos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;email&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]},&lt;/span&gt;
        &lt;span class="n"&gt;expires_delta&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;timedelta&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;minutes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;token&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;access_token&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;The frontend handles the Google Sign-In flow and gets a credential token from Google&lt;/li&gt;
&lt;li&gt;Your frontend sends this token to your &lt;code&gt;/google&lt;/code&gt; endpoint&lt;/li&gt;
&lt;li&gt;The backend verifies the token using Google's libraries&lt;/li&gt;
&lt;li&gt;If valid, you get the user's information (like email and Google ID)&lt;/li&gt;
&lt;li&gt;You can then create a session, JWT token, or whatever authentication mechanism you're using in your app&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Environment Variables
&lt;/h2&gt;

&lt;p&gt;Make sure to set up these environment variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OIDC_GOOGLE_CLIENT_ID=your-google-client-id
ACCESS_TOKEN_EXPIRE_MINUTES=30  # or whatever duration you prefer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Frontend Integration
&lt;/h2&gt;

&lt;p&gt;On your React frontend, you'd typically have something like this:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;GoogleLogin&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@react-oauth/google&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Login&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleSuccess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;credentialResponse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/google?credential=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;credentialResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;credential&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// Store the token, update your auth state, etc.&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;GoogleLogin&lt;/span&gt;
      &lt;span class="nx"&gt;onSuccess&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleSuccess&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;onError&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Login Failed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
    &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;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;That's it! This setup gives you a clean way to handle Google authentication using tokens. Remember to add proper error handling and user management based on your application's needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security Notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Always verify tokens server-side&lt;/li&gt;
&lt;li&gt;Keep your Google Client ID secure&lt;/li&gt;
&lt;li&gt;Consider adding rate limiting to your auth endpoints&lt;/li&gt;
&lt;li&gt;Store user tokens securely in your frontend (preferably in HTTP-only cookies)&lt;/li&gt;
&lt;/ul&gt;

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

</description>
      <category>webdev</category>
      <category>python</category>
      <category>fastapi</category>
      <category>googlecloud</category>
    </item>
    <item>
      <title>Quick tutorial: How to add a release GitHub workflow</title>
      <dc:creator>Ayoub Abidi</dc:creator>
      <pubDate>Fri, 01 Mar 2024 08:07:31 +0000</pubDate>
      <link>https://dev.to/ayoub3bidi/quick-tutorial-how-to-add-a-release-github-workflow-56ib</link>
      <guid>https://dev.to/ayoub3bidi/quick-tutorial-how-to-add-a-release-github-workflow-56ib</guid>
      <description>&lt;p&gt;As developers, we often find ourselves repeating manual steps when releasing new versions of our software. GitHub Actions allows us to automate these tasks, ensuring consistency and saving valuable time. Whether you’re deploying a web app, a library, or any other project, setting up a release workflow can significantly improve your development process.&lt;/p&gt;

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

&lt;p&gt;Before we dive into the tutorial, make sure you have the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;GitHub Repository: You’ll need a GitHub repository where you want to set up the release workflow.&lt;/li&gt;
&lt;li&gt;Basic YAML Knowledge: We’ll be writing our workflow in YAML format, so a basic understanding of YAML syntax will be helpful.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Creating a Simple Release Workflow
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Understanding GitHub Actions Workflows
&lt;/h3&gt;

&lt;p&gt;GitHub Actions workflows consist of triggers, jobs, and steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Triggers:&lt;/strong&gt; Events that initiate a workflow (e.g., pushes to specific branches).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Jobs:&lt;/strong&gt; Units of work within a workflow.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Steps:&lt;/strong&gt; Individual actions performed within a job.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 2: Creating a Workflow File
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Go to your GitHub repository.&lt;/li&gt;
&lt;li&gt;Navigate to the &lt;code&gt;.github/workflows directory&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Create a new YAML file (e.g., &lt;code&gt;release.yml&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 3: Define Your Workflow
&lt;/h3&gt;

&lt;p&gt;Here’s a basic example of a release workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;name: Create release

on:
  push:
    tags:
      - &lt;span class="s2"&gt;"v*"&lt;/span&gt;

permissions:
  contents: write

&lt;span class="nb"&gt;jobs&lt;/span&gt;:
  release:
    name: Release pushed tag
    runs-on: ubuntu-22.04
    steps:
      - name: Create release
        &lt;span class="nb"&gt;env&lt;/span&gt;:
          GITHUB_TOKEN: &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="p"&gt;{ secrets.GITHUB_TOKEN &lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
          tag: &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="p"&gt;{ github.ref_name &lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
        run: |
          gh release create &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$tag&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
              &lt;span class="nt"&gt;--repo&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$GITHUB_REPOSITORY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
              &lt;span class="nt"&gt;--title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;#v&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
              &lt;span class="nt"&gt;--generate-notes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This GitHub workflow, named "Create release," triggers whenever a tag starting with "v" is pushed to the repository, granting write access to repository contents.&lt;br&gt;
It defines a job named "release" that runs on an Ubuntu 22.04 virtual machine. This job executes steps to create a release using the GitHub CLI (gh).&lt;br&gt;
The necessary environment variables, &lt;code&gt;GITHUB_TOKEN&lt;/code&gt;, and &lt;code&gt;tag&lt;/code&gt; are set automatically from GitHub so no need to worry about that.&lt;br&gt;
The gh release create command is used to create a release, specifying the tag name, repository, and title (stripping the initial "v"), and generating release notes automatically. &lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: How to push your first release:
&lt;/h3&gt;

&lt;p&gt;To demonstrate, you can create a tag locally using &lt;code&gt;git tag v1.0.0&lt;/code&gt; and then push the tag to GitHub with &lt;code&gt;git push origin v1.0.0&lt;/code&gt;.&lt;br&gt;
This would trigger the workflow, resulting in the creation of a release with the specified tag and release notes on the GitHub repository's Releases page.&lt;/p&gt;

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

&lt;p&gt;Congratulations! You’ve set up a simple release workflow using GitHub Actions. Remember to customize it based on your project’s specific requirements. Explore more advanced features and integrations to supercharge your development process.&lt;/p&gt;

&lt;p&gt;Happy automating! 🚀&lt;/p&gt;

</description>
      <category>devops</category>
      <category>githubactions</category>
      <category>git</category>
      <category>opensource</category>
    </item>
    <item>
      <title>The Three.js Supremacy</title>
      <dc:creator>Ayoub Abidi</dc:creator>
      <pubDate>Sun, 02 Jul 2023 15:50:17 +0000</pubDate>
      <link>https://dev.to/ayoub3bidi/the-threejs-supermacy-4a45</link>
      <guid>https://dev.to/ayoub3bidi/the-threejs-supermacy-4a45</guid>
      <description>&lt;p&gt;I have used Three.js for a good amount of time now (still a total noob for now), and it does a really great job of abstracting away the headaches of getting going with 3D in the browser. With it you can create cameras, objects, lights, materials and more, and you have a choice of renderer, which means you can decide if you want your scene to be drawn using HTML 5's canvas, WebGL or SVG.&lt;/p&gt;

&lt;p&gt;In this article we will explore Three.js and why you should care about it especially if you are a Frontend developer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why should you care about Three.js?
&lt;/h2&gt;

&lt;p&gt;Three.js was released by Ricardo Cabello in April 2010. At that time, the code was developed in ActionScript and then the code was ported to JavaScript. Three.js was introduced with the rendering code in the form of the module instead of the core itself. Later on in March 2011, Joshua Koo came on the board after the introduction of WebGL. In September 2011, Koo released his first three.js demo for 3D text.&lt;/p&gt;

&lt;p&gt;Three.js allows for the rendering of graphics on the client side, but can also be rendered server side with some node.js magic. This means you can use Three.js to render a simple model on your site from your server, but also allow users to interact with something much more complex on the same site if their specs allow for it. The application of this kind of things are endless.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three.js is all that you need in one library
&lt;/h2&gt;

&lt;p&gt;A big part of any rendering, 3D or otherwise, is the math involved. Typically, you’d have a separate math library that handles all of the fancy linear algebra and calculus that might go into rendering a complex graphic, but Three.js includes all of this in its massive library.&lt;/p&gt;

&lt;p&gt;It has classes that are specifically designed for 3D math, and since it’s all contained under the same library, you can be sure that everything will work together, of course that will be better than 20 libraries that potentially can't fit with each other, so having everything come under the same roof.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three.js is easy to learn
&lt;/h2&gt;

&lt;p&gt;The Three.js learning curve won’t be too steep. It organizes all of the renders you’ll do, whether 3D or 2D, under a “Scene” container. This is analogous to a body tag in HTML, in the sense that everything else that you render will fall inside this container.&lt;/p&gt;

&lt;p&gt;Why? Well, the typical DOM used for rendering graphics such as canvases and SVGs are very limited in how you can manipulate elements (you’re typically allowed to rotate on only one axis and can only move elements in a 2D space).&lt;/p&gt;

&lt;p&gt;Three.js includes a variety of subclasses that do exactly what you’d expect: “Light” renders a light source, “Mesh” renders an object, and “Camera” renders a, well, you know, a camera. Things can not be simpler than that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three.js relies heavily on WebGL
&lt;/h2&gt;

&lt;p&gt;While Three.js handles the setting up of scenes, it really relies on WebGL for a lot of its rendering so it’s important that you understand how it works too.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/f-9LEoYYvE4"&gt;
&lt;/iframe&gt;
 &lt;/p&gt;

&lt;p&gt;WebGL expands on a lot of traditionally non-3D APIs, like the ‘canvas’ and ‘svg’ tags that you can use to tell the browser to draw certain shapes. WebGL simply offers you the ability to use these 2D drawing elements to render 3D elements (whatever you’re drawing, you’re doing it to a 2D screen in the end).&lt;/p&gt;

&lt;p&gt;WebGL makes good use of hardware acceleration to efficiently render these objects on your screen.&lt;br&gt;
In Three.js, 3D objects are rendered through the “WebGLRenderer” class, which is what translates your life-like model of the Eiffel Tower into numbers that your GPU can efficiently process in memory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Should you rely on Three.js to create games?
&lt;/h2&gt;

&lt;p&gt;Three.js is the most flexible and powerful 3D engine for web browsers. With it, you can create anything from simple 3D models to photorealistic, real-time scenes. You can even optionally render THREE.JS layers on top of each other instead of traditional DOM elements, meaning you can create incredibly realistic and immersive scenes with minimal effort.&lt;/p&gt;

&lt;p&gt;There are many reasons to choose Three.js over Unity, including but not exclusive to the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A great asset management system.&lt;/li&gt;
&lt;li&gt;A high-performance 3D graphics engine.&lt;/li&gt;
&lt;li&gt;A modern GUI that can be extended by plugins.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Three.js is an emerging web technology that has the potential to change the face of web development. It provides a powerful toolset for creating 3D graphics and visualizations on the web. With its ease of use and cross-browser compatibility, Three.js has gained popularity among web developers.&lt;/p&gt;

&lt;p&gt;Sources:&lt;br&gt;
&lt;a href="https://web.dev/three-intro/" rel="noopener noreferrer"&gt;https://web.dev/three-intro/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.kofi-group.com/threejs-explained-in-10-minutes/" rel="noopener noreferrer"&gt;https://www.kofi-group.com/threejs-explained-in-10-minutes/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.linkedin.com/pulse/exploring-potential-threejs-emerging-web-technology-chris-chiancone/" rel="noopener noreferrer"&gt;https://www.linkedin.com/pulse/exploring-potential-threejs-emerging-web-technology-chris-chiancone/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://discourse.threejs.org/t/pros-and-cons-of-three-js/7050/2" rel="noopener noreferrer"&gt;https://discourse.threejs.org/t/pros-and-cons-of-three-js/7050/2&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.digiprima.com/blogs/is-threejs-better-for-developing-web-based-3d-games#:%7E:text=js%3F-,Three.,geometries%20using%20just%20JavaScript%20APIs" rel="noopener noreferrer"&gt;https://www.digiprima.com/blogs/is-threejs-better-for-developing-web-based-3d-games#:~:text=js%3F-,Three.,geometries%20using%20just%20JavaScript%20APIs&lt;/a&gt;.&lt;br&gt;
&lt;a href="https://eternitech.com/technologies/three-js/" rel="noopener noreferrer"&gt;https://eternitech.com/technologies/three-js/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>design</category>
      <category>frontend</category>
    </item>
    <item>
      <title>The beauty of using Python for your back-end</title>
      <dc:creator>Ayoub Abidi</dc:creator>
      <pubDate>Mon, 01 May 2023 08:15:36 +0000</pubDate>
      <link>https://dev.to/ayoub3bidi/the-beauty-of-using-python-for-your-back-end-5c2j</link>
      <guid>https://dev.to/ayoub3bidi/the-beauty-of-using-python-for-your-back-end-5c2j</guid>
      <description>&lt;p&gt;Python is a versatile, high-level programming language that is widely used in web development, scientific computing, artificial intelligence, and data analysis. One of its strengths is its ability to serve as a backend language for web applications. In this article, we'll explore some of the reasons why Python should be your backend language of choice, then I will talk about my little expriences with Flask &amp;amp; FastApi.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Python should be your backend language of choice
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Simplistic
&lt;/h3&gt;

&lt;p&gt;Python is a language that is known for its simplistic, readable and easy-to-use syntax. Developers can write less code than in many other languages, which can speed up development times and boost productivity. Aside from SQL supreme similar english syntax, Python comes in second place easily and this what makes it the ideal language for young developers (of course after learning C like real men).&lt;/p&gt;

&lt;h3&gt;
  
  
  Mature Ecosystem
&lt;/h3&gt;

&lt;p&gt;Python has a rich ecosystem of libraries and frameworks that make backend development faster and more accessible. Popular frameworks like Flask and FastApi (which we will talk about them in a while) provide powerful tools for web application development, while libraries like NumPy and Pandas are essential for scientific computing and data analysis.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scalable
&lt;/h3&gt;

&lt;p&gt;Python is a scalable language that can handle large volumes of data and traffic, making it a popular choice for high-traffic websites and applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Performance
&lt;/h3&gt;

&lt;p&gt;Python is referred to as both CPU and memory unfriendly but with a huge number of libraries, Python performs efficiently all the basic development tasks. Golang comes with inbuilt features and is more suitable for microservices software architectures.&lt;/p&gt;

&lt;h3&gt;
  
  
  Active Community
&lt;/h3&gt;

&lt;p&gt;Python has a vast and active community of developers who contribute to open-source projects and offer support through forums and online resources. This community support can be invaluable when facing complex development challenges.&lt;/p&gt;

&lt;h3&gt;
  
  
  Integrable
&lt;/h3&gt;

&lt;p&gt;Python can integrate with many other languages and platforms, making it an excellent choice for building complex systems that require integration with multiple technologies.&lt;/p&gt;

&lt;h3&gt;
  
  
  Machine Learning and AI
&lt;/h3&gt;

&lt;p&gt;Since everyone is talking about the magic of AI we shoudl mention Python's popularity in machine learning and AI. It makes it an excellent choice for building backend systems that require machine learning algorithms. Libraries like TensorFlow and PyTorch are powerful tools for building deep learning models.&lt;/p&gt;

&lt;h2&gt;
  
  
  My experience with Flask
&lt;/h2&gt;

&lt;p&gt;Flask is a well-known and best Python framework that comes under the Microframework category and comes with the BSD license. It is inspired by the Sinatra Ruby framework, so developers can utilize Flask as a web framework for both frontend and backend.&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%2Fzey6wz36u0i1oqt3zg5r.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%2Fzey6wz36u0i1oqt3zg5r.png" alt=" " width="438" height="245"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks to the functionality, restful request dispatching, request handling, modular, and lightweight frontend design of Flask, it is more adaptable than Django.&lt;/p&gt;

&lt;p&gt;ORMs deliver an advanced abstraction on an interactive database that lets a developer transcribe code in place of SQL to read, create, delete, and update tools and data in the database.&lt;/p&gt;

&lt;p&gt;Flask is a framework of Python language that allows the users to build a genuine web app foundation and database tables from where they can use any source of extensions needed.&lt;/p&gt;

&lt;p&gt;The other benefit of using this framework is that it is compatible with Google App Engine and offers a request dispatching way. For instance, 21% of Facebook Infrastructure has Python codebase.&lt;/p&gt;

&lt;h2&gt;
  
  
  My experience with FastApi
&lt;/h2&gt;

&lt;p&gt;Before saying anything about this experience I just want to say that ma man &lt;a href="https://dev.to/tiangolo"&gt;Sebastián Ramírez&lt;/a&gt; didn't just make a framework, he made a weapon. The future of this framework is absolutely bright.&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%2Fta4xy7aqnvpchlzaqvnt.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%2Fta4xy7aqnvpchlzaqvnt.png" alt=" " width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;FastAPI is a Python web framework that is similar to Flask in its minimalistic design, but it offers many powerful features that make it stand out.&lt;br&gt;
It uses Python +3.6 type declarations, allowing for excellent editor support and extensive validation of standard and custom data types.&lt;/p&gt;

&lt;p&gt;FastAPI also provides built-in support for API documentation, security and authentication, and asynchronous endpoints, all of which can simplify and speed up development.&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%2Fcpgftt87kv55wio8cmv5.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%2Fcpgftt87kv55wio8cmv5.png" alt=" " width="800" height="143"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt;Score chart from Techempower&lt;/center&gt;  

&lt;p&gt;FastAPI is known for its excellent performance (It's in the name, of course it will be fast), being built over ASGI instead of WSGI, making it a great choice for building APIs.&lt;/p&gt;

&lt;p&gt;All points above are great on their own, but the most important part is that they are leading (if not forcing) to clean code habits. All points above are great on their own, but the most important part is that they are leading (if not forcing) to clean code habits.&lt;br&gt;
FastAPI makes it mandatory to write type hints, declare dependencies, and follow OOP design patterns which help to create great code structure and keep code clean. This is the reason why it’s so popular now and I feel it’s here to stay.&lt;/p&gt;

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

&lt;p&gt;Whether you're building a web application or a complex system, Python is a language that can handle the challenge.&lt;br&gt;
Flask and FastAPI can put up Python web servers and data science programs rapidly. FastAPI is superior for speed and performance. &lt;br&gt;
Flask is better for simple microservices with a few API endpoints.&lt;/p&gt;

&lt;p&gt;Sources:&lt;br&gt;
&lt;a href="https://micropyramid.com/blog/why-choose-python-as-backend-development" rel="noopener noreferrer"&gt;Why Choose Python As Backend Development?&lt;br&gt;
&lt;/a&gt;&lt;br&gt;
&lt;a href="https://sonali-saikia.medium.com/python-for-backend-development-bbdd4c0cf041" rel="noopener noreferrer"&gt;Python for backend development&lt;br&gt;
&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.monocubed.com/blog/top-python-frameworks/" rel="noopener noreferrer"&gt;List of 7 Best Python Frameworks to Consider For Your Web Project&lt;/a&gt;&lt;br&gt;
&lt;a href="https://medium.com/featurepreneur/why-fastapi-69fb172756b7" rel="noopener noreferrer"&gt;Why FastAPI?&lt;/a&gt;&lt;br&gt;
&lt;a href="https://levelup.gitconnected.com/why-fastapi-is-a-future-of-python-web-development-181bed9d46f4" rel="noopener noreferrer"&gt;Why FastAPI is a Future of Python Web Development&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.infolytx.com/fast-api-gbu/" rel="noopener noreferrer"&gt;FastAPI – The Good, the Bad and the Ugly&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>python</category>
      <category>flask</category>
      <category>fastapi</category>
    </item>
    <item>
      <title>Should you (still) use/learn GraphQL?</title>
      <dc:creator>Ayoub Abidi</dc:creator>
      <pubDate>Mon, 26 Sep 2022 14:03:46 +0000</pubDate>
      <link>https://dev.to/ayoub3bidi/should-you-still-uselearn-graphql-34g5</link>
      <guid>https://dev.to/ayoub3bidi/should-you-still-uselearn-graphql-34g5</guid>
      <description>&lt;p&gt;GraphQL is fast becoming a go-to query language for companies to interact with their data. Although data management is one of the top concerns for a lot of companies, many people don’t really understand what GraphQL does or why it’s so popular. &lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/eIQh02xuVw4"&gt;
&lt;/iframe&gt;
&lt;br&gt;
When GraphQL was first introduced it offered a radically new way to build APIs, with more control, more granularity, and more flexibility.&lt;br&gt;
I know this technology is not a hot topic anymore unlike 2 years ago when literally everyone was talking about it and how fascinating it was.&lt;br&gt;
I used GraphQL for two projects for now and I think it's good, but the real question here is it still worth learning and using in your project or is it just a phase?&lt;/p&gt;
&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;GraphQL is not needed for every project.&lt;/li&gt;
&lt;li&gt;A solid REST API is good enough.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;GraphQL is for when REST is Just Too Slow.&lt;/p&gt;
&lt;h2&gt;
  
  
  GraphQL Vs. REST
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff4qr805foun473d25t8e.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%2Ff4qr805foun473d25t8e.png" alt="GraphQL Vs. REST" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;REST&lt;/strong&gt; is Stateless meaning that it doesn’t require any knowledge of the client's state to correctly interpret the request. all of the necessary information is included in the request itself.&lt;br&gt;
REST fetches JSON data and is available to any server-side language and any frontend framework.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;GraphQL&lt;/strong&gt; was designed to make APIs fast, flexible, and developer-friendly. And just like REST, it is both stateless, available to any frontend framework and any server-side language, and usually fetches JSON data. But where GraphQL becomes very unique, is its way of communicating with the front end.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  What GraphQL does better
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbxzwegtpl3lzadalxu9w.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%2Fbxzwegtpl3lzadalxu9w.png" alt=" " width="800" height="254"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Quick Product Development on the Frontend&lt;/strong&gt;: frontend development groups have to wait a certain amount of time for the backend group to finish writing these APIs for the client app to fetch and post the data. The GraphQL lifecycle provides an approach where both frontend and backend developers can work in parallel without obstructing the overall development process.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;A single API call&lt;/strong&gt;: This allows you to request multiple resources. this minimizes both time and bandwidth by reducing the number of network round trips to the server. It also helps to prevent waterfall network requests, where you are dependent on the result of one call, to create another.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Customizable response&lt;/strong&gt;: It makes it a great benefit to the front end of the application. This involves the ability to define an alias for fields and resolve each of the values into different values. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  What REST does better
&lt;/h2&gt;

&lt;p&gt;REST is still the leading architecture and most developers know it inside out.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmhx3muna6uq4gecgwdh4.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%2Fmhx3muna6uq4gecgwdh4.png" alt=" " width="800" height="254"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;REST has &lt;strong&gt;many build-in features&lt;/strong&gt;: that make it super easy to implement a simplified cache, file upload, or even a rate limitation per API key.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rest is still &lt;strong&gt;a better choice for Complex queries&lt;/strong&gt;: GraphQL's nested architecture can turn into a bottleneck when creating complex queries.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It is still &lt;strong&gt;easier to create good error handling&lt;/strong&gt; in RESTful APIs: GraphQL always returns the 200 Ok status for every API request, including those with errors. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Both GraphQL and REST API development lifecycle approaches are useful depending on the need, and both have their advantages and disadvantages. GraphQL is exponentially gaining popularity, mainly because of its “no over and under-fetching” ability.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/ZfccwYUD8H0"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;sources: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.mobilelive.ca/blog/graphql-vs-rest-what-you-didnt-know" rel="noopener noreferrer"&gt;https://www.mobilelive.ca/blog/graphql-vs-rest-what-you-didnt-know&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://medium.com/@vitaliysteffensen/should-i-use-graphql-or-rest-in-2022-7291cc882cab" rel="noopener noreferrer"&gt;https://medium.com/@vitaliysteffensen/should-i-use-graphql-or-rest-in-2022-7291cc882cab&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.logrocket.com/graphql-vs-rest-api-why-you-shouldnt-use-graphql/" rel="noopener noreferrer"&gt;https://blog.logrocket.com/graphql-vs-rest-api-why-you-shouldnt-use-graphql/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://thenewstack.io/graphql-for-when-rest-just-doesnt-cut-it/" rel="noopener noreferrer"&gt;https://thenewstack.io/graphql-for-when-rest-just-doesnt-cut-it/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>graphql</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>react</category>
    </item>
    <item>
      <title>TypeScript (or Oh god why I didn't learn it sooner ?)</title>
      <dc:creator>Ayoub Abidi</dc:creator>
      <pubDate>Fri, 19 Aug 2022 08:25:40 +0000</pubDate>
      <link>https://dev.to/ayoub3bidi/typescript-or-oh-god-why-i-didnt-learn-it-sooner--52h0</link>
      <guid>https://dev.to/ayoub3bidi/typescript-or-oh-god-why-i-didnt-learn-it-sooner--52h0</guid>
      <description>&lt;p&gt;TypeScript has been increasing in its popularity for the last couple of years. Angular, one of the largest frontend frameworks, is using TypeScript. About &lt;a href="https://2019.stateofjs.com/javascript-flavors/typescript" rel="noopener noreferrer"&gt;60% of JS programmers&lt;/a&gt; already use TypeScript, But why ?&lt;/p&gt;

&lt;h3&gt;
  
  
  What is TypeScript ?
&lt;/h3&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/zQnBQ4tB3ZA"&gt;
&lt;/iframe&gt;
&lt;br&gt;
In short, TypeScript is a superset of JavaScript that has optional typing and compiles to plain JavaScript.&lt;br&gt;
In simpler words, TypeScript technically is JavaScript with static typing, whenever you want to have it.&lt;br&gt;
But why you need to add static typing to JavaScript ? isn't this will add more "unnecessary" code (and isn't will make it more like Java ?) ?&lt;br&gt;
Here are some reasons may change your mind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can avoid masterfully-hidden-ninja errors: The freedom of dynamic typing often leads to bugs that not only decrease the efficiency of the programmer’s work, but can also grind development to halt due to increasing costs of adding new lines of code.&lt;/li&gt;
&lt;li&gt;It is easier to refactor code without breaking it significantly.&lt;/li&gt;
&lt;li&gt;Orienting oneself in complex, large-scale systems is not a nightmare anymore.
TypeScript is essentially a JS linter. Or, JS with documentation that the compiler can understand.
Types in TS are optional, and every JS file is a valid TypeScript file. While the compiler will complain if you have type errors in your initial files, it does give you back a JavaScript file that works as it did before.
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  TS vs JS &amp;amp; why you should choose TypeScript over JavaScript ? &amp;amp; why you shouldn't ?
&lt;/h3&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/D6or2gdrHRE"&gt;
&lt;/iframe&gt;
&lt;br&gt;
You should because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;TypeScript is more reliable&lt;/strong&gt;: TypeScript code is more reliable and easier to refactor. This enables developers to evade errors and do rewrites much easier.
Types invalidate most of the silly errors that can sneak into JavaScript codebases, and create a quick feedback loop to fix all the little mistakes when writing new code and refactoring.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TypeScript is more explicit&lt;/strong&gt;: Making types explicit focuses our attention on how exactly our system is built, and how different parts of it interact with each other. In large-scale systems, it is important to be able to abstract away the rest of the system while keeping the context in mind. Types enable us to do that.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TypeScript and JavaScript are practically interchangeable, so why not?&lt;/strong&gt;: Since JavaScript is a subset of TypeScript, you can use all JavaScript libraries and code that you want in your TypeScript code.
This means that you can gradually adopt TypeScript in your JavaScript codebase, first adding types to individual modules and then scale from there to the moon.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You shouldn't because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can’t just take a JavaScript team or a JavaScript repository and instantly switch them to idiomatic TypeScript. There are tradeoffs, and upfront time sacrifices you have to make.&lt;/li&gt;
&lt;li&gt;Types give you in the long run, in the short run, it does take more time to add them. This is arguably not a huge deal, but it is an argument in favor of JavaScript.&lt;/li&gt;
&lt;li&gt;You might not choose TypeScript for small projects and prototypes for your own use (totally not worth it).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  My (recent) experience with TS in Vue.js, React.js &amp;amp; Backend generally (an unnecessary story you can skip)
&lt;/h3&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/ydkQlJhodio"&gt;
&lt;/iframe&gt;
&lt;br&gt;
My first experience with TS was actually with Angular (it was a university project and my first/last experience with that framework) and I really didn't know what is TS so I google it and knew that you can write JS in TS file without any problem so I did it.&lt;/p&gt;

&lt;p&gt;My first real experience with TS was with Vue.js, I wanted to know what TS will benefit me in my code and it was actually good and weird at the same time (I got some horrible Java flashbacks while doing it) but I felt it wasn't necessary for my code at that time.&lt;/p&gt;

&lt;p&gt;My second experience with TS was with a full-stack project (React.js as the frontend framework), that when I felt that TS is a significant solution for my barbarian JS code.&lt;/p&gt;
&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Overall, TypeScript is a great tool to have in your toolset even if you don’t use it to its full capacity. It’s easy to start small and grow slowly, learning and adding new features as you go.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/ahCwqrYpIuM"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Sources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.vox.com/science-and-health/2019/1/31/18200497/dunning-kruger-effect-explained-trump" rel="noopener noreferrer"&gt;https://www.vox.com/science-and-health/2019/1/31/18200497/dunning-kruger-effect-explained-trump&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://serokell.io/blog/why-typescript" rel="noopener noreferrer"&gt;https://serokell.io/blog/why-typescript&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dzone.com/articles/what-is-typescript-and-why-use-it" rel="noopener noreferrer"&gt;https://dzone.com/articles/what-is-typescript-and-why-use-it&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.typescriptlang.org/why-create-typescript" rel="noopener noreferrer"&gt;https://www.typescriptlang.org/why-create-typescript&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Elegant VS Code Extensions [part 2]</title>
      <dc:creator>Ayoub Abidi</dc:creator>
      <pubDate>Thu, 04 Aug 2022 15:24:14 +0000</pubDate>
      <link>https://dev.to/ayoub3bidi/elegant-vs-code-extensions-part-2-4iaa</link>
      <guid>https://dev.to/ayoub3bidi/elegant-vs-code-extensions-part-2-4iaa</guid>
      <description>&lt;p&gt;It's been over a year since I published &lt;a href="https://dev.to/ayoub3bidi/elegant-vs-code-extensions-2fo6"&gt;Elegant VS Code Extensions&lt;/a&gt; article.&lt;br&gt;
So I decided to make a second part.&lt;br&gt;
Without further ado, let's jump into our new list.&lt;/p&gt;

&lt;h3&gt;
  
  
  Auto Rename Tag
&lt;/h3&gt;

&lt;p&gt;Instead of changing open and close tags by yourself, you can use Auto-Rename Tag and do this simultaneously. Start changing an open tag and its close tag will change automatically. This is very useful, especially when you have a lot of nested code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Better Comments
&lt;/h3&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%2Fa753yiyz7mmg5scrnm2d.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%2Fa753yiyz7mmg5scrnm2d.png" alt=" " width="223" height="107"&gt;&lt;/a&gt; &lt;br&gt;
What this extension do is spice up your code commenting game by allowing different colored comments which would make them stand out rather than the boring grey default.&lt;/p&gt;

&lt;h3&gt;
  
  
  Code Snap
&lt;/h3&gt;

&lt;p&gt;So far, the CodeSnap extension is my favorite tool to create a screenshot with its simplicity. After installation, you can just drag to select your code where you want a screenshot, right-click to open the CodeSnap menu, and click a button to generate a screenshot and save it as PNG locally.&lt;/p&gt;

&lt;h3&gt;
  
  
  Git History
&lt;/h3&gt;

&lt;p&gt;Git History gives us a wide range of features, Using Git History we can access the git log with the graph and details, As the name also suggests we can view and search the history and we can also compare branches, commits, and files across commits along with many miscellaneous features. With the new update of VS Code, you will see many miscellaneous features of Git History already available on the Source control section on VS Code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Live Server
&lt;/h3&gt;

&lt;p&gt;This extension launch a local development server with live reload feature for static &amp;amp; dynamic pages. It will help you while developing a basic project without any framework but with feature of real-time reload that exist in every framework.&lt;/p&gt;

&lt;h3&gt;
  
  
  Vim
&lt;/h3&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/-txKSRn0qeA"&gt;
&lt;/iframe&gt;
&lt;br&gt;
In case you don't know what vim is, it's a free and open-source, screen-based text editor program. it was know for it's capability to make you productive while coding But we all are using vs code now. This is when vim extension comes and give you the best of both worlds.&lt;/p&gt;

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

&lt;p&gt;This was it. I'm hoping these extensions help you become more productive!&lt;/p&gt;

</description>
      <category>vscode</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I've learned React (after being in love with Vue)</title>
      <dc:creator>Ayoub Abidi</dc:creator>
      <pubDate>Fri, 13 May 2022 14:44:23 +0000</pubDate>
      <link>https://dev.to/ayoub3bidi/ive-learned-react-after-being-in-love-with-vue-2ng2</link>
      <guid>https://dev.to/ayoub3bidi/ive-learned-react-after-being-in-love-with-vue-2ng2</guid>
      <description>&lt;p&gt;These days, a new trending front-end framework is released every now and then. But React and Vue.js still stands as the most popular among all the other alternatives. And although both are performant, elegant, and arguably easy to learn, they have some different opinions on how certain things should be done, and different ways of achieving the same end result. I believe getting comfortable and efficient with a frontend framework is mostly about learning the patterns of doing regular stuff.&lt;/p&gt;

&lt;h1&gt;
  
  
  TL;DR
&lt;/h1&gt;

&lt;p&gt;React is good (but I still love Vue more), I need to work, think differently, and have the best community support available on the internet.&lt;/p&gt;

&lt;h2&gt;
  
  
  My story with Vue
&lt;/h2&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/nhBVL41-_Cw"&gt;
&lt;/iframe&gt;
 &lt;br&gt;
I’ve been a long-time Vue.js fan and still think it’s a great framework with a lot of potentials. It was the first JS framework I learned and will always have a special place in my heart. It’s easy to learn and with the Vue CLI, you can create a functional site in minutes and easily deploy it. I liked the organization of the .vue files with their separate HTML, JS, and CSS sections. I even used it during my summer and my end of studies internships. So here you may ask me why you switched to react? you obviously like this framework. Ok, let me explain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vue Vs React (or How developers feel about them)
&lt;/h2&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/Tn6-PIqc4UM"&gt;
&lt;/iframe&gt;
&lt;br&gt;
I'm not making this article about which framework is best for you but we need to know what professionals think about the two frameworks. The way experts see React and Vue might help others decide which of the two is more suited to their current expectations and capabilities. Although there aren't available any reports asking this question anymore, answers from 2018 are rather ever-green aspects so we can treat them as up to date to a huge extent. What devs love about Vue.js:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Elegant programming style and patterns&lt;/li&gt;
&lt;li&gt;Easy learning curve&lt;/li&gt;
&lt;li&gt;Good documentation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What devs love about React:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Elegant programming style and patterns&lt;/li&gt;
&lt;li&gt;Rich package ecosystem&lt;/li&gt;
&lt;li&gt;Widespread usage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;React took the top spot in the most popular web framework list in the 2021 Stack Overflow Survey, with 40.14% of respondents choosing React while Vue.js went two positions up getting 5th place. Given its steadily rising popularity, we can predict its growth in the following years.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv699vq0sgzs3857u1qnk.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%2Fv699vq0sgzs3857u1qnk.png" alt="stackOverflow survey" width="582" height="647"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Job market
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhtt1v1skfbh6lszl3lh0.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%2Fhtt1v1skfbh6lszl3lh0.png" alt="SoV 2021 vue" width="800" height="457"&gt;&lt;/a&gt; &lt;br&gt;
Although Vue.js is easy to learn (60% of &lt;a href="https://2021.stateofjs.com/en-US/libraries/front-end-frameworks/" rel="noopener noreferrer"&gt;the SoV 2021 respondents&lt;/a&gt; describe it this way), there are more React developers on the market who are already experienced in this framework and would use it again.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frbjowogywpgrfpni7rqr.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%2Frbjowogywpgrfpni7rqr.png" alt="SoV 2021 react" width="800" height="457"&gt;&lt;/a&gt; &lt;br&gt;
So if there is a business need for a more complex app, getting an experienced React developer who can jump into the project and start working immediately can take less time. On the other hand, the pool of Vue.js developers has been steadily growing in the last six years so this is becoming less challenging, too.&lt;/p&gt;

&lt;p&gt;Interestingly, &lt;a href="https://www.jetbrains.com/lp/devecosystem-2021/javascript/" rel="noopener noreferrer"&gt;The Jet Brains Dev Ecosystem 2021 survey&lt;/a&gt; showed slightly different numbers and revealed that the developer knowledge and regular usage of the two frameworks is high, with Vue.js being on the rise. The share of Vue.js users grew from 34% in 2020 to 43% in 2021 while React experienced a drop from 64% to 49% in a YoY comparison.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw4o3qddu5hzwi646ulfl.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%2Fw4o3qddu5hzwi646ulfl.png" alt="Jet Brains Dev Ecosystem 2021 survey" width="498" height="376"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Community support
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F64tca6a47xi9t5px36of.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%2F64tca6a47xi9t5px36of.png" alt="React community support" width="800" height="449"&gt;&lt;/a&gt; &lt;br&gt;
One of the most important aspects you should see too is the community support around the framework, this was an issue I slowly realized as I was using Vue throughout the course of this year. I don't really want to talk about this, But the reality is React community is much bigger than Vue's and this is because React is older than Vue so you can find more articles, tutorials, and packages to help you on your React project more than Vue. So in terms of the community support react is the clear winner for me but this does not mean things will stay like this for a long time.&lt;/p&gt;

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

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/HyWYpM_S-2c"&gt;
&lt;/iframe&gt;
&lt;br&gt;
The purpose of this post was not to say that Vue is bad - in fact, during the year and a half time span that I worked with Vue, for the most part, I was quite pleased with it and still believe it to be a fantastic frontend framework. I think that it is an easy framework to learn and a good starting place for new web developers. But this does not mean you should stop learning new things and you really should try to think differently and see other developers' viewpoints.&lt;/p&gt;

&lt;p&gt;Sources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.techmagic.co/blog/why-we-use-react-js-in-the-development/#:%7E:text=React%20is%20a%20JavaScript%20library,js%20is%20virtual%20DOM" rel="noopener noreferrer"&gt;https://www.techmagic.co/blog/why-we-use-react-js-in-the-development/#:~:text=React%20is%20a%20JavaScript%20library,js%20is%20virtual%20DOM&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.jotform.com/blog/7-reasons-why-you-should-use-react/" rel="noopener noreferrer"&gt;https://www.jotform.com/blog/7-reasons-why-you-should-use-react/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>vue</category>
      <category>react</category>
      <category>vscode</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
