<?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: Jay-Em</title>
    <description>The latest articles on DEV Community by Jay-Em (@joshmatthew).</description>
    <link>https://dev.to/joshmatthew</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F479268%2Fd1c72509-437e-45ba-b1a9-e8fd700bf4e9.jpeg</url>
      <title>DEV Community: Jay-Em</title>
      <link>https://dev.to/joshmatthew</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/joshmatthew"/>
    <language>en</language>
    <item>
      <title>neovim-final-final: Why I Can't Stop Tinkering With My Dev Environment (And Why That's Okay)</title>
      <dc:creator>Jay-Em</dc:creator>
      <pubDate>Fri, 05 Jun 2026 19:13:33 +0000</pubDate>
      <link>https://dev.to/joshmatthew/neovim-final-final-why-i-cant-stop-tinkering-with-my-dev-environment-and-why-thats-okay-3576</link>
      <guid>https://dev.to/joshmatthew/neovim-final-final-why-i-cant-stop-tinkering-with-my-dev-environment-and-why-thats-okay-3576</guid>
      <description>&lt;p&gt;Let me paint you a picture.&lt;/p&gt;

&lt;p&gt;It's a perfectly good Saturday afternoon. You had &lt;em&gt;plans&lt;/em&gt;. Real plans. Maybe you were going to finish that side project, maybe finally write some tests (lol), or at the very least touch grass for twenty minutes.&lt;/p&gt;

&lt;p&gt;Instead, you're 4 hours deep into your Neovim config, you've rewritten your &lt;code&gt;keymaps.lua&lt;/code&gt; for the third time this month, your &lt;code&gt;lazy.nvim&lt;/code&gt; plugin list has grown by six plugins you don't fully understand yet, and your repo—God help you—is named &lt;code&gt;neovim-final-final&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Not &lt;code&gt;neovim-config&lt;/code&gt;. Not &lt;code&gt;dotfiles&lt;/code&gt;. &lt;strong&gt;&lt;code&gt;neovim-final-final&lt;/code&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Because the one before it was &lt;em&gt;final&lt;/em&gt;, and that was a lie, and you knew it was a lie when you named it, and you did it anyway.&lt;/p&gt;

&lt;p&gt;Hi. My name is Josh, and I have a configuration problem. I'm not in recovery.&lt;/p&gt;




&lt;h2&gt;
  
  
  "Just Use VS Code" — A Eulogy
&lt;/h2&gt;

&lt;p&gt;I did use VS Code. For a long time, actually. It's fine. It's great, even. It has extensions for everything, it works out of the box.&lt;/p&gt;

&lt;p&gt;But at some point, something shifted. I'd be in the middle of coding and I'd think: &lt;em&gt;this editor doesn't feel like mine&lt;/em&gt;. It felt like renting an apartment versus owning a house. Everything worked, but none of it was &lt;em&gt;mine&lt;/em&gt;. I couldn't knock down a wall. I couldn't rewire the kitchen. The landlord (Microsoft) was always one update away from rearranging the furniture while I slept.&lt;/p&gt;

&lt;p&gt;So I did what any completely normal, well-adjusted developer does.&lt;/p&gt;

&lt;p&gt;I nuked it. Installed Neovim. And fell into a rabbit hole I haven't climbed out of since.&lt;/p&gt;

&lt;p&gt;Credit where it's due: a big part of what pushed me over the edge was &lt;a href="https://www.youtube.com/@ThePrimeagen" rel="noopener noreferrer"&gt;ThePrimeagen&lt;/a&gt;. If you've never watched him, he's a developer who moves through code so fast it looks illegal, and he does it all in Neovim. Watching him work made me feel like I was using a tricycle when I could be riding a motorcycle. He didn't just inspire me to switch editors — he inspired me to &lt;em&gt;tinker&lt;/em&gt;. To care about the tools. To never just accept the defaults.&lt;/p&gt;




