<?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: ArseniyDev</title>
    <description>The latest articles on DEV Community by ArseniyDev (@arseniydev).</description>
    <link>https://dev.to/arseniydev</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%2F2844170%2F3d498112-d204-4505-b096-8fabcaeca776.png</url>
      <title>DEV Community: ArseniyDev</title>
      <link>https://dev.to/arseniydev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/arseniydev"/>
    <language>en</language>
    <item>
      <title>How to sync APIs from code with WatchAPI extension</title>
      <dc:creator>ArseniyDev</dc:creator>
      <pubDate>Tue, 20 Jan 2026 09:30:27 +0000</pubDate>
      <link>https://dev.to/arseniydev/how-to-sync-apis-from-code-with-watchapi-extension-1dpd</link>
      <guid>https://dev.to/arseniydev/how-to-sync-apis-from-code-with-watchapi-extension-1dpd</guid>
      <description>&lt;p&gt;Hey devs, I was looking for a tool to get all APIs organized in one place. I used Postman, then Thunder Client, all looks "not that bad". The main problem, aside from pricing and UX, was that you had to define endpoints manually. &lt;/p&gt;

&lt;p&gt;I didn't like this approach because, in the end, I had already written my definitions in code with schema types and interfaces, so why repeat myself? This question led me to build the WatchAPI Client extension that solves just that.&lt;/p&gt;

&lt;p&gt;Here how it works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You install it from &lt;a href="https://open-vsx.org/extension/watchapi/watchapi-client" rel="noopener noreferrer"&gt;open-vsx&lt;/a&gt; or &lt;a href="https://marketplace.visualstudio.com/items?itemName=WatchAPI.watchapi-client" rel="noopener noreferrer"&gt;marketplace&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Open it and press sync, and here we go.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Everything needed been extracted, now how we proceed?&lt;br&gt;
I would check the &lt;code&gt;rest-client.env.json&lt;/code&gt; file that been created, to see if the configuration of &lt;code&gt;baseUrl&lt;/code&gt; is correct, by default it's: port 3000.&lt;/p&gt;

&lt;p&gt;Now to get &lt;code&gt;authToken&lt;/code&gt; we usually run the login endpoint, something like this:&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%2Fofv9mkldhf3w62z0suti.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%2Fofv9mkldhf3w62z0suti.png" alt=" " width="800" height="249"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One thing to note you need &lt;code&gt;REST Client&lt;/code&gt; extension to execute endpoints, and better syntax highlighting.&lt;/p&gt;

&lt;p&gt;From here, you add the token to our: &lt;code&gt;rest-client.env.json&lt;/code&gt; and you can enjoy debugging.&lt;/p&gt;

&lt;p&gt;If you have any questions or issues, feel free to open a ticket below. Thank you.&lt;/p&gt;

</description>
      <category>vscode</category>
      <category>nextjs</category>
      <category>nestjs</category>
      <category>development</category>
    </item>
    <item>
      <title>Claude: Approaching weekly limit.</title>
      <dc:creator>ArseniyDev</dc:creator>
      <pubDate>Tue, 07 Oct 2025 06:42:11 +0000</pubDate>
      <link>https://dev.to/arseniydev/claude-approaching-weekly-limit-15j8</link>
      <guid>https://dev.to/arseniydev/claude-approaching-weekly-limit-15j8</guid>
      <description>&lt;p&gt;If you use Claude for coding, planning, or project work, you might have run into a frustrating problem: &lt;strong&gt;weekly limits stop you from working efficiently&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Top-tier plans aren’t enough
&lt;/h2&gt;

&lt;p&gt;Even on the Max 20x plan, you can hit your weekly limit after just a few hours of focused work. The daily session limits already cap you at 5 hours, so the weekly limit often blocks serious work.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Work gets interrupted
&lt;/h2&gt;

&lt;p&gt;A common workflow might be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Spend a few days making a product plan and breaking it into small tasks.&lt;/li&gt;
&lt;li&gt;Use Claude to generate code or content for each task.&lt;/li&gt;
&lt;li&gt;Review and adjust as needed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With the weekly limit, you might hit the cap in 1-2 days, leaving you &lt;strong&gt;locked out&lt;/strong&gt; for the rest of the week. This is a big problem for bigger projects or prototypes.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. High cost, low value
&lt;/h2&gt;

&lt;p&gt;Top plans can cost hundreds of dollars per month. But if you can’t work when you need to, it doesn’t feel worth it. Pay-as-you-go is an option, but most developers want &lt;strong&gt;continuous access&lt;/strong&gt;, not extra steps or limits.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Limits make planning harder
&lt;/h2&gt;

&lt;p&gt;The daily 5-hour session cap is reasonable, but the weekly cap makes it even harder. Many developers need &lt;strong&gt;8–9 hours of AI-assisted work per day&lt;/strong&gt;. Current limits allow far less, slowing down projects and forcing work to stretch over more days.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this means for developers
&lt;/h2&gt;

&lt;p&gt;If you rely on Claude for planning, coding sprints, or prototyping, weekly limits can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Force you to split work across multiple days.&lt;/li&gt;
&lt;li&gt;Make you switch to other tools mid-project.&lt;/li&gt;
&lt;li&gt;Slow down your projects because AI isn’t available when you need it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  TL;DR
&lt;/h3&gt;