&lt;h2&gt;
  
  
  The First Config Is Always a Disaster (And That's the Point)
&lt;/h2&gt;

&lt;p&gt;Here's what nobody tells you about switching to Neovim: &lt;strong&gt;the first week is a humbling experience.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Honestly, my first encounter with Vim wasn't even intentional. I made a &lt;code&gt;git commit&lt;/code&gt; without the &lt;code&gt;-m&lt;/code&gt; flag, and suddenly I was staring at a screen I did not ask for. I had no idea what it was. I just knew I was stuck. Couldn't type, couldn't exit, couldn't do anything. I literally Googled "stuck in commit can't exit" — not even "how to exit vim" — because I didn't even know it &lt;em&gt;was&lt;/em&gt; Vim. That Stack Overflow question with 2 million views? I am one of those 2 million people.&lt;/p&gt;

&lt;p&gt;And yet, somehow, that cursed moment planted a seed.&lt;/p&gt;

&lt;p&gt;Fast forward to actually switching to Neovim full time: you forget how to save files. You accidentally enter some mode you've never seen before and the only way out is to close the terminal and pretend it never happened.&lt;/p&gt;

&lt;p&gt;But then something clicks. You learn that every single thing—every keybind, every behavior, every color on your screen—is a &lt;em&gt;choice you made&lt;/em&gt;. Nobody pre-packaged it for you. When your LSP starts working and Telescope fuzzy-finds a file in 0.1 seconds and your statusline shows exactly the info you care about and nothing else...&lt;/p&gt;

&lt;p&gt;That feeling? That's ownership. That's craftsmanship. That's the closest thing a programmer gets to carving their name into something.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Configs That Taught Me More Than Any Tutorial
&lt;/h2&gt;

&lt;p&gt;Here's the dirty secret about tinkering with your dev environment: &lt;strong&gt;it's not actually about the tools.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sure, I love my &lt;code&gt;which-key&lt;/code&gt; setup. I love that I've bound &lt;code&gt;&amp;lt;leader&amp;gt;\&lt;/code&gt; to Telescope and &lt;code&gt;&amp;lt;leader&amp;gt;gg&lt;/code&gt; to NeoGit and my fingers just &lt;em&gt;know&lt;/em&gt; where to go without thinking. I love that my Neovim is fast—genuinely, disgustingly fast—in a way that VS Code on a good day can only dream about.&lt;/p&gt;

&lt;p&gt;But what I actually &lt;em&gt;learned&lt;/em&gt; from all of this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How Lua works&lt;/strong&gt;, because your Neovim config is just a Lua program. You are literally programming your editor.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;How LSPs work&lt;/strong&gt;—like, actually work. What a language server protocol &lt;em&gt;is&lt;/em&gt;, why it exists, what &lt;code&gt;mason.nvim&lt;/code&gt; is doing when it installs one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;How terminal multiplexing works&lt;/strong&gt;, because once you go Neovim you inevitably end up in Tmux, splitting panes, managing sessions, and feeling like a wizard in a movie about hackers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;How to read documentation&lt;/strong&gt;, because Neovim will teach you patience or it will break you. There is no middle ground.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of that came from a course. It came from breaking things, reading the source code of plugins at 1 AM, and occasionally nuking the whole config and starting over.&lt;/p&gt;

&lt;p&gt;Which brings me to something important.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Nuclear Option Is Not Failure. It's a Feature.
&lt;/h2&gt;

&lt;p&gt;I've deleted my Neovim config and started from scratch multiple times.&lt;/p&gt;

&lt;p&gt;Every time, I told myself &lt;em&gt;this is the final one&lt;/em&gt;. Every time, I was wrong. Hence: &lt;code&gt;neovim-final-final&lt;/code&gt;. (Spoiler: there will be a &lt;code&gt;neovim-final-final-v2&lt;/code&gt;. I've made my peace with this.)&lt;/p&gt;

&lt;p&gt;And you know what? Each restart made my config &lt;em&gt;better&lt;/em&gt;. Because I stopped copying configurations I found online wholesale and started understanding &lt;em&gt;why&lt;/em&gt; things were structured a certain way. I stopped installing plugins because some YouTuber had them and started asking "do I actually need this, or does it just look cool in a demo?"&lt;/p&gt;

&lt;p&gt;The tinkering &lt;em&gt;is&lt;/em&gt; the learning. The mess &lt;em&gt;is&lt;/em&gt; the process.&lt;/p&gt;

&lt;p&gt;There's a certain type of programmer who looks at someone like me and says "that's a waste of time, just use the defaults." And look, I get it. Pragmatism is a virtue.&lt;/p&gt;

&lt;p&gt;But there's something those programmers are missing: &lt;strong&gt;the act of configuring your environment forces you to understand it.&lt;/strong&gt; You can't set up an LSP without learning what an LSP is. You can't write a keymap without thinking about your own workflow. You can't structure a Lua config without picking up at least some programming instincts.&lt;/p&gt;

&lt;p&gt;Tinkerers aren't wasting time. They're learning sideways.&lt;/p&gt;




&lt;h2&gt;
  
  
  Tmux: The Part Where I Become Insufferable at Screen Shares
&lt;/h2&gt;

&lt;p&gt;I need to talk about Tmux for a second.&lt;/p&gt;

&lt;p&gt;Tmux is a terminal multiplexer, which is a fancy way of saying "multiple terminals in one terminal, with sessions that persist even when you close everything." It sounds niche. It sounds unnecessary. Every person I've shown it to in a screen share has said some variation of "wait, what just happened" followed by either genuine curiosity or quiet concern for my mental health.&lt;/p&gt;

&lt;p&gt;I love it.&lt;/p&gt;

&lt;p&gt;I have a Tmux session for every project. I detach, I reattach, I split panes horizontally and run my dev server on one side and my Neovim on the other. My workflow is a single terminal window and nothing else. No alt-tabbing. No losing focus. Just me, my keyboard, and a black screen full of text that somehow builds web applications.&lt;/p&gt;

&lt;p&gt;Is this more efficient than having a normal setup? Genuinely, yes. I think so.&lt;/p&gt;

&lt;p&gt;Is part of the appeal that it looks like I'm doing something extremely technical and impressive at all times? &lt;/p&gt;

&lt;p&gt;...also yes. I'm not a saint.&lt;/p&gt;

&lt;p&gt;There's also this other thing that happens during screen shares that I didn't expect: occasionally, someone will see my setup and just &lt;em&gt;light up&lt;/em&gt;. Not confusion — recognition. They'll say something like "wait, are you using Neovim and Tmux?" and suddenly we're talking like old friends. It's happened with developers I've never met before, halfway across the world — and as a Filipino working remotely, that moment of unexpected connection hits different. It's like stumbling into a secret club. The terminal is the handshake. It's a small community, but it's ours.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why You Should Try It (Even If You Don't Stick With It)
&lt;/h2&gt;

&lt;p&gt;Here's my honest take: &lt;strong&gt;you don't have to use Neovim or Tmux forever.&lt;/strong&gt; You don't have to commit. You don't have to throw away VS Code or Cursor or whatever IDE is paying your rent right now.&lt;/p&gt;

&lt;p&gt;But you should tinker with &lt;em&gt;something&lt;/em&gt; outside your comfort zone. Configure something from scratch. Break it. Fix it. Break it again. Name the repo something embarrassing like &lt;code&gt;neovim-final-final&lt;/code&gt; because that's just the natural endpoint of caring about your tools.&lt;/p&gt;

&lt;p&gt;Because here's what I've found: &lt;strong&gt;programmers who understand their environment write better code.&lt;/strong&gt; Not because Vim makes you smarter (it doesn't, I've tested this on myself), but because the curiosity that drives you to customize your editor is the same curiosity that drives you to understand your codebase. It's the same instinct.&lt;/p&gt;

&lt;p&gt;The tinkerers are the ones who ask "why does this work this way?" instead of accepting it.&lt;/p&gt;

&lt;p&gt;And that question—&lt;em&gt;why does this work this way?&lt;/em&gt;—is the most important question in this entire profession.&lt;/p&gt;




&lt;h2&gt;
  
  
  Go Break Your Config
&lt;/h2&gt;

&lt;p&gt;Stop using default settings for everything (unless you have a deadline, in which case: godspeed, use VS Code, no judgment).&lt;/p&gt;

&lt;p&gt;But when you have a free Saturday? Crack open a Neovim config. Spend four hours on a keymap. Name the repo something ridiculous. Feel the specific joy of your editor doing &lt;em&gt;exactly&lt;/em&gt; what you want it to do.&lt;/p&gt;

&lt;p&gt;It's worth it. I promise. And if you nuke the whole thing and start over, that's fine too.&lt;/p&gt;

&lt;p&gt;That's just &lt;code&gt;neovim-final-final-v2&lt;/code&gt; waiting to happen.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Enjoyed this? Follow me for more programming blogs where I justify my terrible life choices with technical reasoning.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://twitter.com/jmtalplacido" rel="noopener noreferrer"&gt;Twitter/X&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/JoshMatthew" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://jmct.dev" rel="noopener noreferrer"&gt;My Website&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Catch you in the next one. 🚀&lt;/p&gt;

</description>
      <category>pro</category>
      <category>neovim</category>
    </item>
    <item>
      <title>I Built an ORM That Starts With JSON So You Can Stop Overthinking Your Database</title>
      <dc:creator>Jay-Em</dc:creator>
      <pubDate>Thu, 19 Feb 2026 03:36:05 +0000</pubDate>
      <link>https://dev.to/joshmatthew/i-built-an-orm-that-starts-with-json-so-you-can-stop-overthinking-your-database-2439</link>
      <guid>https://dev.to/joshmatthew/i-built-an-orm-that-starts-with-json-so-you-can-stop-overthinking-your-database-2439</guid>
      <description>&lt;p&gt;You know that thing where you have a project idea at 1am, you're hyped, and then you spend the next 2 hours setting up Postgres, writing migrations, configuring connection strings, and by the time you're done your motivation is gone and you go to bed?&lt;/p&gt;

&lt;p&gt;Yeah. That kept happening to me. So I built something about it.&lt;/p&gt;

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

&lt;p&gt;SeedORM is a Node.js ORM that stores everything in local JSON files. No database server, no Docker, no connection strings. You define your models and start building immediately.&lt;/p&gt;

&lt;p&gt;Then when your project is ready for the real world, you migrate to Postgres with one command. Same models, same queries, same API. Nothing changes except where the data lives.&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;seedorm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Every side project I start follows the same pattern:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Cool idea hits me&lt;/li&gt;
&lt;li&gt;Create new folder, &lt;code&gt;npm init&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Okay now I need a database&lt;/li&gt;
&lt;li&gt;Do I use Postgres? MongoDB? SQLite?&lt;/li&gt;
&lt;li&gt;Spend 30 minutes setting up Docker, env vars, connection pooling&lt;/li&gt;
&lt;li&gt;Write migration files&lt;/li&gt;
&lt;li&gt;I'm tired now&lt;/li&gt;
&lt;li&gt;Abandon project&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I wanted something where step 3 is just... skip.&lt;/p&gt;

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

&lt;p&gt;Define your models like you normally would:&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;SeedORM&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;FieldType&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;seedorm&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;db&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;SeedORM&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&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;User&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;model&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;users&lt;/span&gt;&lt;span class="dl"&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="na"&gt;name&lt;/span&gt;&lt;span class="p"&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="nx"&gt;FieldType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;String&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="na"&gt;email&lt;/span&gt;&lt;span class="p"&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="nx"&gt;FieldType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;unique&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;age&lt;/span&gt;&lt;span class="p"&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="nx"&gt;FieldType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;Number&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;init&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. No database running. No config file pointing to &lt;code&gt;localhost:5432&lt;/code&gt;. It just writes to JSON files in a &lt;code&gt;data/&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;Now use it like any ORM:&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="c1"&gt;// Create&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&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;User&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;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;Josh&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;josh@hey.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Query&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;adults&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;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$gte&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18&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;// Update&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Delete&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Relations
&lt;/h2&gt;

&lt;p&gt;It supports the relation types you'd expect:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Post&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;model&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;posts&lt;/span&gt;&lt;span class="dl"&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="na"&gt;title&lt;/span&gt;&lt;span class="p"&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="nx"&gt;FieldType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;String&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="na"&gt;body&lt;/span&gt;&lt;span class="p"&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="nx"&gt;FieldType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;relations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;author&lt;/span&gt;&lt;span class="p"&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;belongsTo&lt;/span&gt;&lt;span class="dl"&gt;"&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;users&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;foreignKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;authorId&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;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;hasMany, belongsTo, manyToMany. They all work the same way when you eventually switch to Postgres.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Studio
&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%2Fkk2neq6vy2e52p6krqpq.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%2Fkk2neq6vy2e52p6krqpq.png" alt=" " width="800" height="387"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I got tired of opening JSON files to check my data, so I built a visual browser for it. Run &lt;code&gt;seedorm studio&lt;/code&gt; and you get a web UI at &lt;code&gt;localhost:4200&lt;/code&gt; where you can browse collections, search across fields, paginate through documents, and edit records.&lt;/p&gt;

&lt;p&gt;It's nothing fancy. It's just nice to have when you're building and want to see what's in your database without writing a query.&lt;/p&gt;

&lt;h2&gt;
  
  
  Per-Collection File Storage
&lt;/h2&gt;

&lt;p&gt;One thing that bugged me early on was that everything was stored in a single &lt;code&gt;seedorm.json&lt;/code&gt; file. With a few thousand documents across multiple collections, that file gets massive.&lt;/p&gt;

&lt;p&gt;So now each collection gets its own file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;data/
  users.json
  posts.json
  comments.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each file is minified (single line), writes only happen for collections that changed, and if you have an old &lt;code&gt;seedorm.json&lt;/code&gt; from a previous version it auto-migrates on startup. You don't have to do anything.&lt;/p&gt;

&lt;h2&gt;
  
  
  When You're Ready for Postgres
&lt;/h2&gt;

&lt;p&gt;Your project took off. Congrats. Time for a real database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;seedorm migrate to postgres
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your models stay the same. Your queries stay the same. You just change the adapter config:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;db&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;SeedORM&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;adapter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;adapter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;postgres&lt;/span&gt;&lt;span class="dl"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;postgresql://localhost:5432/myapp&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;p&gt;That's the whole point. Build fast with JSON, switch when it matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  What It's NOT
&lt;/h2&gt;

&lt;p&gt;Let me be clear about what SeedORM is not:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It's not a Prisma replacement for your production app with 10 million users&lt;/li&gt;
&lt;li&gt;It's not meant for high-concurrency workloads&lt;/li&gt;
&lt;li&gt;It's not trying to be the last ORM you'll ever use&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's for prototyping, side projects, hackathons, and that 1am idea that deserves to exist without a 30 minute setup ritual.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&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;seedorm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/JoshMatthew/seedorm" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/seedorm" rel="noopener noreferrer"&gt;npm&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you try it, I'd genuinely love to hear what you think. What's missing? What's annoying? What would make you actually use this?&lt;/p&gt;

&lt;p&gt;Thanks for reading.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>node</category>
      <category>opensource</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Dart Extensions: Unleashing the Power of Your Code! 🚀</title>
      <dc:creator>Jay-Em</dc:creator>
      <pubDate>Sat, 18 May 2024 02:04:50 +0000</pubDate>
      <link>https://dev.to/joshmatthew/dart-extensions-unleashing-the-power-of-your-code-5h8m</link>
      <guid>https://dev.to/joshmatthew/dart-extensions-unleashing-the-power-of-your-code-5h8m</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Hello everyone! Welcome to another exciting post. I hope you'll find this one just as useful!! Arigatogozaimasuuu! 🎉&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Have you ever felt limited by the built-in methods in Dart? Ever wished you could add your own methods to existing classes? Well, you're in luck because today I'm going to show you how to harness the magic of Dart extensions! 🌟&lt;/p&gt;

&lt;p&gt;Extensions allow you to add new functionality to existing libraries. They're a game-changer for making your code cleaner and more readable. Let's dive right in!&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Dart SDK&lt;/li&gt;
&lt;li&gt;A Dart project setup&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting Started with Dart Extensions
&lt;/h2&gt;

&lt;p&gt;First things first, make sure you have Dart installed. If you don't, you can download it from &lt;a href="https://dart.dev/get-dart"&gt;Dart's official website&lt;/a&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  Creating Your First Extension
&lt;/h3&gt;

&lt;p&gt;Let's say you want to add a new method to the &lt;code&gt;String&lt;/code&gt; class. Here's how you can do it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open your Dart project and create a new file called &lt;code&gt;string_extensions.dart&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Inside &lt;code&gt;string_extensions.dart&lt;/code&gt;, add the following code:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;extension&lt;/span&gt; &lt;span class="n"&gt;StringExtensions&lt;/span&gt; &lt;span class="kd"&gt;on&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;isPalindrome&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="k"&gt;this&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;reversed&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&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;p&gt;What did we just do? We created an extension on the &lt;code&gt;String&lt;/code&gt; class that adds a method called &lt;code&gt;isPalindrome&lt;/code&gt;. This method checks if a string reads the same backward as forward. Cool, right? 😎&lt;/p&gt;

&lt;h3&gt;
  
  
  Using Your Extension
&lt;/h3&gt;

&lt;p&gt;Now, let's use this new method in our project.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Import your extension into your main Dart file:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'string_extensions.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Use the new method on any string:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'level'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Is "&lt;/span&gt;&lt;span class="si"&gt;$word&lt;/span&gt;&lt;span class="s"&gt;" a palindrome? &lt;/span&gt;&lt;span class="si"&gt;${word.isPalindrome()}&lt;/span&gt;&lt;span class="s"&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;Run your Dart program, and you should see the output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Is "level" a palindrome? true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Boom! You've just extended the String class with a custom method. 🚀&lt;/p&gt;

&lt;h2&gt;
  
  
  More Practical Examples
&lt;/h2&gt;

&lt;p&gt;Let's explore some more practical examples to get you comfortable with extensions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 1: Adding a &lt;code&gt;toCapitalized&lt;/code&gt; Method
&lt;/h3&gt;

&lt;p&gt;Sometimes you might need to capitalize the first letter of a string. Let's create an extension for that.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;extension&lt;/span&gt; &lt;span class="n"&gt;CapitalizedString&lt;/span&gt; &lt;span class="kd"&gt;on&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;toCapitalized&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="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="si"&gt;${this[0].toUpperCase()}${this.substring(1)}&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&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;
  
  
  Example 2: Adding a &lt;code&gt;num&lt;/code&gt; Extension
&lt;/h3&gt;

&lt;p&gt;You can also extend numeric types. Let's add a method to double a number.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;extension&lt;/span&gt; &lt;span class="n"&gt;NumExtensions&lt;/span&gt; &lt;span class="kd"&gt;on&lt;/span&gt; &lt;span class="kt"&gt;num&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;num&lt;/span&gt; &lt;span class="n"&gt;doubled&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="k"&gt;this&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&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;
  
  
  Using the New Extensions
&lt;/h3&gt;

&lt;p&gt;Don't forget to import your extensions and use them in your code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'string_extensions.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'dart'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Capitalized: &lt;/span&gt;&lt;span class="si"&gt;${name.toCapitalized()}&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kt"&gt;num&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Doubled: &lt;/span&gt;&lt;span class="si"&gt;${value.doubled()}&lt;/span&gt;&lt;span class="s"&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;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;That's it! You've just learned how to create and use Dart extensions to make your code more powerful and expressive. 🎉&lt;/p&gt;

&lt;p&gt;Extensions are a fantastic way to add custom functionality to existing classes without modifying their source code. Use them wisely to keep your code clean and maintainable.&lt;/p&gt;

&lt;p&gt;I hope you've enjoyed this post and found it useful. Stay tuned for more exciting content! 🚀&lt;/p&gt;

</description>
      <category>dart</category>
      <category>programming</category>
      <category>extensions</category>
      <category>coding</category>
    </item>
    <item>
      <title>Auto update React app in Heroku upon git push on GitHub</title>
      <dc:creator>Jay-Em</dc:creator>
      <pubDate>Sat, 16 Jul 2022 12:28:45 +0000</pubDate>
      <link>https://dev.to/joshmatthew/auto-update-react-app-in-heroku-upon-git-push-on-github-2m8i</link>
      <guid>https://dev.to/joshmatthew/auto-update-react-app-in-heroku-upon-git-push-on-github-2m8i</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Hello everyone! This is going to be my first ever post here. I hope you'll find this useful!! Arigatogozaimasuuu!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Update: Heroku is not free anymore, these tutorial is outdated and will be updated soon&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Have you ever wondered if it is possible to just push your application update in your Github repo and then it will auto re-deploy your app in Heroku? Well, stop wondering because today I will share you the process on how to setup one in your React app project and save you the hassle of searching it on your own!&lt;/p&gt;

&lt;p&gt;We will utilize the use of what we call, "the magical" Github Actions. This is the main key that will unlock the possibility on how to make this idea come true.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I will assume that you already know how to create a Github repo, create an application in Heroku, and know the basics of Git. With that in mind, let us now start doing it!&lt;/p&gt;
&lt;/blockquote&gt;



&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://nodejs.org/en/"&gt;node.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git-scm.com/"&gt;Git&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="//heroku.com"&gt;Heroku account&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/"&gt;Github account&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setting up Github and Heroku
&lt;/h2&gt;

&lt;p&gt;1) First, you need to create a Github repository and push your React project there. In my case, I just pushed the default React app created by using npx create-react-app. &lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa9vdvuakom53w050da91.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa9vdvuakom53w050da91.png" alt="github repo" width="800" height="488"&gt;&lt;/a&gt; &lt;br&gt;
2) After that, you can now create an app in Heroku. Just leave the tabs open for the moment ;)&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4cndmawsspb28fjwgkoo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4cndmawsspb28fjwgkoo.png" alt="heroku app" width="800" height="428"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Setting up your React app
&lt;/h2&gt;

&lt;p&gt;3) Now in your project's root directory, create a new folder or a directory if that's what you want to call it, name it as &lt;code&gt;server&lt;/code&gt; and then create a new file inside naming &lt;code&gt;app.js&lt;/code&gt; and paste this code.&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;path&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;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&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;port&lt;/span&gt; &lt;span class="o"&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;PORT&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;3000&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;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&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;publicPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;path&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="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;..&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;build&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;static&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;publicPath&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&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="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&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="nx"&gt;publicPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;index.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt; 

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Server is up on port &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;!`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What in the world does this code do? Well, if you read it carefully, it's just serving your app's public folder to the browser.&lt;/p&gt;

&lt;p&gt;4) The project should look something like this.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzsb0rml1milocjqy0vtl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzsb0rml1milocjqy0vtl.png" alt="project structure" width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;5) Now open your favorite terminal, navigate inside the &lt;code&gt;server&lt;/code&gt; directory of your React app, and initiate node.js by&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm init &lt;span class="nt"&gt;--y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs4d09wfxa2llsshbsgsi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs4d09wfxa2llsshbsgsi.png" alt="init node" width="727" height="364"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;6) Now from here, I recommend using &lt;a href="https://www.npmjs.com/package/yarn"&gt;yarn&lt;/a&gt;, and then install express.js by&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add express
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;7) After installing express you should probably add a &lt;code&gt;.gitignore&lt;/code&gt; file containing &lt;code&gt;node_modules&lt;/code&gt; inside. You don't want to push it in Heroku because of its massive size. It should look like this.&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fybyqnuso0id8rr6szkz3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fybyqnuso0id8rr6szkz3.png" alt="gitignore" width="514" height="287"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;8) Navigate back to our project's root directory and create a &lt;code&gt;Procfile&lt;/code&gt; file and paste this inside&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;web: node ./server/app.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It should now look something like this.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs5ymlnhfkljh1k6mnzus.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs5ymlnhfkljh1k6mnzus.png" alt="procfile" width="670" height="464"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Setting up the Github action
&lt;/h2&gt;

&lt;p&gt;9) After adding that, open a new terminal and login to Heroku by typing&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;heroku login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If heroku is unknown to your system, you should &lt;a href="https://devcenter.heroku.com/articles/heroku-cli"&gt;install&lt;/a&gt; the Heroku cli first. It will open a login prompt in your browser. Just follow the instructions there and if it works, you should see something like this. &lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvn72f6hwt7kkt9yfrc9m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvn72f6hwt7kkt9yfrc9m.png" alt="heroku login" width="721" height="219"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;10) After successfully logging in, switch back to your previous terminal or open a new one and navigate back to your project's root directory. Commit all of your changes to your local branch, and add a remote branch for Heroku by typing in&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;heroku git:remote &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;name of your app]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It should look like this.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjeh5gmv1uqwgt84xy98i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjeh5gmv1uqwgt84xy98i.png" alt="add heroku branch" width="719" height="311"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;11) Now push your React app to Heroku by typing&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git push heroku &lt;span class="o"&gt;[&lt;/span&gt;your master branch]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My master branch is &lt;code&gt;main&lt;/code&gt; so it should look like this.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdekoghau5woztivo89w4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdekoghau5woztivo89w4.png" alt="start" width="352" height="77"&gt;&lt;/a&gt;&lt;br&gt;
 &lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkyocfnd53kbstfnksqjj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkyocfnd53kbstfnksqjj.png" alt="done" width="393" height="80"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;12) After pushing it to Heroku successfully, from your project's root directory, create a new directory following this structure.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxdrjdfyfqc5t7szcxyxk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxdrjdfyfqc5t7szcxyxk.png" alt="structure" width="231" height="292"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;13) In the newly created file &lt;code&gt;main.yml&lt;/code&gt;, paste this code inside.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;gitmainbranch&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;akhileshns/heroku-deploy@v3.12.12&lt;/span&gt; &lt;span class="c1"&gt;# This is the action&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;heroku_api_key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{secrets.HEROKU_API_KEY}}&lt;/span&gt;
          &lt;span class="na"&gt;heroku_app_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[herokuappname]"&lt;/span&gt; &lt;span class="c1"&gt;#Must be unique in Heroku&lt;/span&gt;
          &lt;span class="na"&gt;heroku_email&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[emailloggedinheroku]"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;em&gt;[gitmainbranch]&lt;/em&gt; with your master branch or main branch.&lt;br&gt;
Replace &lt;em&gt;[herokuappname]&lt;/em&gt; with your Heroku app name.&lt;br&gt;
Replace &lt;em&gt;[emailloogedinheroku]&lt;/em&gt; with the email you use in your Heroku account. &lt;/p&gt;

&lt;p&gt;This code is just a simple Github workflow that tells Github to auto update Heroku upon changes in the main branch of your React application.&lt;/p&gt;

&lt;p&gt;With my setup, it should look like this.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqtjt3yobgl9jvgocp3sg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqtjt3yobgl9jvgocp3sg.png" alt="yml" width="714" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;14) In your Heroku account, go to account settings and reveal your API key, and guess what? Copy it.&lt;br&gt;
 &lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff37s11dzemv4oty8y9al.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff37s11dzemv4oty8y9al.png" alt="api key" width="800" height="129"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;15) In your Github repo, go to your repository settings and add a new secret named &lt;code&gt;HEROKU_API_KEY&lt;/code&gt; and paste the API key you copied from Heroku.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiks3s5we5b9a5p93erbz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiks3s5we5b9a5p93erbz.png" alt="secret" width="800" height="633"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;16) We're almost done!!! Now save all files, commit all the changes and push it to your Github repo by&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git push origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It should be something like this. &lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft04gukln100fkepiieam.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft04gukln100fkepiieam.png" alt="commit" width="722" height="455"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  You're done! Congrats!
&lt;/h2&gt;

&lt;p&gt;17) Hooray!! We're done! Try making some changes in your app and push it on Github repo by&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git push origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or by merging a certain branch to your master branch. This action will be triggered whenever there's a change in your master branch. Once you've pushed a change, you'll see something like this in your action tab.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fblmneb1npyg5svhawumb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fblmneb1npyg5svhawumb.png" alt="action" width="800" height="164"&gt;&lt;/a&gt;&lt;br&gt;
 You'll also gonna see the logs in your Heroku app&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw9ctxv55sdxm00sik3di.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw9ctxv55sdxm00sik3di.png" alt="Heroku log" width="482" height="152"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;h2&gt;
  
  
  Thanks!
&lt;/h2&gt;

&lt;p&gt;That's it! You have now successfully setup your Github-Heroku workflow that will auto update your deployed React app on the go. &lt;br&gt;
I hope you've liked my first content here at DEV! I will post more in the future! Please see my &lt;a href="https://joshmatthew.herokuapp.com"&gt;website&lt;/a&gt; to know me more! Thanks!&lt;/p&gt;

</description>
      <category>github</category>
      <category>react</category>
      <category>heroku</category>
      <category>workflow</category>
    </item>
  </channel>
</rss>