&lt;p&gt;Claude’s weekly limits make it hard for serious developers to get work done, even on top-tier plans. If you use Claude for planning or coding, be aware that your workflow might get blocked before the week is over.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Building GitusAI: An AI-Powered Commit Message Generator</title>
      <dc:creator>ArseniyDev</dc:creator>
      <pubDate>Wed, 01 Oct 2025 20:55:37 +0000</pubDate>
      <link>https://dev.to/arseniydev/building-gitusai-an-ai-powered-commit-message-generator-4a1b</link>
      <guid>https://dev.to/arseniydev/building-gitusai-an-ai-powered-commit-message-generator-4a1b</guid>
      <description>&lt;p&gt;We've all been there - staring at a Git commit dialog, trying to summarize hours of work into a concise, meaningful message. After experiencing this frustration one too many times, I decided to build &lt;strong&gt;&lt;a href="https://gitusai.com" rel="noopener noreferrer"&gt;GitusAI&lt;/a&gt;&lt;/strong&gt;, a VS Code extension that generates clear, professional commit messages automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  🎯 The Problem
&lt;/h2&gt;

&lt;p&gt;Writing good commit messages is hard. They need to be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Concise (under 72 characters for the first line)&lt;/li&gt;
&lt;li&gt;Descriptive (explain the "what" and "why")&lt;/li&gt;
&lt;li&gt;Consistent (follow team conventions like Conventional Commits)&lt;/li&gt;
&lt;li&gt;Professional (no more "fix stuff" or "WIP" messages)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most developers rush through this step, leading to unclear project histories that make debugging and collaboration difficult.&lt;/p&gt;

&lt;h2&gt;
  
  
  💡 The Solution
&lt;/h2&gt;

&lt;p&gt;GitusAI analyzes your staged changes and generates commit messages that are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Smart&lt;/strong&gt;: Uses OpenAI's GPT-3.5 to understand code context&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customizable&lt;/strong&gt;: Supports multiple commit styles (Conventional Commits, emoji commits, regular format)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fast&lt;/strong&gt;: Generates messages in seconds&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integrated&lt;/strong&gt;: Works directly in VS Code's Git panel with one-click insertion&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🏗️ Tech Stack
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Frontend &amp;amp; Landing Page
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Next.js 15&lt;/strong&gt; (App Router with React 19)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TypeScript&lt;/strong&gt; for type safety&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tailwind CSS&lt;/strong&gt; with custom design system&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Radix UI&lt;/strong&gt; for accessible components&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Framer Motion&lt;/strong&gt; for smooth animations&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Backend &amp;amp; API
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Next.js API Routes&lt;/strong&gt; for serverless endpoints&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OpenAI API&lt;/strong&gt; (GPT-3.5-turbo) for AI generation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Drizzle ORM&lt;/strong&gt; with Neon Postgres for data management&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Arctic&lt;/strong&gt; for OAuth (GitHub &amp;amp; Google authentication)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JWT&lt;/strong&gt; for secure token-based auth&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Infrastructure
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cloudflare Workers&lt;/strong&gt; for edge deployment (using @opennextjs/cloudflare)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stripe&lt;/strong&gt; &amp;amp; &lt;strong&gt;LemonSqueezy&lt;/strong&gt; for payment processing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rate limiting&lt;/strong&gt; with usage tracking&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🔨 How I Built It
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. The Core API (&lt;code&gt;src/app/api/commit-generate/route.ts&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;The heart of GitusAI is a Next.js API route that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NextRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// 1. Authenticate the user&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getAuthToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&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;decoded&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;verifyJWT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;// 2. Check rate limits based on plan (Free/Pro)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rateLimitResult&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;checkRateLimit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;decoded&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;decoded&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;plan&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;// 3. Parse the git diff from VS Code&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;changes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;commitStyle&lt;/span&gt; &lt;span class="p"&gt;}&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;request&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;// 4. Generate AI prompt based on commit style&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;systemPrompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;buildSystemPrompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;commitStyle&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;userPrompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;buildUserPrompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;changes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;// 5. Call OpenAI&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="nx"&gt;openai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gpt-3.5-turbo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;messages&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="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;system&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;systemPrompt&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userPrompt&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;// 6. Return the generated message&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&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="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&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;h3&gt;
  
  
  2. Commit Style System
&lt;/h3&gt;

&lt;p&gt;I created a flexible system supporting three commit formats:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;commitConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;functional&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type(scope): description&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;feat&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fix&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;docs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;style&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;refactor&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;test&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;chore&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;icons&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;:emoji: description&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;regular&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type: description&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each style has custom prompts that guide OpenAI to generate appropriate messages:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Functional (Conventional Commits):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;feat(auth): add OAuth2 login integration
fix(api): resolve null pointer in user validation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Icons:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;:sparkles: add new authentication system
:bug: fix memory leak in user cache
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Authentication &amp;amp; Authorization
&lt;/h3&gt;

&lt;p&gt;I implemented a complete auth system using Arctic for OAuth:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// GitHub OAuth setup&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;github&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GitHub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;GITHUB_CLIENT_ID&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;GITHUB_CLIENT_SECRET&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;baseUrl&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/api/auth/callback/github`&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;JWTs are issued on successful login and validated on every API request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;verifyJWT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;JWT_SECRET&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;JWTPayload&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Rate Limiting &amp;amp; Monetization
&lt;/h3&gt;

&lt;p&gt;The platform has tiered pricing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Free&lt;/strong&gt;: 10 commits/day&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pro&lt;/strong&gt; ($5/month): 500 commits/day + custom styles&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enterprise&lt;/strong&gt;: Custom limits + team features&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rate limiting is enforced at the API level:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;checkRateLimit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;plan&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&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;usage&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;getUsageFromDB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&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;limit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;plan&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;free&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;usage&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;limit&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="na"&gt;allowed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Rate limit exceeded&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;upgradeUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/pricing&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;allowed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;remainingCommits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;limit&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;usage&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;h3&gt;
  
  
  5. Cloudflare Edge Deployment
&lt;/h3&gt;

&lt;p&gt;One of the coolest parts is deploying Next.js to Cloudflare Workers for global edge performance:&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;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"deploy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"opennextjs-cloudflare build &amp;amp;&amp;amp; opennextjs-cloudflare deploy"&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;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;This gives users sub-100ms response times worldwide.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Landing Page Design
&lt;/h3&gt;

&lt;p&gt;I built a modern landing page with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hero section with animated background&lt;/li&gt;
&lt;li&gt;Interactive pricing cards with annual/monthly toggle&lt;/li&gt;
&lt;li&gt;FAQ accordion&lt;/li&gt;
&lt;li&gt;Testimonials grid&lt;/li&gt;
&lt;li&gt;CTA sections&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All components are fully responsive and accessible using Radix UI primitives.&lt;/p&gt;

&lt;h2&gt;
  
  
  📊 Challenges &amp;amp; Learnings
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Challenge 1: Prompt Engineering
&lt;/h3&gt;

&lt;p&gt;Getting OpenAI to consistently generate good commit messages required extensive prompt refinement. Key learnings:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Be explicit about format requirements&lt;/li&gt;
&lt;li&gt;Provide multiple examples&lt;/li&gt;
&lt;li&gt;Specify character limits clearly&lt;/li&gt;
&lt;li&gt;Use system prompts for rules, user prompts for context&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Challenge 2: VS Code Integration
&lt;/h3&gt;

&lt;p&gt;Building the VS Code extension required understanding:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;VS Code's Git API&lt;/li&gt;
&lt;li&gt;Extension authentication flows&lt;/li&gt;
&lt;li&gt;One-click commit insertion&lt;/li&gt;
&lt;li&gt;Error handling and user feedback&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Challenge 3: Edge Deployment
&lt;/h3&gt;

&lt;p&gt;Deploying Next.js to Cloudflare Workers had gotchas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Environment variable handling&lt;/li&gt;
&lt;li&gt;Database connections at the edge&lt;/li&gt;
&lt;li&gt;Cold start optimization&lt;/li&gt;
&lt;li&gt;API route compatibility&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🚀 Results
&lt;/h2&gt;

&lt;p&gt;GitusAI is now live and helps developers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Save time on commit messages&lt;/li&gt;
&lt;li&gt;Maintain consistent commit history&lt;/li&gt;
&lt;li&gt;Learn better commit message practices&lt;/li&gt;
&lt;li&gt;Focus on coding instead of documentation&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🔮 What's Next?
&lt;/h2&gt;

&lt;p&gt;Planned features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Team-wide commit style templates&lt;/li&gt;
&lt;li&gt;Multi-repo project support&lt;/li&gt;
&lt;li&gt;Commit history consistency analysis&lt;/li&gt;
&lt;li&gt;Custom AI training on project history&lt;/li&gt;
&lt;li&gt;IDE support beyond VS Code&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🛠️ Try It Yourself
&lt;/h2&gt;

&lt;p&gt;The project is built with modern, developer-friendly tools. Key files to explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;API Handler&lt;/strong&gt;: &lt;code&gt;src/app/api/commit-generate/route.ts&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authentication&lt;/strong&gt;: &lt;code&gt;src/lib/auth.ts&lt;/code&gt; and &lt;code&gt;src/lib/jwt.ts&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rate Limiting&lt;/strong&gt;: &lt;code&gt;src/lib/rate-limit.ts&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database Schema&lt;/strong&gt;: &lt;code&gt;src/lib/schema.ts&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pricing Logic&lt;/strong&gt;: &lt;code&gt;src/components/pricing-section.tsx&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Building GitusAI taught me a lot about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI prompt engineering for production use cases&lt;/li&gt;
&lt;li&gt;Building SaaS with Next.js and Cloudflare&lt;/li&gt;
&lt;li&gt;Creating VS Code extensions&lt;/li&gt;
&lt;li&gt;Implementing auth, payments, and rate limiting&lt;/li&gt;
&lt;li&gt;Designing developer-focused products&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key to success was solving a real problem I experienced daily, validating it with other developers, and building a solution that "just works."&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Want to try GitusAI?&lt;/strong&gt; Check it out on the &lt;a href="https://marketplace.visualstudio.com/items?itemName=GitusAI.gitusai" rel="noopener noreferrer"&gt;VS Code Marketplace&lt;/a&gt; or visit our &lt;a href="https://gitusai.com" rel="noopener noreferrer"&gt;landing page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Have questions about the implementation?&lt;/strong&gt; Drop them in the comments below!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Found this useful?&lt;/strong&gt; Share it with developers who hate writing commit messages! 🚀&lt;/p&gt;

</description>
      <category>ai</category>
      <category>vscode</category>
      <category>typescript</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>Finally, a Database That Actually Listens to You</title>
      <dc:creator>ArseniyDev</dc:creator>
      <pubDate>Thu, 25 Sep 2025 19:23:11 +0000</pubDate>
      <link>https://dev.to/arseniydev/finally-a-database-that-actually-listens-to-you-c89</link>
      <guid>https://dev.to/arseniydev/finally-a-database-that-actually-listens-to-you-c89</guid>
      <description>&lt;p&gt;Remember that moment when you're deep in debugging at 2 AM, staring at a gnarly database schema, and you just want to ask: "Hey DB, which users haven't logged in for the past 30 days?" Instead, you end up crafting some SQL monstrosity, second-guessing your joins, and probably making three syntax errors before you get it right.&lt;/p&gt;

&lt;p&gt;What if I told you there's a tool that lets you literally have a conversation with your database? Meet &lt;a href="https://chatwithdb.com" rel="noopener noreferrer"&gt;ChatWithDB&lt;/a&gt; – and no, it's not just another query builder with a fancy UI.&lt;/p&gt;

&lt;h2&gt;
  
  
  The "Aha!" Moment
&lt;/h2&gt;

&lt;p&gt;Last week, I was helping a junior developer on my team who was struggling with a complex analytics query. You know the drill – multiple tables, date ranges, aggregations, and that special kind of panic that comes with production data.&lt;/p&gt;

&lt;p&gt;Instead of spending 30 minutes walking through SQL syntax, I opened ChatWithDB and typed: "Show me the top 10 customers by revenue in the last quarter, but exclude refunded orders."&lt;/p&gt;

&lt;p&gt;Boom. Perfect query. The junior dev's jaw dropped. Mine did too, honestly.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Makes This Different?
&lt;/h2&gt;

&lt;p&gt;Here's the thing – we've all seen "natural language to SQL" tools before. Most of them work great for demo databases with clean, obvious table names like "customers" and "orders." Real databases? Not so much.&lt;/p&gt;

&lt;p&gt;ChatWithDB actually gets it. It understands your weird legacy column names, your unconventional relationships, and even that one table everyone's afraid to touch (you know the one). The AI learns your database structure and adapts to how your team actually organizes data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real Talk: Where It Shines
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;For the SQL wizards&lt;/strong&gt;: You're still faster at writing complex queries by hand, but ChatWithDB is incredible for exploring unfamiliar schemas or when you need to explain queries to non-technical stakeholders. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For the "I know enough SQL to be dangerous" crowd&lt;/strong&gt;: This is your new best friend. No more copy-pasting from Stack Overflow and hoping for the best.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For data analysts who speak business, not database&lt;/strong&gt;: Finally, you can ask questions the way you think about them, not the way MySQL wants you to think about them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Surprisingly Smooth Setup
&lt;/h2&gt;

&lt;p&gt;I expected the usual database connection nightmare – you know, firewall rules, connection strings, and at least two Slack messages to the DevOps team. &lt;/p&gt;

&lt;p&gt;Nope. Point it at your database (they support all the major ones), and it spends a few minutes learning your schema. That's it. No complex configurations, no agents to install.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Actually Use It For
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Quick data exploration&lt;/strong&gt;: "How many users signed up each month this year?"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sanity checks&lt;/strong&gt;: "Are there any orders without customers?" (There were. Yikes.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Explaining queries to stakeholders&lt;/strong&gt;: The AI can break down complex queries in plain English&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Learning new schemas&lt;/strong&gt;: When I inherited a project with zero documentation (classic), ChatWithDB helped me understand what everything actually meant&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Honest Drawbacks
&lt;/h2&gt;

&lt;p&gt;Look, it's not perfect. Sometimes it gets confused by really complex business logic or heavily normalized schemas. And if your database is a complete disaster with no naming conventions... well, even AI has limits.&lt;/p&gt;

&lt;p&gt;But here's what I appreciate: when it's not sure about something, it asks. It doesn't just guess and give you wrong results.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Matters for Our Industry
&lt;/h2&gt;

&lt;p&gt;We spend way too much time translating between "what the business wants to know" and "how the database stores that information." Tools like ChatWithDB aren't replacing SQL skills – they're removing the friction that keeps good developers away from data exploration.&lt;/p&gt;

&lt;p&gt;Plus, let's be honest: how many times have you written the same basic queries over and over? Why not just ask for what you want?&lt;/p&gt;

&lt;h2&gt;
  
  
  Give It a Shot
&lt;/h2&gt;

&lt;p&gt;If you're curious, &lt;a href="https://chatwithdb.com" rel="noopener noreferrer"&gt;ChatWithDB&lt;/a&gt; has a free tier that's perfect for trying it out on a test database. Even if you're a SQL ninja, it's worth seeing how it interprets your schema.&lt;/p&gt;

&lt;p&gt;And if you're teaching someone SQL or working with non-technical team members who need data insights, this tool might just save your sanity.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Have you tried any AI-powered database tools? What's been your experience with natural language queries? Drop a comment – I'm genuinely curious about what's working (or not working) for other developers.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>database</category>
      <category>sql</category>
      <category>ai</category>
      <category>startup</category>
    </item>
    <item>
      <title>Stop Writing SQL by Hand: Building My MVP to Chat With Databases</title>
      <dc:creator>ArseniyDev</dc:creator>
      <pubDate>Thu, 11 Sep 2025 19:29:36 +0000</pubDate>
      <link>https://dev.to/arseniydev/stop-writing-sql-by-hand-building-my-mvp-to-chat-with-databases-3fhg</link>
      <guid>https://dev.to/arseniydev/stop-writing-sql-by-hand-building-my-mvp-to-chat-with-databases-3fhg</guid>
      <description>&lt;p&gt;As developers, we all end up writing SQL queries — sometimes simple, sometimes painfully complex.&lt;br&gt;
But I kept asking myself:&lt;/p&gt;

&lt;p&gt;👉 &lt;em&gt;Why do I have to think in SQL when my brain is already thinking in English?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That’s what led me to build my latest side project: &lt;strong&gt;ChatWithDB&lt;/strong&gt;, an MVP that lets you connect to your database and just… talk to it.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;SQL is powerful, but not everyone on a team is fluent in it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Product managers just want numbers.&lt;/li&gt;
&lt;li&gt;Analysts want insights without fighting syntax.&lt;/li&gt;
&lt;li&gt;Even developers sometimes waste time debugging queries instead of focusing on features.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And when you finally get the data, you often want to visualize it quickly.&lt;/p&gt;




&lt;h2&gt;
  
  
  My Approach
&lt;/h2&gt;

&lt;p&gt;Instead of building a heavy “end-to-end AI analytics platform,” I wanted something &lt;strong&gt;light and fast&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Connect your DB&lt;/strong&gt; (Postgres/MySQL first).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ask in natural language&lt;/strong&gt; → “Show me daily signups in the last 30 days.”&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Get SQL + results instantly.&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No extra modeling. No complex setup. Just query → answer.&lt;/p&gt;




&lt;h2&gt;
  
  
  Lessons Learned While Building
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Speed matters&lt;/strong&gt;: People lose trust if the model takes forever to respond.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Schema awareness is tricky&lt;/strong&gt;: LLMs need context, but too much context slows things down.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UI simplicity wins&lt;/strong&gt;: If it feels like ChatGPT, adoption is easier.&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;Right now, I’m testing whether a &lt;em&gt;lighter approach&lt;/em&gt; (fast responses, no over-engineering) is more valuable than big enterprise-style systems.&lt;/p&gt;

&lt;p&gt;I’d love feedback:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Would you prefer a &lt;strong&gt;quick tool that handles 80% of your queries fast&lt;/strong&gt;?&lt;/li&gt;
&lt;li&gt;Or a &lt;strong&gt;heavier system&lt;/strong&gt; that tries to cover every possible edge case?&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;(If you’re curious, I’m hacking on this at [ChatWithDB](&lt;a href="https://chatwithdb.com" rel="noopener noreferrer"&gt;https://chatwithdb.com&lt;/a&gt;), still super early but feedback is welcome.)&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>database</category>
      <category>ai</category>
      <category>sql</category>
      <category>saas</category>
    </item>
    <item>
      <title>Why Knowing CMS Can Make You a More Valuable Developer</title>
      <dc:creator>ArseniyDev</dc:creator>
      <pubDate>Mon, 31 Mar 2025 08:53:00 +0000</pubDate>
      <link>https://dev.to/arseniydev/why-knowing-cms-can-make-you-a-more-valuable-developer-3e2n</link>
      <guid>https://dev.to/arseniydev/why-knowing-cms-can-make-you-a-more-valuable-developer-3e2n</guid>
      <description>&lt;p&gt;Imagine this: You apply for a developer job, and during the interview, the hiring manager asks, "Have you ever worked with a CMS?" You hesitate. Maybe you've focused on building applications from scratch, writing custom APIs, or mastering JavaScript frameworks like Next.js or React. But the truth is, CMS experience is becoming more valuable than ever.&lt;/p&gt;

&lt;p&gt;In today’s tech landscape, no-code and low-code platforms are rising in popularity. Businesses are moving fast, and instead of reinventing the wheel, many startups and enterprises rely on CMS solutions to handle content, eCommerce, and even complex workflows. As a developer, this means two things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You’ll likely need to work alongside no-code tools.&lt;/li&gt;
&lt;li&gt;Sooner or later, you might be the one migrating a project from a no-code platform to a custom-built solution.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Why Payload CMS Stands Out
&lt;/h3&gt;

&lt;p&gt;While platforms like WordPress and Shopify dominate the CMS world, modern developers need more flexible and developer-friendly alternatives. This is where &lt;strong&gt;Payload CMS&lt;/strong&gt; shines.&lt;/p&gt;

&lt;p&gt;Payload is a headless CMS built on Node.js that gives you full control over your backend while maintaining a powerful admin panel for non-technical users. Unlike traditional CMSs, it’s designed for developers who want to customize everything without being limited by rigid structures. With Payload, you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Define custom collections and relationships using JavaScript/TypeScript.&lt;/li&gt;
&lt;li&gt;Store content in a database of your choice (PostgreSQL, MongoDB, etc.).&lt;/li&gt;
&lt;li&gt;Integrate with modern frontends like Next.js easily.&lt;/li&gt;
&lt;li&gt;Extend functionalities with custom plugins.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  A Practical Example: ShopNex - A Fully Customizable eCommerce CMS
&lt;/h3&gt;

&lt;p&gt;If you're looking to showcase your CMS expertise, eCommerce is one of the most in-demand areas. &lt;strong&gt;ShopNex&lt;/strong&gt; (&lt;a href="https://github.com/shopnex-ai/shopnex" rel="noopener noreferrer"&gt;https://github.com/shopnex-ai/shopnex&lt;/a&gt;) is an open-source template built with Payload CMS that enables developers to create fully customizable online stores.&lt;/p&gt;

&lt;p&gt;With ShopNex, you get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A modern eCommerce backend powered by Payload CMS.&lt;/li&gt;
&lt;li&gt;Complete control over product management, orders, and customer data.&lt;/li&gt;
&lt;li&gt;The ability to extend and modify the platform as needed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By understanding how Payload works and leveraging solutions like ShopNex, you not only improve your CMS skills but also position yourself as a developer who can bridge the gap between low-code and fully custom solutions—something hiring managers are actively looking for.&lt;/p&gt;

&lt;h3&gt;
  
  
  Final Thoughts
&lt;/h3&gt;

&lt;p&gt;The rise of no-code and CMS solutions isn’t a threat to developers—it’s an opportunity. Companies still need skilled engineers who can work with these tools, migrate projects when necessary, and customize them to fit business needs. If you’re looking to stand out in the job market, adding CMS expertise—especially with modern solutions like Payload—can give you a competitive edge.&lt;/p&gt;

&lt;p&gt;What are your thoughts on working with CMSs? Have you explored Payload or other developer-friendly CMS options? Let’s discuss in the comments!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>beginners</category>
      <category>productivity</category>
    </item>
    <item>
      <title>After 5 Years of Coding, I Switched to a CMS – Here's Why</title>
      <dc:creator>ArseniyDev</dc:creator>
      <pubDate>Mon, 24 Mar 2025 13:50:44 +0000</pubDate>
      <link>https://dev.to/arseniydev/after-5-years-of-coding-i-switched-to-a-cms-heres-why-173j</link>
      <guid>https://dev.to/arseniydev/after-5-years-of-coding-i-switched-to-a-cms-heres-why-173j</guid>
      <description>&lt;h2&gt;
  
  
  My Journey in the Node.js and React/Next.js Stack
&lt;/h2&gt;

&lt;p&gt;For the past five years, I have been deeply involved in full-stack development using Node.js, React, and Next.js. I built various applications, from simple Saas applications to complex eCommerce platforms. While working with these technologies, I realized that a significant amount of my time was being spent on repetitive tasks—writing boilerplate code, setting up CRUD operations, and defining schemas and types over and over again.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem: Wasting Time on Boilerplate Code
&lt;/h2&gt;

&lt;p&gt;When I analyzed my workflow, I found that 80-90% of my development time was spent on things that didn’t add direct value to the product itself. Setting up authentication, structuring API routes, and defining database schemas became a tedious and time-consuming process. This inefficiency was not just slowing down development but also affecting productivity and innovation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Discovering Payload CMS
&lt;/h2&gt;

&lt;p&gt;While searching for ways to optimize my workflow, I came across Payload CMS. It’s a modern headless CMS built on Node.js and TypeScript that allows developers to focus on building products rather than reinventing the wheel. What caught my attention was its flexibility—Payload provides full control over the database, authentication, and APIs without unnecessary complexity.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Payload CMS Reduces Boilerplate
&lt;/h2&gt;

&lt;p&gt;Payload simplifies CRUD operations, authentication, and API handling with minimal setup. Instead of manually defining schemas and API endpoints, Payload allows you to define collections, relationships, and access control in a structured way. This eliminates a large chunk of repetitive work and lets developers focus on building the actual business logic.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example: Traditional API vs. Payload CMS
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Without Payload CMS (Manual Approach):&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Define database schemas in PostgreSQL or MongoDB.&lt;/li&gt;
&lt;li&gt;Write models using an ORM like Drizzle or Prisma.&lt;/li&gt;
&lt;li&gt;Create API routes for CRUD operations.&lt;/li&gt;
&lt;li&gt;Implement authentication and permissions manually.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;With Payload CMS:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Define a collection in a simple configuration file.&lt;/li&gt;
&lt;li&gt;Authentication and access control are built-in.&lt;/li&gt;
&lt;li&gt;API endpoints are automatically generated.&lt;/li&gt;
&lt;li&gt;Hooks allow for custom business logic without unnecessary complexity.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Using Payload CMS for eCommerce – ShopNex Example
&lt;/h2&gt;

&lt;p&gt;To put Payload CMS to the test, I decided to use it for an eCommerce project. I'm using ShopNex, an open-source eCommerce template built on Payload CMS. Here’s how you can set it up:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Clone the Repository and install dependencies.
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone git@github.com:shopnex-ai/shopnex.git
&lt;span class="nb"&gt;cd &lt;/span&gt;shopnex
pnpm i
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Configure Environment Variables
&lt;/h3&gt;

&lt;p&gt;Rename .env.example to .env and update the necessary configurations such as the database URL, authentication settings, and API keys.&lt;/p&gt;

&lt;p&gt;CJ_CONFIGURATIONS is optional.&lt;/p&gt;

&lt;p&gt;PAYLOAD_SECRET should be a random string used for encryption.&lt;/p&gt;

&lt;p&gt;DATABASE_URI is the database connection string. You can use SQLite or PostgreSQL (you will need to use postgresAdapter for postgres).&lt;/p&gt;

&lt;p&gt;You can find these configurations in &lt;code&gt;payload.config.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;sqliteAdapter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DATABASE_URI&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Run the code
&lt;/h3&gt;



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

&lt;/div&gt;



&lt;p&gt;When your app is up and running, you can explore it using the following links:&lt;/p&gt;

&lt;p&gt;Storefront: &lt;a href="http://localhost:3000/" rel="noopener noreferrer"&gt;http://localhost:3000/&lt;/a&gt; – This is the main store interface. We'll return to it later.&lt;/p&gt;

&lt;p&gt;Admin Panel: &lt;a href="http://localhost:3000/admin" rel="noopener noreferrer"&gt;http://localhost:3000/admin&lt;/a&gt; – This is where you can configure your storefront.&lt;/p&gt;

&lt;p&gt;Start by visiting &lt;a href="http://localhost:3000/admin" rel="noopener noreferrer"&gt;http://localhost:3000/admin&lt;/a&gt;. The first time you access it, you'll be prompted to create a user account. Once that's done, you'll be taken to the dashboard, where you can manage all configurations.&lt;/p&gt;

&lt;p&gt;The first step is to ensure everything is working correctly. Let's navigate to the Hero section and add some content.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9stoi4y73e1bnhzlmkfd.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%2F9stoi4y73e1bnhzlmkfd.png" alt=" " width="800" height="456"&gt;&lt;/a&gt;&lt;br&gt;
Once you're done, save your changes and visit &lt;a href="http://localhost:3000/" rel="noopener noreferrer"&gt;http://localhost:3000/&lt;/a&gt; to see the updates.&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%2F5y8r5iylwwa56ywtjdzr.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%2F5y8r5iylwwa56ywtjdzr.png" alt=" " width="800" height="351"&gt;&lt;/a&gt;&lt;br&gt;
To illustrate power of Payload CMS you can go to the Products.tsx and notice every field has own purpose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Products&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CollectionConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Unique identifier for the collection&lt;/span&gt;
    &lt;span class="na"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;products&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="c1"&gt;// Access control: Only admins can create, update, and delete; anyone can read&lt;/span&gt;
    &lt;span class="na"&gt;access&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;admins&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;admins&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;read&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;anyone&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;update&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;admins&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;

    &lt;span class="na"&gt;admin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Field to use as the title in the admin panel&lt;/span&gt;
        &lt;span class="na"&gt;useAsTitle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

        &lt;span class="c1"&gt;// Organizing the collection under a specific group&lt;/span&gt;
        &lt;span class="na"&gt;group&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;groups&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;catalog&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

        &lt;span class="c1"&gt;// Default columns shown in the admin panel&lt;/span&gt;
        &lt;span class="na"&gt;defaultColumns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;variants&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;collections&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;

    &lt;span class="na"&gt;hooks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;beforeRead&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&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;doc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// Fetch global store settings to retrieve the currency&lt;/span&gt;
                &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;storeSettings&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;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findGlobal&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                    &lt;span class="na"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;store-settings&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="p"&gt;});&lt;/span&gt;

                &lt;span class="c1"&gt;// Assign the currency from store settings to the product document&lt;/span&gt;
                &lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currency&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;storeSettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currency&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="p"&gt;},&lt;/span&gt;

    &lt;span class="na"&gt;fields&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;// Product ID from supplier side, disabled in the admin&lt;/span&gt;
            &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pid&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;admin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="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;// Product title, required field&lt;/span&gt;
            &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Currency field, auto-filled from store settings and disabled in admin&lt;/span&gt;
            &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;currency&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;admin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="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;// Checkbox to control product visibility in the store&lt;/span&gt;
            &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Visibility&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;visible&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;checkbox&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;admin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sidebar&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Displayed in the sidebar&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="na"&gt;defaultValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Default visibility is enabled&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;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Payload CMS has significantly improved my development workflow, allowing me to focus on building features instead of writing boilerplate code. Whether you’re working on an eCommerce site, a SaaS product, or any other web application, Payload can help streamline your development process.&lt;/p&gt;

&lt;p&gt;Have any questions or thoughts? Drop a comment below, and let’s discuss!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>tutorial</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Tired of Shopify? Build and launch your own eCommerce platform in seconds!</title>
      <dc:creator>ArseniyDev</dc:creator>
      <pubDate>Mon, 17 Mar 2025 16:02:41 +0000</pubDate>
      <link>https://dev.to/arseniydev/tired-of-shopify-build-and-launch-your-own-ecommerce-platform-in-seconds-16jp</link>
      <guid>https://dev.to/arseniydev/tired-of-shopify-build-and-launch-your-own-ecommerce-platform-in-seconds-16jp</guid>
      <description>&lt;p&gt;Shopify has been the go-to solution for eCommerce for years, but as a developer, I’ve always wanted more flexibility. While it’s great for non-technical users, it comes with high fees, limited customization, and vendor lock-in.&lt;/p&gt;

&lt;p&gt;I’ve spent years working in eCommerce, building stores and platforms using various commercial and open-source solutions. I’ve worked with:&lt;/p&gt;

&lt;p&gt;Commercial platforms – Shopify, Wix, OpenCart.&lt;br&gt;
Open-source solutions – Medusa.js, Magento, Saleor, Vendure, and others.&lt;br&gt;
Each of these has strengths, but I often ran into limitations—either they were too restrictive, too complex, or lacked modern developer experience.&lt;/p&gt;

&lt;p&gt;That’s why I decided to build my own eCommerce template using Payload CMS. In just three days, I had a fully functional store, complete with Stripe payments and CJ Dropshipping integration. Here’s how I did it.&lt;/p&gt;

&lt;p&gt;Why Payload CMS?&lt;br&gt;
eCommerce platforms are, by design, mostly static. Products don’t change often, and performance is crucial. A headless CMS like Payload is a great fit because it:&lt;/p&gt;

&lt;p&gt;✅ Has a modern, clean admin panel – Easy to manage products, orders, and settings.&lt;br&gt;
✅ Gives full control over API and integrations – Unlike Shopify, you’re not limited to what they allow.&lt;br&gt;
✅ Self-hosted and open-source – No monthly fees, no vendor lock-in.&lt;/p&gt;

&lt;p&gt;For a developer, Payload CMS gives you the freedom to build an eCommerce platform your way—without the restrictions of SaaS solutions.&lt;/p&gt;

&lt;p&gt;Building the E-Commerce Template&lt;br&gt;
With Payload CMS as the backend, I structured my eCommerce solution like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Product Management
Custom product schema with support for variations, images, and metadata.
Easy-to-use admin panel to add and edit products.&lt;/li&gt;
&lt;li&gt;Checkout &amp;amp; Payments (Stripe)
Integrated Stripe for a smooth checkout process.
Supports one-time payments and subscriptions.&lt;/li&gt;
&lt;li&gt;Dropshipping (CJ Dropshipping)
API integration with CJ Dropshipping to import products dynamically.
Automated order fulfillment, reducing manual work.&lt;/li&gt;
&lt;li&gt;Optimized Frontend
Built with Next.js for performance and SEO benefits.
Static rendering for speed, with dynamic checkout logic.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;What’s Next?&lt;br&gt;
With this setup, I can launch multiple stores, customize them however I want, and avoid the limitations of Shopify or other SaaS platforms.&lt;/p&gt;

&lt;p&gt;What Do You Think?&lt;br&gt;
Would you consider building your own eCommerce platform instead of relying on Shopify? Have you tried Payload CMS for eCommerce?&lt;/p&gt;

&lt;p&gt;Let’s discuss in the comments! 🚀&lt;/p&gt;

&lt;p&gt;If you're interested in trying this out, I’ve open-sourced the template! You can find it here:&lt;br&gt;
&lt;a href="https://github.com/shoplyjs/shopload" rel="noopener noreferrer"&gt;🔗 GitHub Repository&lt;/a&gt;&lt;br&gt;
Feel free to star it, contribute, or give feedback!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>opensource</category>
      <category>node</category>
    </item>
    <item>
      <title>Say Goodbye to If-Else Chaos – Feature Flags for Everyone</title>
      <dc:creator>ArseniyDev</dc:creator>
      <pubDate>Sun, 16 Feb 2025 18:27:33 +0000</pubDate>
      <link>https://dev.to/arseniydev/say-goodbye-to-if-else-chaos-feature-flags-for-everyone-4p2p</link>
      <guid>https://dev.to/arseniydev/say-goodbye-to-if-else-chaos-feature-flags-for-everyone-4p2p</guid>
      <description>&lt;p&gt;If you’ve ever tried rolling out a new feature in a React app, you know the drill. You add a bunch of &lt;code&gt;if-else&lt;/code&gt; statements, check environment variables, or maybe even maintain separate branches for different versions. It’s messy, error-prone, and worst of all—it doesn’t scale.  &lt;/p&gt;

&lt;p&gt;Meanwhile, big tech companies use feature flags to make these problems disappear. They roll out new features gradually, run A/B tests effortlessly, and toggle features on or off without redeploying. But if you're a startup or a solo developer, implementing feature flags yourself feels like overkill.  &lt;/p&gt;

&lt;p&gt;That’s exactly why we built &lt;strong&gt;FlagSwitch React&lt;/strong&gt;—to bring powerful, enterprise-level feature management to &lt;em&gt;everyone&lt;/em&gt;. And the best part? &lt;strong&gt;You don’t need if-else statements, and it works with just a single import.&lt;/strong&gt;  &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;One Import. No If-Else. Infinite Flexibility.&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Imagine this: instead of writing convoluted logic like this—&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;NewCheckout&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./NewCheckout&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;OldCheckout&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./OldCheckout&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isFeatureEnabled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;VITE_FEATURES&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CheckoutFlow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Checkout&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;isFeatureEnabled&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NewCheckout&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;OldCheckout&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;—you just &lt;strong&gt;import and call one function&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&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;flagSwitch&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="s2"&gt;flagswitch-react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// ./flag-switch.ts&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;loadFeatures&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;flagSwitch&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;features&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;CheckoutFlow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;split&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;MultiStepCheckout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;SingleStepCheckout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;70&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="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// ./index.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;loadFeatures&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="s2"&gt;./flag-switch&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CheckoutFlow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;loadFeatures&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;CheckoutFlow&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Boom. No environment variables, no conditional rendering, no spaghetti code. Just clean, maintainable feature toggling that works right out of the box.  &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Feature Flags Without the Overhead&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;With &lt;strong&gt;FlagSwitch React&lt;/strong&gt;, you can:  &lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Roll out features gradually&lt;/strong&gt; – Control what percentage of users see a new feature.&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;A/B test different versions&lt;/strong&gt; – Let users experience multiple UI variations without extra work.&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Avoid breaking production&lt;/strong&gt; – Instantly disable a buggy feature without redeploying.&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Stay flexible&lt;/strong&gt; – Override versions manually or let the system decide dynamically.  &lt;/p&gt;

&lt;p&gt;All of this happens automatically behind the scenes. No need to refactor your app, write complex logic, or set up a backend just for feature management.  &lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Flexible Yet Stupidly Simple&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Need global settings? No problem. You can tweak &lt;strong&gt;FlagSwitch React&lt;/strong&gt; to work exactly the way you want:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;loadFeatures&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;flagSwitch&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;features&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;VITE_FEATURES&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="c1"&gt;// Other global options can be defined here.&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or if you just want to force a feature for testing, that’s just one line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;loadFeatures&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;single-step-checkout&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Feature Flags Are No Longer Just for Big Tech&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;For too long, feature flags and A/B testing have been seen as tools reserved for large enterprises with dedicated DevOps teams. But that’s changing. &lt;strong&gt;With FlagSwitch React, you get all the power of feature flags with none of the complexity.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;No more conditional logic. No more painful rollouts. No more guessing what works.  &lt;/p&gt;

&lt;p&gt;Just &lt;strong&gt;import, define, and deploy&lt;/strong&gt;—it’s that easy.  &lt;/p&gt;

&lt;p&gt;Ready to ship features like the pros? Install now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;flagswitch-react
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🚀 &lt;strong&gt;Try it out today and take control of your React app!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>programming</category>
      <category>productivity</category>
      <category>product</category>
    </item>
  </channel>
</rss>
