<?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>Forem: ak0047</title>
    <description>The latest articles on Forem by ak0047 (@a-k-0047).</description>
    <link>https://forem.com/a-k-0047</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%2F3404455%2F2a54388b-2216-4fc5-9cdc-2c10ce881cdc.png</url>
      <title>Forem: ak0047</title>
      <link>https://forem.com/a-k-0047</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/a-k-0047"/>
    <language>en</language>
    <item>
      <title>Why React Feels So Confusing: My Observations</title>
      <dc:creator>ak0047</dc:creator>
      <pubDate>Thu, 22 Jan 2026 22:24:04 +0000</pubDate>
      <link>https://forem.com/a-k-0047/why-react-feels-so-confusing-my-observations-3djh</link>
      <guid>https://forem.com/a-k-0047/why-react-feels-so-confusing-my-observations-3djh</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I’ve worked with various programming languages and frameworks, both professionally and through self-study.&lt;/p&gt;

&lt;p&gt;Usually, after reading a basic book or going through a tutorial, I can get the hang of things by looking up details online as needed.&lt;/p&gt;

&lt;p&gt;However, &lt;strong&gt;React didn’t fit into my usual approach at all.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Even after building a few React apps, I often found myself unsure where to write code when I wanted to make small changes to existing functionality.&lt;/p&gt;

&lt;p&gt;This made me wonder: &lt;strong&gt;why is React so hard to grasp?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this article, I’ll share my thoughts. I hope it can help people who are just starting with React, or those struggling with it, find a clearer way to understand it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Reason 1: Multiple Layers of Processing
&lt;/h2&gt;

&lt;p&gt;Let’s look at a simple example:&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&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="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&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;count&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&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;This code increases a number when the button is clicked.&lt;br&gt;
However, the actual process behind the scenes is more complex than it seems.&lt;/p&gt;

&lt;p&gt;Here’s what happens step by step:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The JS/TS code written by the developer&lt;/strong&gt; calls React’s API (updates the state).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;React&lt;/strong&gt; determines whether re-rendering is necessary.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;React&lt;/strong&gt; updates the virtual DOM.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The browser&lt;/strong&gt; updates the actual DOM based on React’s instructions.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In other words:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Developer-written JS/TS code&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;React’s internal processing&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Browser rendering&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…all happen at different layers. This separation makes it hard to intuitively understand &lt;strong&gt;which code runs at which layer&lt;/strong&gt;, which I think is one reason why React feels confusing.&lt;/p&gt;


&lt;h2&gt;
  
  
  Reason 2: Triggers for Code Execution Are Hard to Identify
&lt;/h2&gt;

&lt;p&gt;In React, code can be triggered by multiple events:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When a button is clicked (event)&lt;/li&gt;
&lt;li&gt;When state changes&lt;/li&gt;
&lt;li&gt;When props change&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example:&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="nf"&gt;useEffect&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;updated&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="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Doesn’t explicitly call a function&lt;/li&gt;
&lt;li&gt;Doesn’t involve a direct button click&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…but still runs whenever count changes.&lt;/p&gt;

&lt;p&gt;This makes it &lt;strong&gt;difficult to intuitively understand from the code itself when and why a piece of code will execute&lt;/strong&gt;, which adds to React’s learning curve.&lt;/p&gt;




&lt;h2&gt;
  
  
  Reason 3: Display Elements and Logic Are Mixed
&lt;/h2&gt;

&lt;p&gt;In React, JSX mixes the elements displayed in the browser with the logic controlling them:&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;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&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;count&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&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;count&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;}
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&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;While it looks similar to HTML:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Conditional expressions&lt;/li&gt;
&lt;li&gt;Variable evaluation&lt;/li&gt;
&lt;li&gt;Display logic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…are all included.&lt;/p&gt;

&lt;p&gt;This mixing makes it &lt;strong&gt;hard to immediately tell which elements will appear under which conditions&lt;/strong&gt;, contributing to React’s complexity.&lt;/p&gt;




&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;React feels confusing because of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Multiple layers of processing&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Triggers that are not obvious from the code&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Blurred boundaries between display elements and logic&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These factors combine to create a sense of &lt;strong&gt;“I don’t know what’s happening, when, or where”&lt;/strong&gt;.&lt;br&gt;
On top of this, the variety of JS/TS syntax and styling approaches only adds to the difficulty.&lt;/p&gt;

&lt;p&gt;I’m still learning, but being aware of these points helps me approach React more consciously.&lt;/p&gt;




&lt;h2&gt;
  
  
  💬 How about you?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;What aspects of React did you find most confusing when you started?&lt;/li&gt;
&lt;li&gt;How do you usually keep track of different layers (state, React processing, DOM updates)?&lt;/li&gt;
&lt;li&gt;Do you have any tips for making React code easier to reason about?&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>beginners</category>
      <category>react</category>
      <category>frontend</category>
      <category>programming</category>
    </item>
    <item>
      <title>Essential Shell Scripting Basics You Should Know First</title>
      <dc:creator>ak0047</dc:creator>
      <pubDate>Tue, 16 Dec 2025 11:49:57 +0000</pubDate>
      <link>https://forem.com/a-k-0047/essential-shell-scripting-basics-you-should-know-first-3in6</link>
      <guid>https://forem.com/a-k-0047/essential-shell-scripting-basics-you-should-know-first-3in6</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I previously wrote an article about shell scripting, and to my surprise, it was read by far more people than I expected.&lt;br&gt;
Since shell scripting isn’t exactly a “trendy” technology, I assumed there wouldn’t be much interest.&lt;/p&gt;

&lt;p&gt;That experience made me realize:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;There are probably more people who want to learn shell scripting than we think.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So in this article, I’d like to share a &lt;strong&gt;digest of essential shell scripting basics.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This guide is designed to cover &lt;strong&gt;“the minimum you need to know to avoid getting stuck when writing your first shell script.”&lt;/strong&gt;&lt;br&gt;
Rather than going deep into each topic, I focus on breadth and practical awareness.&lt;/p&gt;

&lt;p&gt;This article is especially useful if you:&lt;/p&gt;

&lt;p&gt;✅ Have never written a shell script before&lt;br&gt;
✅ Tried once but struggled&lt;br&gt;
✅ Want to understand how shell scripting differs from other languages&lt;/p&gt;


&lt;h2&gt;
  
  
  Basic Rules of Shell Scripts
&lt;/h2&gt;
&lt;h3&gt;
  
  
  The &lt;code&gt;.sh&lt;/code&gt; Extension Is a Convention
&lt;/h3&gt;

&lt;p&gt;Technically, shell scripts can have any file extension.&lt;br&gt;
However, &lt;code&gt;.sh&lt;/code&gt; is the widely accepted convention.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;hello.sh
backup.sh
deploy.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using &lt;code&gt;.sh&lt;/code&gt; enables syntax highlighting in editors and on GitHub, so unless you have a specific reason not to, stick with it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Write a Shebang (&lt;code&gt;#!&lt;/code&gt;) on the First Line
&lt;/h3&gt;

&lt;p&gt;A shell script should start with a &lt;strong&gt;shebang&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The shebang specifies &lt;strong&gt;which shell should execute the script.&lt;/strong&gt;&lt;br&gt;
It starts with &lt;code&gt;#!&lt;/code&gt; followed by the full path to the shell.&lt;/p&gt;
&lt;h3&gt;
  
  
  One Command Per Line
&lt;/h3&gt;

&lt;p&gt;In shell scripts, a newline separates commands, so the basic rule is &lt;strong&gt;one command per line.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you want to split a command across multiple lines, use &lt;code&gt;\&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"This is &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;
one command"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Comments Use &lt;code&gt;#&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Comments start with &lt;code&gt;#&lt;/code&gt;. You can also place comments mid-line.&lt;/p&gt;

&lt;p&gt;There is no native way to comment out multiple lines at once.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# This is a comment&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"hello"&lt;/span&gt; &lt;span class="c"&gt;# inline comments are allowed&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Working with Variables
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Defining Variables
&lt;/h3&gt;

&lt;p&gt;Variables are created automatically using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;variable_name=value
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No declaration is required. &lt;/p&gt;

&lt;p&gt;Variable naming rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Allowed characters: letters, numbers, and &lt;code&gt;_&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Cannot start with a number&lt;/li&gt;
&lt;li&gt;Lower snake_case is commonly used&lt;/li&gt;
&lt;li&gt;Variables are treated as strings by default&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want an integer variable, you need to declare it explicitly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# String variable&lt;/span&gt;
&lt;span class="nb"&gt;sum&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2+9
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$sum&lt;/span&gt;
&lt;span class="c"&gt;# -&amp;gt; 2+9&lt;/span&gt;

&lt;span class="c"&gt;# Integer variable&lt;/span&gt;
&lt;span class="nb"&gt;declare&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nb"&gt;sum
sum&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2+9
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$sum&lt;/span&gt;
&lt;span class="c"&gt;# -&amp;gt; 11&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Referencing Variables
&lt;/h3&gt;

&lt;p&gt;To reference a variable, prefix it with &lt;code&gt;$&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Alice"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$name&lt;/span&gt;
&lt;span class="c"&gt;# -&amp;gt; Alice&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In bash, referencing an undefined variable does &lt;strong&gt;not&lt;/strong&gt; cause an error—it expands to an empty string:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$name&lt;/span&gt;
&lt;span class="c"&gt;# -&amp;gt; (empty output)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To clearly separate variable names from surrounding text, use &lt;code&gt;{}&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;item&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"pen"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"I have many &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;item&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;s"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Single vs Double Quotes
&lt;/h3&gt;

&lt;p&gt;Quotes behave differently depending on the type:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;"&lt;/code&gt; : variables are expanded&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;'&lt;/code&gt; : variables are &lt;strong&gt;not&lt;/strong&gt; expanded
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Alice"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="c"&gt;# -&amp;gt; Alice&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'$name'&lt;/span&gt;
&lt;span class="c"&gt;# -&amp;gt; $name&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To escape characters inside double quotes, use &lt;code&gt;\&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\$&lt;/span&gt;&lt;span class="s2"&gt;name"&lt;/span&gt;
&lt;span class="c"&gt;# -&amp;gt; $name&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Common Control Structures
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Conditional Branching (if / case)
&lt;/h3&gt;

&lt;h4&gt;
  
  
  if Statements
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; condition &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;do_something
&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; another_condition &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;do_something_else
&lt;span class="k"&gt;else
  &lt;/span&gt;fallback
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are two condition styles (&lt;code&gt;[]&lt;/code&gt; and &lt;code&gt;[[]]&lt;/code&gt;).&lt;br&gt;
If you’re curious about the difference, see this article:&lt;br&gt;
&lt;a href="https://dev.to/a-k-0047/whats-the-difference-between-and-in-shell-scripts-3kkj"&gt;https://dev.to/a-k-0047/whats-the-difference-between-and-in-shell-scripts-3kkj&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  case Statements
&lt;/h4&gt;

&lt;p&gt;case is useful when handling multiple patterns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$var&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in
  &lt;/span&gt;start&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"start"&lt;/span&gt;
    &lt;span class="p"&gt;;;&lt;/span&gt;
  stop&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"stop"&lt;/span&gt;
    &lt;span class="p"&gt;;;&lt;/span&gt;
  &lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"other"&lt;/span&gt;
    &lt;span class="p"&gt;;;&lt;/span&gt;
&lt;span class="k"&gt;esac&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Loops (for / while)
&lt;/h3&gt;

&lt;h4&gt;
  
  
  for Loop
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;for &lt;/span&gt;value &lt;span class="k"&gt;in &lt;/span&gt;a b c&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  while Loop
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;declare&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nv"&gt;count&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0

&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$count&lt;/span&gt; &lt;span class="nt"&gt;-lt&lt;/span&gt; 5 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$count&lt;/span&gt;
  &lt;span class="nv"&gt;count&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$count&lt;/span&gt;+1
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An infinite loop can be written like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"looping..."&lt;/span&gt;
  &lt;span class="nb"&gt;sleep &lt;/span&gt;1
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Functions
&lt;/h2&gt;

&lt;p&gt;Functions are defined as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hello&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Hello &lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt; and &lt;/span&gt;&lt;span class="nv"&gt;$2&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Arguments are accessed using &lt;code&gt;$1&lt;/code&gt;, &lt;code&gt;$2&lt;/code&gt;, &lt;code&gt;$3&lt;/code&gt;, and so on.&lt;/p&gt;

&lt;p&gt;Calling a function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hello &lt;span class="s2"&gt;"Alice"&lt;/span&gt; &lt;span class="s2"&gt;"Bob"&lt;/span&gt;
&lt;span class="c"&gt;# -&amp;gt; Hello Alice and Bob&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Shell-Specific Concepts
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Exit Status
&lt;/h3&gt;

&lt;p&gt;On Linux, every command returns an &lt;strong&gt;exit status.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;0&lt;/strong&gt; → success&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Non-zero&lt;/strong&gt; → failure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The exit status is not displayed automatically.&lt;br&gt;
You can check it using &lt;code&gt;$?&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; /usr
&lt;span class="c"&gt;# -&amp;gt; bin  libexec  sbin  standalone  X11R6  lib  local  share  X11&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$?&lt;/span&gt;
&lt;span class="c"&gt;# -&amp;gt; 0&lt;/span&gt;

&lt;span class="nb"&gt;ls&lt;/span&gt; /aaa
&lt;span class="c"&gt;# -&amp;gt; ls: /aaa: No such file or directory&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$?&lt;/span&gt;
&lt;span class="c"&gt;# -&amp;gt; 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When using exit status in &lt;code&gt;if&lt;/code&gt; statements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;0 is treated as true&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Non-zero is treated as false&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; /usr&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"success"&lt;/span&gt;
&lt;span class="k"&gt;else
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"failure"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="c"&gt;# -&amp;gt; success&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; /aaa&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"success"&lt;/span&gt;
&lt;span class="k"&gt;else
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"failure"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="c"&gt;# -&amp;gt; failure&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Command Substitution
&lt;/h3&gt;

&lt;p&gt;You can store command output in a variable using &lt;code&gt;$(...)&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;now&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$now&lt;/span&gt;
&lt;span class="c"&gt;# -&amp;gt; Fri Dec 12 19:47:14 JST 2025&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pathname Expansion (Globbing)
&lt;/h3&gt;

&lt;p&gt;Shells can expand patterns like &lt;code&gt;*&lt;/code&gt; and &lt;code&gt;?&lt;/code&gt; into multiple filenames.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt;
&lt;span class="c"&gt;# -&amp;gt; file1.txt file2.txt string.c string.h string.txt&lt;/span&gt;

&lt;span class="c"&gt;# ? matches a single character&lt;/span&gt;
&lt;span class="nb"&gt;ls &lt;/span&gt;string.?
&lt;span class="c"&gt;# -&amp;gt; string.c string.h&lt;/span&gt;

&lt;span class="c"&gt;# * matches any string&lt;/span&gt;
&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt;.txt
&lt;span class="c"&gt;# -&amp;gt; file1.txt file2.txt string.txt&lt;/span&gt;

&lt;span class="c"&gt;# [] matches one of the listed characters&lt;/span&gt;
&lt;span class="nb"&gt;ls &lt;/span&gt;string.[ch]
&lt;span class="c"&gt;# -&amp;gt; string.c string.h&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Running Shell Scripts Manually
&lt;/h2&gt;

&lt;p&gt;There are two main ways to execute a shell script.&lt;/p&gt;

&lt;h3&gt;
  
  
  Method 1: Execute Directly (Recommended)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./hello.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Specify the script path (relative or absolute)&lt;/li&gt;
&lt;li&gt;Executed using the shebang-defined shell&lt;/li&gt;
&lt;li&gt;Requires execute permission: &lt;code&gt;chmod +x hello.sh&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Script name alone is not enough
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;✅ ./hello.sh
❌ hello.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Method 2: Pass to the Shell
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bash hello.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Execute permission not required&lt;/li&gt;
&lt;li&gt;You must manually choose the correct shell&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;This article summarized &lt;strong&gt;the minimum knowledge needed to avoid getting stuck when writing your first shell script.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are many more important patterns and techniques to learn, so I plan to write follow-up articles that dive deeper into specific topics.&lt;/p&gt;




&lt;h2&gt;
  
  
  💬 How about you?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;What was the most confusing part of shell scripting when you first learned it?&lt;/li&gt;
&lt;li&gt;Are there any shell scripting rules or behaviors that surprised you?&lt;/li&gt;
&lt;li&gt;Would you like to see a deeper article on a specific topic (e.g. &lt;code&gt;if&lt;/code&gt; conditions, quoting, or debugging)?&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>beginners</category>
      <category>bash</category>
      <category>linux</category>
      <category>basic</category>
    </item>
    <item>
      <title>I Built a Curl Command Generator App with React</title>
      <dc:creator>ak0047</dc:creator>
      <pubDate>Sun, 23 Nov 2025 04:34:05 +0000</pubDate>
      <link>https://forem.com/a-k-0047/i-built-a-curl-command-generator-app-with-react-4njb</link>
      <guid>https://forem.com/a-k-0047/i-built-a-curl-command-generator-app-with-react-4njb</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I built a &lt;strong&gt;browser-based curl command generator&lt;/strong&gt; using React.&lt;/p&gt;

&lt;p&gt;In this article, I’ll introduce the app, explain how to use it, share the background behind the development, and talk about the challenges and lessons learned along the way.&lt;/p&gt;

&lt;p&gt;▶ App URL: &lt;a href="https://d249wz41volo8p.cloudfront.net" rel="noopener noreferrer"&gt;https://d249wz41volo8p.cloudfront.net&lt;/a&gt;&lt;/p&gt;

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




&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;This application is a tool that &lt;strong&gt;automatically generates curl commands&lt;/strong&gt; for sending HTTP requests.&lt;br&gt;
By simply entering the method, URL, headers, and body, the corresponding curl command is generated instantly.&lt;/p&gt;




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

&lt;ol&gt;
&lt;li&gt;Select the &lt;strong&gt;HTTP method&lt;/strong&gt; (e.g., GET, POST).&lt;/li&gt;
&lt;li&gt;Enter the &lt;strong&gt;request URL&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Add &lt;strong&gt;headers, body, or authentication info&lt;/strong&gt; as needed.&lt;/li&gt;
&lt;li&gt;Choose additional options (e.g., &lt;code&gt;-i&lt;/code&gt;, &lt;code&gt;-L&lt;/code&gt;, &lt;code&gt;-v&lt;/code&gt;, &lt;code&gt;-k&lt;/code&gt;) using checkboxes.&lt;/li&gt;
&lt;li&gt;The curl command is generated and displayed in real time based on your input.&lt;/li&gt;
&lt;li&gt;Click the &lt;strong&gt;Copy&lt;/strong&gt; button to copy it to your clipboard.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Use Cases
&lt;/h2&gt;

&lt;p&gt;✅ Quickly test API requests.&lt;br&gt;
✅ Generate multiple curl commands for different scenarios.&lt;br&gt;
✅ Learn and review how to write curl commands and use common options.&lt;/p&gt;




&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Real-time curl command generation&lt;/strong&gt; based on input.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Common options&lt;/strong&gt; can be easily selected with checkboxes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add or remove multiple headers&lt;/strong&gt; dynamically.&lt;/li&gt;
&lt;li&gt;Supports &lt;strong&gt;Basic Authentication&lt;/strong&gt; and &lt;strong&gt;Bearer Tokens&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Light / Dark mode switching&lt;/strong&gt; supported.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Language switching (Japanese / English)&lt;/strong&gt; supported.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Technologies Used
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Frontend
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Technology&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Language&lt;/td&gt;
&lt;td&gt;TypeScript&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Library&lt;/td&gt;
&lt;td&gt;React&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Styling&lt;/td&gt;
&lt;td&gt;Tailwind CSS, Shadcn UI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Icons&lt;/td&gt;
&lt;td&gt;lucide-react&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;State Management&lt;/td&gt;
&lt;td&gt;React Hooks (useState, useEffect)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Development Env&lt;/td&gt;
&lt;td&gt;Docker, Docker Compose&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hosting&lt;/td&gt;
&lt;td&gt;S3 + CloudFront&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Backend
&lt;/h3&gt;

&lt;p&gt;None (frontend-only architecture)&lt;/p&gt;




&lt;h2&gt;
  
  
  System Architecture
&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%2Fuadih0qnaoz3e8rhdeqb.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%2Fuadih0qnaoz3e8rhdeqb.png" alt="system_configuration_diagram" width="631" height="311"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I Built This
&lt;/h2&gt;

&lt;p&gt;Recently, I started using curl more often at work. Since I wasn’t very familiar with it, I found myself repeatedly asking:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How do I specify the method again?&lt;/li&gt;
&lt;li&gt;How do I set headers?&lt;/li&gt;
&lt;li&gt;What does this option do?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I had to look things up every time.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Wouldn’t it be convenient if curl commands could be built just by selecting options in a UI?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That idea led me to build this app.&lt;/p&gt;

&lt;p&gt;Another reason was that I thought I could reuse parts of the code from a previous project:&lt;/p&gt;

&lt;p&gt;my &lt;strong&gt;“&lt;code&gt;.gitignore&lt;/code&gt; behavior checker”&lt;/strong&gt; app.👇&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/a-k-0047/i-built-a-gitignore-behavior-checker-app-with-react-a31"&gt;https://dev.to/a-k-0047/i-built-a-gitignore-behavior-checker-app-with-react-a31&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Focused On
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Reusing Code from &lt;code&gt;.gitignore&lt;/code&gt; Checker
&lt;/h3&gt;

&lt;p&gt;I tried to be efficient by reusing &lt;strong&gt;layouts, components, and logic&lt;/strong&gt; from my previous app.&lt;br&gt;
The language-switching feature (Japanese/English) was also reusable, which saved a lot of development time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementing Dark Mode
&lt;/h3&gt;

&lt;p&gt;I wanted to try something new in this project, so I added &lt;strong&gt;dark mode&lt;/strong&gt;.&lt;br&gt;
Unifying almost all UI with &lt;strong&gt;shadcn/ui&lt;/strong&gt; made dark mode support straightforward.&lt;/p&gt;

&lt;p&gt;Since shadcn/ui exposes component styles directly through code, I was able to match my custom components to its style and maintain a consistent design easily.&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%2Fmldwolta5deug98w80g2.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%2Fmldwolta5deug98w80g2.png" alt="dark_mode" width="800" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing Generated Curl Commands
&lt;/h3&gt;

&lt;p&gt;For verifying the generated curl commands, I used:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://httpbin.org/" rel="noopener noreferrer"&gt;https://httpbin.org/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It was helpful for testing various options and authentication patterns.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using AWS CDK
&lt;/h3&gt;

&lt;p&gt;I used &lt;strong&gt;AWS CDK&lt;/strong&gt; to create and manage the hosting environment (S3 + CloudFront).&lt;br&gt;
I previously created these resources manually via the AWS console, but automating them made things much easier.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Reusing Code Matters
&lt;/h3&gt;

&lt;p&gt;Reusing code from my &lt;code&gt;.gitignore&lt;/code&gt; checker app significantly reduced development time.&lt;br&gt;
I also wrote this app with reuse in mind—features like dark mode and AWS CDK configuration will be useful in future projects.&lt;/p&gt;

&lt;h3&gt;
  
  
  You Learn a Lot by Actually Using What You Built
&lt;/h3&gt;

&lt;p&gt;It sounds obvious, but using your own tools reveals many areas for improvement.&lt;/p&gt;

&lt;p&gt;For example, I originally placed the “Copy” button inside the command output area,&lt;br&gt;
but long commands would overlap with the button.&lt;br&gt;
So I moved it outside the text area.&lt;/p&gt;

&lt;p&gt;By actually using the app, I found many design and layout tweaks that made it more user-friendly.&lt;/p&gt;

&lt;p&gt;Getting feedback from others would be ideal, but first ensuring &lt;strong&gt;you&lt;/strong&gt; can use your app comfortably is a great start.&lt;/p&gt;




&lt;h2&gt;
  
  
  Future Plans
&lt;/h2&gt;

&lt;h3&gt;
  
  
  New Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;More curl options&lt;/li&gt;
&lt;li&gt;Saving generated commands&lt;/li&gt;
&lt;li&gt;Running commands directly from the UI&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Deployment Automation
&lt;/h3&gt;

&lt;p&gt;I automated resource creation with AWS CDK, but deployment is still manual.&lt;br&gt;
I’d like to automate it using GitHub Actions.&lt;/p&gt;




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

&lt;p&gt;There are already many curl generators out there, so I wondered whether it was worth building one myself.&lt;/p&gt;

&lt;p&gt;But in the end, I learned a lot and built reusable components and infrastructure that will help in future projects.&lt;/p&gt;

&lt;p&gt;I’m glad I took the time to build it, and I’d like to continue applying what I learned.&lt;/p&gt;

&lt;h3&gt;
  
  
  ▶ App
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://d249wz41volo8p.cloudfront.net" rel="noopener noreferrer"&gt;https://d249wz41volo8p.cloudfront.net&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  ▶ GitHub Repository
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/a-k-0047/curl-generator-front" rel="noopener noreferrer"&gt;https://github.com/a-k-0047/curl-generator-front&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  💬 How about you?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Have you ever built a small tool like this for your workflow? How did it go?&lt;/li&gt;
&lt;li&gt;What kind of features would you add to a curl generator like this?&lt;/li&gt;
&lt;li&gt;Do you usually write curl commands by hand, or do you use tools to help?&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>beginners</category>
      <category>react</category>
      <category>portfolio</category>
      <category>cli</category>
    </item>
    <item>
      <title>What’s the Difference Between [ ] and [[ ]] in Shell Scripts?</title>
      <dc:creator>ak0047</dc:creator>
      <pubDate>Tue, 18 Nov 2025 13:21:05 +0000</pubDate>
      <link>https://forem.com/a-k-0047/whats-the-difference-between-and-in-shell-scripts-3kkj</link>
      <guid>https://forem.com/a-k-0047/whats-the-difference-between-and-in-shell-scripts-3kkj</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Recently, I had an opportunity to write some shell scripts at work.&lt;br&gt;
Since I didn’t have much experience with shell scripting, I looked things up online while writing the code. That’s when I ran into this question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What’s the difference between writing &lt;code&gt;if [ ]; then&lt;/code&gt; and &lt;code&gt;if [[ ]]; then&lt;/code&gt; ?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this article, I’ll share what I learned about the differences between the two and how to choose which one to use.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Basic Difference Between &lt;code&gt;[ ]&lt;/code&gt; and &lt;code&gt;[[ ]]&lt;/code&gt;
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Syntax&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Characteristics&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;if [ condition ]; then&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;POSIX-standard&lt;/td&gt;
&lt;td&gt;Works on any UNIX environment. The classic format.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;if [[ condition ]]; then&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Bash extension&lt;/td&gt;
&lt;td&gt;Bash-only. Safer and more powerful.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The POSIX-standard syntax is defined so that it behaves the same across all UNIX-like systems.&lt;br&gt;
It works on Linux, macOS, BSD, and any POSIX-compliant shell.&lt;/p&gt;

&lt;p&gt;On the other hand, the Bash extension syntax works on &lt;strong&gt;Bash&lt;/strong&gt; and &lt;strong&gt;Zsh&lt;/strong&gt;, but does &lt;strong&gt;not&lt;/strong&gt; work on &lt;code&gt;/bin/sh&lt;/code&gt; or other strictly POSIX-compliant shells.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;[ ]&lt;/code&gt; internally calls the &lt;code&gt;test&lt;/code&gt; command.&lt;br&gt;
So this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; file &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Exists"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is actually equivalent to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; file&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Exists"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Meanwhile, &lt;code&gt;[[ ]]&lt;/code&gt; is parsed directly by the shell, which allows safer handling of complex expressions and pattern matching.&lt;/p&gt;




&lt;h2&gt;
  
  
  Common Conditional Expressions Compared
&lt;/h2&gt;

&lt;p&gt;Here are common examples written using both &lt;code&gt;[ ]&lt;/code&gt; and &lt;code&gt;[[ ]]&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Checking File or Directory Existence
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Condition&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;th&gt;&lt;code&gt;[ ]&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;[[ ]]&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;File exists&lt;/td&gt;
&lt;td&gt;-f&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[ -f "$file" ]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[[ -f $file ]]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Directory exists&lt;/td&gt;
&lt;td&gt;-d&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[ -d "$dir" ]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[[ -d $dir ]]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Does not exist&lt;/td&gt;
&lt;td&gt;!&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[ ! -f "$file" ]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[[ ! -f $file ]]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Both work the same, but with &lt;code&gt;[[ ]]&lt;/code&gt; you can omit quotes safely.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. String Comparison
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Condition&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;th&gt;&lt;code&gt;[ ]&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;[[ ]]&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Equal&lt;/td&gt;
&lt;td&gt;&lt;code&gt;=&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[ "$a" = "$b" ]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[[ $a = $b ]]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Not equal&lt;/td&gt;
&lt;td&gt;&lt;code&gt;!=&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[ "$a" != "$b" ]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[[ $a != $b ]]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Empty&lt;/td&gt;
&lt;td&gt;&lt;code&gt;-z&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[ -z "$a" ]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[[ -z $a ]]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Not empty&lt;/td&gt;
&lt;td&gt;&lt;code&gt;-n&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[ -n "$a" ]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[[ -n $a ]]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;[ ]&lt;/code&gt; → Always quote variables&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;[[ ]]&lt;/code&gt; → Quotes optional and safer&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Numeric Comparison
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Condition&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;th&gt;&lt;code&gt;[ ]&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;[[ ]]&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Equal&lt;/td&gt;
&lt;td&gt;-eq&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[ "$x" -eq "$y" ]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[[ $x -eq $y ]]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Greater&lt;/td&gt;
&lt;td&gt;-gt&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[ "$x" -gt "$y" ]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[[ $x -gt $y ]]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Smaller&lt;/td&gt;
&lt;td&gt;-lt&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[ "$x" -lt "$y" ]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[[ $x -lt $y ]]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Same syntax in both cases.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. AND / OR Conditions
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;[ ]&lt;/code&gt; syntax&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$a&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$a&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;    &lt;span class="c"&gt;# AND（both true）&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$a&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$b&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;    &lt;span class="c"&gt;# OR（one true）&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;[[ ]]&lt;/code&gt; syntax&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nv"&gt;$a&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="nv"&gt;$a&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;    &lt;span class="c"&gt;# AND（both true）&lt;/span&gt;
&lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nv"&gt;$a&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nv"&gt;$b&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;    &lt;span class="c"&gt;# OR（one true）&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;[[ ]]&lt;/code&gt; allows combining conditions inside a single expression.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Pattern Matching
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"report.txt"&lt;/span&gt;

&lt;span class="c"&gt;# Works in [[ ]]&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nv"&gt;$file&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt;.txt &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Text file"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c"&gt;# Does NOT work in [ ] (always false)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$file&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt;.txt &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Will not run"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wildcards (&lt;code&gt;*&lt;/code&gt;, &lt;code&gt;?&lt;/code&gt;) are supported only in &lt;code&gt;[[ ]]&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  How to Choose
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Use Case&lt;/th&gt;
&lt;th&gt;Recommended Syntax&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Needs POSIX compatibility (&lt;code&gt;/bin/sh&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[ ]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bash-only script, want safety&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[[ ]]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Avoiding quote-related bugs&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[[ ]]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Needs compatibility with other shells&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[ ]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Pick One Style and Stick to It
&lt;/h2&gt;

&lt;p&gt;You can use either style, but it’s best to &lt;strong&gt;choose one and stay consistent&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here’s why:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Better readability and maintainability
&lt;/h3&gt;

&lt;p&gt;Mixing &lt;code&gt;[ ]&lt;/code&gt; and &lt;code&gt;[[ ]]&lt;/code&gt; in one script makes readers wonder:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Why is this one using &lt;code&gt;[ ]&lt;/code&gt;? Is there a special reason?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Unintended inconsistencies increase mental load and confusion.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Prevent incompatibility across shells
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;[[ ]]&lt;/code&gt; works only in Bash.&lt;br&gt;
It fails in &lt;code&gt;/bin/sh&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/sh&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; file &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Exists"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Works in &lt;strong&gt;bash&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Errors in &lt;strong&gt;sh&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Therefore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Writing a Bash script? → Use &lt;code&gt;[[ ]]&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Want POSIX portability? → Use &lt;code&gt;[ ]&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Avoid subtle bugs
&lt;/h3&gt;

&lt;p&gt;Since &lt;code&gt;[ ]&lt;/code&gt; and &lt;code&gt;[[ ]]&lt;/code&gt; evaluate expressions differently, mixing them can cause unexpected behavior.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;var&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"*.txt"&lt;/span&gt;

&lt;span class="c"&gt;# [ ] → filename expansion occurs&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$var&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"*.txt"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"match"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c"&gt;# [[ ]] → treated as a pattern&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nv"&gt;$var&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt;.txt &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"match"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even though the lines look similar, their behavior differs.&lt;br&gt;
Consistency prevents surprises.&lt;/p&gt;




&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;[ ]&lt;/code&gt; is the POSIX-standard test command&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;[[ ]]&lt;/code&gt; is a Bash extension: safer and more flexible&lt;/li&gt;
&lt;li&gt;Both support &lt;code&gt;-n&lt;/code&gt; / &lt;code&gt;-z&lt;/code&gt;, but &lt;code&gt;[[ ]]&lt;/code&gt; is safer without quotes&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;[[ ]]&lt;/code&gt; supports combining conditions and pattern matching&lt;/li&gt;
&lt;li&gt;Either is fine—but don’t mix them&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;Before writing this article, I didn’t even know there were two different syntaxes.&lt;br&gt;
I was copying conditional expressions from the internet and ended up mixing &lt;code&gt;[ ]&lt;/code&gt; and &lt;code&gt;[[ ]]&lt;/code&gt; in the same script without realizing it.&lt;/p&gt;

&lt;p&gt;If this article helps even one person avoid that mistake, I’ll be happy.&lt;br&gt;
Be mindful when choosing which syntax to use!&lt;/p&gt;




&lt;h2&gt;
  
  
  💬 How about you?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;What syntax do you usually use in your shell scripts — &lt;code&gt;[ ]&lt;/code&gt; or &lt;code&gt;[[ ]]&lt;/code&gt;? And why?&lt;/li&gt;
&lt;li&gt;Have you ever run into unexpected behavior because of differences between &lt;code&gt;[ ]&lt;/code&gt; and &lt;code&gt;[[ ]]&lt;/code&gt;?&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>beginners</category>
      <category>bash</category>
      <category>linux</category>
      <category>shell</category>
    </item>
    <item>
      <title>Understanding the Asterisk (*) in Python Function Arguments</title>
      <dc:creator>ak0047</dc:creator>
      <pubDate>Thu, 06 Nov 2025 12:22:35 +0000</pubDate>
      <link>https://forem.com/a-k-0047/understanding-the-asterisk-in-python-function-arguments-1pl0</link>
      <guid>https://forem.com/a-k-0047/understanding-the-asterisk-in-python-function-arguments-1pl0</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Have you ever seen function arguments in Python with a &lt;code&gt;*&lt;/code&gt; or &lt;code&gt;**&lt;/code&gt; and wondered what they mean?&lt;br&gt;
I’ve definitely seen them — and to be honest, I used to just ignore them because they looked confusing.&lt;/p&gt;

&lt;p&gt;Recently, I came across them again and decided it was finally time to understand what’s really going on.&lt;br&gt;
Here’s what I learned about how and when to use &lt;code&gt;*&lt;/code&gt; and &lt;code&gt;**&lt;/code&gt; in Python functions.&lt;/p&gt;


&lt;h2&gt;
  
  
  When to Use &lt;code&gt;*&lt;/code&gt; and &lt;code&gt;**&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;We use &lt;code&gt;*&lt;/code&gt; and &lt;code&gt;**&lt;/code&gt; in function arguments when we want to &lt;strong&gt;reuse the same logic, but the number or names of arguments might differ&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In short, these allow us to define &lt;strong&gt;functions that don’t fix the number or names of arguments&lt;/strong&gt; — making our code much more flexible.&lt;/p&gt;

&lt;p&gt;Let’s go through the different ways to use them 👇&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;code&gt;*args&lt;/code&gt;: Collecting Multiple Positional Arguments
&lt;/h2&gt;

&lt;p&gt;You can use a single asterisk (&lt;code&gt;*&lt;/code&gt;) to collect &lt;strong&gt;any number of positional arguments&lt;/strong&gt; into a tuple.&lt;br&gt;
That means the function can accept a variable number of arguments without breaking.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Alice&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="c1"&gt;# Hello, Alice!
&lt;/span&gt;
&lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Alice&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bob&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Charlie&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# Hello, Alice!
# Hello, Bob!
# Hello, Charlie!
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By convention, we name it &lt;code&gt;args&lt;/code&gt;, but you can actually use any name.&lt;/p&gt;

&lt;p&gt;This pattern is useful when you don’t know in advance how many arguments will be passed — for example, logging, combining results, or batch processing.&lt;/p&gt;

&lt;p&gt;Note that any argument &lt;strong&gt;after&lt;/strong&gt; &lt;code&gt;*args&lt;/code&gt; must be passed &lt;strong&gt;as a keyword argument:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# ✅ OK
# sample(1, 2, 3, 4, 5)    # ❌ Error: x and y must be keyword arguments
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;code&gt;**kwargs&lt;/code&gt;: &lt;strong&gt;Collecting Keyword Arguments as a Dictionary&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A double asterisk (&lt;code&gt;**&lt;/code&gt;) allows a function to collect &lt;strong&gt;any number of keyword arguments&lt;/strong&gt; into a dictionary.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;show_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;show_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Alice&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;country&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Japan&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# name: Alice
# age: 25
# country: Japan
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The name &lt;code&gt;kwargs&lt;/code&gt; stands for keyword arguments, but again — any name works.&lt;/p&gt;

&lt;p&gt;This is handy when you want to handle optional parameters or when a function may receive additional options in the future.&lt;/p&gt;

&lt;p&gt;Keep in mind: &lt;code&gt;**kwargs&lt;/code&gt; must appear &lt;strong&gt;last&lt;/strong&gt; in the function definition.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ✅ OK
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# ❌ Invalid
# def sample(a, b, **kwargs, c):
#     print(a, b, kwargs, c)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  The Lone &lt;code&gt;*&lt;/code&gt;: Forcing Keyword-Only Arguments
&lt;/h2&gt;

&lt;p&gt;If you include a bare &lt;code&gt;*&lt;/code&gt; in your function definition, all parameters &lt;strong&gt;after&lt;/strong&gt; it must be passed as &lt;strong&gt;keyword arguments&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;speed&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;forward&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="bp"&gt;...&lt;/span&gt;

&lt;span class="c1"&gt;# ✅ OK
&lt;/span&gt;&lt;span class="nf"&gt;move&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;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;speed&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;backward&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# ❌ Error: speed and direction must be passed as keyword arguments
# move(10, 20, 2.0, "backward")
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This helps clearly separate main parameters from optional ones, making your function calls more readable and less error-prone.&lt;/p&gt;




&lt;h2&gt;
  
  
  Argument Unpacking with &lt;code&gt;*&lt;/code&gt; and &lt;code&gt;**&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;You can also use &lt;code&gt;*&lt;/code&gt; and &lt;code&gt;**&lt;/code&gt; &lt;strong&gt;when calling a function&lt;/strong&gt;, not just when defining one.&lt;br&gt;
This technique is known as &lt;strong&gt;argument unpacking&lt;/strong&gt; — it lets you “expand” a list, tuple, or dictionary into separate arguments.&lt;/p&gt;
&lt;h3&gt;
  
  
  Example 1: Unpacking a list or tuple
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;

&lt;span class="n"&gt;numbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# same as add(1, 2, 3)
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# 6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Example 2: Unpacking a dictionary
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;show_profile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;country&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; (&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;) from &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;country&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;profile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Alice&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;age&lt;/span&gt;&lt;span class="sh"&gt;"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;country&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Japan&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;show_profile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# same as show_profile(name="Alice", age=25, country="Japan")
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Practical Example: Shared Logic with Different Arguments
&lt;/h2&gt;

&lt;p&gt;Here’s a simple but powerful use case — when multiple functions share the same workflow, but take different arguments.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_anything&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;=== Start process ===&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;=== End process ===&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;notify&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Processing user:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;notify&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Processing order:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;process_anything&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;process_user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;notify&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# === Start process ===
# Processing user: 123 True True
# === End process ===
&lt;/span&gt;
&lt;span class="nf"&gt;process_anything&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;process_order&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;999&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# === Start process ===
# Processing order: 999 True
# === End process ===
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why this works&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;process_anything()&lt;/code&gt; can call any function, regardless of how many arguments it takes&lt;/li&gt;
&lt;li&gt;Shared steps (logging, setup, teardown) live in one place&lt;/li&gt;
&lt;li&gt;Great for decorators, wrappers, or utility functions&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  When to Use Each
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Situation&lt;/th&gt;
&lt;th&gt;Syntax&lt;/th&gt;
&lt;th&gt;Why it helps&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Variable number of arguments&lt;/td&gt;
&lt;td&gt;&lt;code&gt;*args&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Flexibility&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Collecting optional parameters&lt;/td&gt;
&lt;td&gt;&lt;code&gt;**kwargs&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Easy to extend&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Forcing keyword arguments&lt;/td&gt;
&lt;td&gt;&lt;code&gt;def func(*, option=...)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Safer and clearer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Passing a list/dict as arguments&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;*obj&lt;/code&gt; / &lt;code&gt;**obj&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Clean and concise&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reusing logic for different functions&lt;/td&gt;
&lt;td&gt;&lt;code&gt;*args, **kwargs&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Improves reusability&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;*args&lt;/code&gt;: collects positional arguments&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;**kwargs&lt;/code&gt;: collects keyword arguments&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;*&lt;/code&gt; alone: makes following parameters keyword-only&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;*&lt;/code&gt; / &lt;code&gt;**&lt;/code&gt; when calling a function to unpack arguments&lt;/li&gt;
&lt;li&gt;Perfect for “same logic, slightly different arguments” cases&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;I used to avoid &lt;code&gt;*&lt;/code&gt; and &lt;code&gt;**&lt;/code&gt; because they looked intimidating — but after digging in, I realized how powerful and practical they are.&lt;br&gt;
I wish I’d learned about them earlier; they would’ve made some of my past code so much cleaner.&lt;br&gt;
From now on, I’m definitely going to use them more often.&lt;/p&gt;




&lt;h2&gt;
  
  
  💬 How about you?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Have you used &lt;code&gt;*args&lt;/code&gt; or &lt;code&gt;**kwargs&lt;/code&gt; in your own projects?&lt;/li&gt;
&lt;li&gt;What’s a situation where they saved you from writing repetitive code?&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>beginners</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>What kind of day is this ‘day’? — Naming Tips That Won’t Confuse Your Readers</title>
      <dc:creator>ak0047</dc:creator>
      <pubDate>Wed, 15 Oct 2025 10:33:13 +0000</pubDate>
      <link>https://forem.com/a-k-0047/what-kind-of-day-is-this-day-naming-tips-that-wont-confuse-your-readers-21kh</link>
      <guid>https://forem.com/a-k-0047/what-kind-of-day-is-this-day-naming-tips-that-wont-confuse-your-readers-21kh</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;day&lt;/code&gt; — What kind of day is it?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;status&lt;/code&gt; — The status of what?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;user&lt;/code&gt; — Which user?&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In one of the systems I maintained in the past, I came across code filled with extremely generic variable names like &lt;code&gt;day&lt;/code&gt;, &lt;code&gt;status&lt;/code&gt;, and &lt;code&gt;user&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
It was painful to read and understand what each variable actually represented.&lt;/p&gt;

&lt;p&gt;That experience made me wonder:&lt;br&gt;&lt;br&gt;
&lt;strong&gt;How can we name things in a way that makes sense not only to others, but also to our future selves?&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;So I decided to dig into the fundamentals of naming — and summarize what I found.&lt;/p&gt;

&lt;p&gt;While the examples below use Python, most of these principles apply to any programming language.&lt;/p&gt;


&lt;h2&gt;
  
  
  Follow a Consistent Naming Rule
&lt;/h2&gt;

&lt;p&gt;You can use any naming style, but what really matters is &lt;strong&gt;consistency within the project&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Here are some common conventions:&lt;/p&gt;
&lt;h3&gt;
  
  
  Case Styles
&lt;/h3&gt;

&lt;p&gt;Pick one and stick with it.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Style&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;th&gt;Common Usage&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;snake_case&lt;/td&gt;
&lt;td&gt;&lt;code&gt;user_name&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Python variables, functions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;camelCase&lt;/td&gt;
&lt;td&gt;&lt;code&gt;userName&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;JavaScript variables&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PascalCase&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UserProfile&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Class names&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  Use Verbs and Nouns Properly
&lt;/h3&gt;

&lt;p&gt;Match the word type to what you're naming.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Naming pattern&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Function / Method&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;verb + object&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;send_email&lt;/code&gt;, &lt;code&gt;calculate_total&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Variable / Class&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;noun&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;user&lt;/code&gt;, &lt;code&gt;payment_service&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  Prefixes and Suffixes
&lt;/h3&gt;

&lt;p&gt;Use consistent patterns for similar kinds of behavior.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Prefix&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Getter&lt;/td&gt;
&lt;td&gt;&lt;code&gt;get_&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;get_user&lt;/code&gt;, &lt;code&gt;get_order&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Converter&lt;/td&gt;
&lt;td&gt;&lt;code&gt;to_&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;to_json&lt;/code&gt;, &lt;code&gt;to_dict&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Test function&lt;/td&gt;
&lt;td&gt;&lt;code&gt;test_&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;test_user_login&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  Share and Automate Your Naming Rules
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Document your naming conventions and share them with your team.
&lt;/li&gt;
&lt;li&gt;Use linters like &lt;strong&gt;flake8&lt;/strong&gt;, &lt;strong&gt;pylint&lt;/strong&gt;, or &lt;strong&gt;ESLint&lt;/strong&gt; to enforce consistency automatically.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✅ This keeps your codebase coherent and reduces review fatigue.&lt;/p&gt;


&lt;h2&gt;
  
  
  Avoid Names That Are Too Short
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Avoid Single Words That Lack Context
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;email&lt;/span&gt;          &lt;span class="c1"&gt;# ❌ What is this? An address? A message?
&lt;/span&gt;&lt;span class="n"&gt;email_address&lt;/span&gt;  &lt;span class="c1"&gt;# ✅ Clearer
&lt;/span&gt;&lt;span class="n"&gt;email_message&lt;/span&gt;  &lt;span class="c1"&gt;# ✅ Clearer
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Be Careful with Overly Generic Words
&lt;/h3&gt;

&lt;p&gt;Words like &lt;code&gt;data&lt;/code&gt;, &lt;code&gt;result&lt;/code&gt;, or &lt;code&gt;status&lt;/code&gt; are too vague.&lt;br&gt;
Also, avoid using temporary placeholders like &lt;code&gt;tmp&lt;/code&gt; or &lt;code&gt;temp&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;pending_user&lt;/span&gt;  &lt;span class="c1"&gt;# ✅ A user waiting for approval
&lt;/span&gt;&lt;span class="n"&gt;temp_user&lt;/span&gt;     &lt;span class="c1"&gt;# ❌ “Temporary” in what sense?
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Avoid One- or Two-Letter Names
&lt;/h3&gt;

&lt;p&gt;Use single letters only when there’s a clear, conventional reason —&lt;br&gt;
for example, loop counters or coordinate axes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&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="c1"&gt;# ✅ OK, conventional for loops
&lt;/span&gt;    &lt;span class="bp"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&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;20&lt;/span&gt;  &lt;span class="c1"&gt;# ✅ OK for coordinates
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Avoid Abbreviations
&lt;/h3&gt;

&lt;p&gt;Abbreviations make search and readability harder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;copy_data&lt;/span&gt;  &lt;span class="c1"&gt;# ✅
&lt;/span&gt;&lt;span class="n"&gt;cpy_data&lt;/span&gt;   &lt;span class="c1"&gt;# ❌
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use only well-known abbreviations such as &lt;strong&gt;HTML, URL, DB, or ID&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Omit Unnecessary Information
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Don’t Include Class Names in Attributes
&lt;/h3&gt;

&lt;p&gt;Keep names concise but meaningful.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Cat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;weight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;weight&lt;/span&gt;  &lt;span class="c1"&gt;# ✅ Don't name it catweight
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Don’t Add Numbers to Differentiate Variables
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;payment1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;payment2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;payment3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead, use a list, dictionary, or more descriptive names.&lt;/p&gt;

&lt;h3&gt;
  
  
  Don’t Include Data Types in Names
&lt;/h3&gt;

&lt;p&gt;Usually, the data type is obvious or irrelevant.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;name&lt;/span&gt;      &lt;span class="c1"&gt;# ✅
&lt;/span&gt;&lt;span class="n"&gt;name_str&lt;/span&gt;  &lt;span class="c1"&gt;# ❌
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Make Your Names More Expressive
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Use &lt;code&gt;is&lt;/code&gt; / &lt;code&gt;has&lt;/code&gt; for Boolean Variables or Functions
&lt;/h3&gt;

&lt;p&gt;This makes intent immediately clear.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;is_valid_email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;has_permission&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="bp"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Avoid Negative Names
&lt;/h3&gt;

&lt;p&gt;Negative forms can create confusing double negatives.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;is_valid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="c1"&gt;# ✅ Easy to read
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;is_not_valid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="c1"&gt;# ❌ Harder to process
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Include Units in Names
&lt;/h3&gt;

&lt;p&gt;This avoids ambiguity about measurement.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;weight_kg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;5.2&lt;/span&gt;
&lt;span class="n"&gt;length_m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;3.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Use Plural Names for Collections
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Alice&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;            &lt;span class="c1"&gt;# ✅ Single item
&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Alice&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bob&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="c1"&gt;# ✅ Collection
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Watch Out for These Common Pitfalls
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Don’t Override Built-in Names
&lt;/h3&gt;

&lt;p&gt;Avoid using names like &lt;code&gt;list&lt;/code&gt;, &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;sum&lt;/code&gt;, or &lt;code&gt;type&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nb"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;     &lt;span class="c1"&gt;# ❌
&lt;/span&gt;&lt;span class="n"&gt;my_list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="c1"&gt;# ✅
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Think Ahead — Future Changes Matter
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Don’t embed implementation details or formats in names.

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;read_csv()&lt;/code&gt; → If you later support JSON, &lt;code&gt;load_data()&lt;/code&gt; is more flexible.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Avoid naming variables after data structures.

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;user_list&lt;/code&gt; → It might later become a &lt;code&gt;set&lt;/code&gt; or a &lt;code&gt;dict&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




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

&lt;p&gt;When I revisited the topic of naming, I realized there’s much more to consider than I thought.&lt;br&gt;
Even names that make sense today can become meaningless months later.&lt;/p&gt;

&lt;p&gt;That’s why I try to keep these principles in mind —&lt;br&gt;
to write code that’s not only clear to others, but also to future me.&lt;/p&gt;




&lt;h2&gt;
  
  
  💬 How about you?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;What naming conventions or rules do you follow in your projects?
&lt;/li&gt;
&lt;li&gt;Are there any particular pitfalls or lessons you've learned when it comes to naming?&lt;/li&gt;
&lt;li&gt;What’s the worst (or funniest) variable name you’ve seen?&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>beginners</category>
      <category>programming</category>
      <category>python</category>
      <category>cleancode</category>
    </item>
    <item>
      <title>I Built a .gitignore Behavior Checker App with React</title>
      <dc:creator>ak0047</dc:creator>
      <pubDate>Fri, 03 Oct 2025 09:14:32 +0000</pubDate>
      <link>https://forem.com/a-k-0047/i-built-a-gitignore-behavior-checker-app-with-react-a31</link>
      <guid>https://forem.com/a-k-0047/i-built-a-gitignore-behavior-checker-app-with-react-a31</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I built a small web app that lets you &lt;strong&gt;check how &lt;code&gt;.gitignore&lt;/code&gt; rules behave directly in your browser&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In this post, I’ll walk through the app’s overview and usage, share some background on why I created it, highlight some challenges and design choices, and summarize what I learned during the process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;▶ Live Demo&lt;/strong&gt;: &lt;a href="https://d14csvmoeha0t5.cloudfront.net/" rel="noopener noreferrer"&gt;https://d14csvmoeha0t5.cloudfront.net/&lt;/a&gt;&lt;/p&gt;

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




&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;The app allows you to quickly check whether a given file or directory would be &lt;strong&gt;tracked by Git or ignored&lt;/strong&gt; based on &lt;code&gt;.gitignore&lt;/code&gt; rules.&lt;/p&gt;

&lt;p&gt;It’s essentially a playground for &lt;code&gt;.gitignore&lt;/code&gt;—helpful for developers who want to test and debug ignore patterns without having to commit and check inside a repo.&lt;/p&gt;




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

&lt;ol&gt;
&lt;li&gt;Upload a &lt;code&gt;.gitignore&lt;/code&gt; file, or paste its contents into the text area.&lt;/li&gt;
&lt;li&gt;Enter file or directory names in the other text area.&lt;/li&gt;
&lt;li&gt;The app will automatically evaluate whether those files/directories are &lt;strong&gt;tracked&lt;/strong&gt; or &lt;strong&gt;ignored&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  When You Might Use It
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;✅To double-check if your &lt;code&gt;.gitignore&lt;/code&gt; rules are working correctly&lt;/li&gt;
&lt;li&gt;✅Before adding new ignore rules and wanting to test them&lt;/li&gt;
&lt;li&gt;✅To debug why something is unexpectedly tracked or ignored&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Key Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Batch checks&lt;/strong&gt;: Evaluate multiple file and directory names at once&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-time results&lt;/strong&gt;: Changes in the text area are instantly reflected in the results&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rule transparency&lt;/strong&gt;: Shows which rule caused the file to be ignored&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Language toggle&lt;/strong&gt;: Switch between English and Japanese&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Tech Stack
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Frontend&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Technology&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Language&lt;/td&gt;
&lt;td&gt;TypeScript&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Framework&lt;/td&gt;
&lt;td&gt;React&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Styling&lt;/td&gt;
&lt;td&gt;Tailwind CSS, Shadcn UI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dev Env&lt;/td&gt;
&lt;td&gt;Docker, Docker Compose&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hosting&lt;/td&gt;
&lt;td&gt;S3 + CloudFront&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Backend&lt;/strong&gt;&lt;br&gt;
None — it’s a frontend-only app.&lt;/p&gt;




&lt;h3&gt;
  
  
  System Architecture
&lt;/h3&gt;

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




&lt;h2&gt;
  
  
  Why I Built This
&lt;/h2&gt;

&lt;p&gt;This project started as a React learning exercise. I wanted to build something useful for developers while keeping it entirely frontend-based.&lt;/p&gt;

&lt;p&gt;At first, I considered building a &lt;code&gt;.gitignore&lt;/code&gt; generator, but similar tools already exist. Instead, I thought: &lt;strong&gt;“What if I add a feature to check whether a file will actually be ignored?”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Since I’ve personally run into situations where files were unexpectedly tracked (or ignored), this seemed like a practical idea.&lt;/p&gt;

&lt;p&gt;Eventually, I decided to keep it simple and focus only on the checking feature. That made the app easier to use and more focused.&lt;/p&gt;




&lt;h2&gt;
  
  
  Challenges I Faced
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Patterns like &lt;code&gt;.&lt;/code&gt; or &lt;code&gt;*&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
Handling them correctly was tricky—regex conflicts caused plenty of unexpected behavior.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Language toggle &amp;amp; layout issues&lt;/strong&gt;&lt;br&gt;
Switching between Japanese and English changes text length, which broke layouts. Styling had to account for that.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;File download limitations&lt;/strong&gt;&lt;br&gt;
I originally planned to let users export their &lt;code&gt;.gitignore&lt;/code&gt; file, but ran into restrictions: browsers don’t allow direct downloads with filenames starting with a dot.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Design Decisions &amp;amp; Improvements
&lt;/h2&gt;

&lt;p&gt;To make the app approachable even for first-time users, I focused on simplicity:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Default sample input and output are shown on load&lt;/li&gt;
&lt;li&gt;Minimal UI: mostly black and white, with color used only for results/errors&lt;/li&gt;
&lt;li&gt;Clear support for both Japanese and English&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;React alone can do more than expected&lt;/strong&gt;&lt;br&gt;
Previously, I always combined frontend + backend, but this project showed me how far you can go with just React.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Simple UIs are deceptively hard&lt;/strong&gt;&lt;br&gt;
Striking the balance between too little explanation (confusing) and too much (cluttered) was harder than I thought.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Less is more&lt;/strong&gt;&lt;br&gt;
By cutting extra features (like generating/downloading &lt;code&gt;.gitignore&lt;/code&gt; files), I reduced dev time, kept the UI clean, and improved usability of the core functionality.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Future Ideas
&lt;/h2&gt;

&lt;p&gt;I’d like to build more small, developer-focused tools like this. Maybe even a &lt;strong&gt;collection of utilities&lt;/strong&gt; that share components such as language toggling or upload/copy/reset buttons.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;.gitignore&lt;/code&gt; checker was a good experiment, and its components are reusable in other tools.&lt;/p&gt;




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

&lt;p&gt;This &lt;code&gt;.gitignore&lt;/code&gt; checker was inspired by real frustrations I’ve had when files weren’t being ignored as expected.&lt;/p&gt;

&lt;p&gt;I designed it to be intuitive for first-time users, but I’d love to hear feedback from developers who try it. Your opinions will help me improve and guide future projects.&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%2Fjqzp87xhvepnmqsg8rz7.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%2Fjqzp87xhvepnmqsg8rz7.png" alt="App Image" width="800" height="471"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Live Demo&lt;/strong&gt;: &lt;a href="https://d14csvmoeha0t5.cloudfront.net/" rel="noopener noreferrer"&gt;https://d14csvmoeha0t5.cloudfront.net/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Repo&lt;/strong&gt;: &lt;a href="https://github.com/a-k-0047/gitignore-checker-front" rel="noopener noreferrer"&gt;https://github.com/a-k-0047/gitignore-checker-front&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Questions
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Did you find this kind of &lt;code&gt;.gitignore&lt;/code&gt; checker useful or interesting?&lt;/li&gt;
&lt;li&gt;Have you ever run into a tricky situation where &lt;code&gt;.gitignore&lt;/code&gt; didn’t behave the way you expected?&lt;/li&gt;
&lt;li&gt;If you could add one more feature to this app, what would it be?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;Feel free to answer any of these&lt;/strong&gt; — I’d love to hear your thoughts!&lt;/p&gt;

</description>
      <category>git</category>
      <category>beginners</category>
      <category>portfolio</category>
      <category>react</category>
    </item>
    <item>
      <title>Automatically Backing Up a GitHub Repository to S3 with GitHub Actions</title>
      <dc:creator>ak0047</dc:creator>
      <pubDate>Sun, 14 Sep 2025 11:41:41 +0000</pubDate>
      <link>https://forem.com/a-k-0047/automatically-backing-up-a-github-repository-to-s3-with-github-actions-32dg</link>
      <guid>https://forem.com/a-k-0047/automatically-backing-up-a-github-repository-to-s3-with-github-actions-32dg</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I built a &lt;strong&gt;GitHub Actions workflow that automatically backs up GitHub repositories to AWS S3&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;The workflow is available as a template repository on GitHub:&lt;br&gt;&lt;br&gt;
👉 &lt;a href="https://github.com/a-k-0047/github-backup-template" rel="noopener noreferrer"&gt;github-backup-template&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;Feel free to try it out if you’re interested!&lt;/p&gt;




&lt;h2&gt;
  
  
  Motivation
&lt;/h2&gt;

&lt;p&gt;The idea came from this blog post I recently read:  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/zainulabdeenofficial/why-you-should-keep-multiple-backups-of-your-code-dont-rely-only-on-github-2j90"&gt;🚀 Why You Should Keep Multiple Backups of Your Code (Don’t Rely Only on GitHub)&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;The author emphasized the importance of &lt;strong&gt;not relying solely on GitHub&lt;/strong&gt; and keeping backups of your repositories. After reading it, I decided to set up my own backup system.  &lt;/p&gt;

&lt;p&gt;That article demonstrated how to automate local backups using cron or Task Scheduler. However, since my computer isn’t always running, I wanted a &lt;strong&gt;fully online, serverless approach&lt;/strong&gt;. That’s when I thought:&lt;br&gt;&lt;br&gt;
&lt;strong&gt;“Why not leverage GitHub Actions’ scheduled workflows?”&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;So, I gave it a try.&lt;/p&gt;




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

&lt;h3&gt;
  
  
  Workflow steps
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Run on schedule with GitHub Actions
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git clone --mirror&lt;/code&gt; the target repository
&lt;/li&gt;
&lt;li&gt;Create a bundle file
&lt;/li&gt;
&lt;li&gt;Upload the bundle to an S3 bucket
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What gets backed up
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Full commit history (all branches &amp;amp; tags)
&lt;/li&gt;
&lt;li&gt;Branch and tag references
&lt;/li&gt;
&lt;li&gt;Remote configuration &amp;amp; refs
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What doesn’t get backed up
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Issues / Pull Requests / Projects / Discussions / Actions history
&lt;/li&gt;
&lt;li&gt;Wiki or static files in GitHub Pages
&lt;/li&gt;
&lt;li&gt;Repository settings (e.g., Branch Protection rules)
&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;A couple of tricky points during implementation:&lt;/p&gt;

&lt;h3&gt;
  
  
  awscli installation
&lt;/h3&gt;

&lt;p&gt;Initially, I tried installing &lt;code&gt;awscli&lt;/code&gt; in the workflow runner and ran into errors. Turns out it’s already pre-installed on GitHub-hosted runners—so no installation step was needed.  &lt;/p&gt;

&lt;h3&gt;
  
  
  GitHub Personal Access Token authentication
&lt;/h3&gt;

&lt;p&gt;I first tried with &lt;strong&gt;Fine-grained Personal Access Tokens&lt;/strong&gt;, but authentication failed. Switching to a &lt;strong&gt;Classic Token with &lt;code&gt;repo&lt;/code&gt; scope&lt;/strong&gt; solved the issue.  &lt;/p&gt;

&lt;p&gt;Interestingly, GitHub Copilot was really helpful here—it suggested possible causes and fixes when my workflow runs failed.&lt;/p&gt;




&lt;h2&gt;
  
  
  Publishing the Template
&lt;/h2&gt;

&lt;p&gt;After testing it on my own repositories and confirming the backups worked, I decided to publish it as a template repository.  &lt;/p&gt;

&lt;p&gt;My reasons:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Someone else might find it useful
&lt;/li&gt;
&lt;li&gt;It adds to my portfolio
&lt;/li&gt;
&lt;li&gt;It gives me something to blog about
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other words, &lt;strong&gt;three birds with one stone&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;To make it easier for others to use, I:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Wrote all workflow comments in &lt;strong&gt;English&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Provided a &lt;strong&gt;multi-language README&lt;/strong&gt; (Japanese &amp;amp; English)
&lt;/li&gt;
&lt;li&gt;Added an &lt;strong&gt;MIT license&lt;/strong&gt; for clarity
&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;This project is still new, so I don’t have a detailed roadmap yet. But for now, my plans are:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run it for my own repositories for a while
&lt;/li&gt;
&lt;li&gt;Collect user feedback
&lt;/li&gt;
&lt;li&gt;Consider S3 lifecycle policies (storage cost optimization, automated deletion, etc.)
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you have suggestions for improvement, I’d love to hear them!&lt;/p&gt;




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

&lt;p&gt;This project started when reading an English blog post (as part of my language learning), which unexpectedly connected with something else I had learned earlier—GitHub Actions for automating React deployments.  &lt;/p&gt;

&lt;p&gt;It reminded me how valuable it is to keep gathering new inputs and ideas—you never know when they’ll connect.  &lt;/p&gt;

&lt;p&gt;Building this workflow was fun because I got to use &lt;strong&gt;GitHub Actions, GitHub Copilot, and AWS together&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
I’m looking forward to making more small tools like this that might help others—while enjoying the process.  &lt;/p&gt;

</description>
      <category>github</category>
      <category>aws</category>
      <category>devops</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Getting Started with IaC on AWS: Choosing Between CloudFormation, SAM, and CDK</title>
      <dc:creator>ak0047</dc:creator>
      <pubDate>Fri, 05 Sep 2025 11:26:18 +0000</pubDate>
      <link>https://forem.com/a-k-0047/getting-started-with-iac-on-aws-choosing-between-cloudformation-sam-and-cdk-2mmp</link>
      <guid>https://forem.com/a-k-0047/getting-started-with-iac-on-aws-choosing-between-cloudformation-sam-and-cdk-2mmp</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I’m currently building a React app.&lt;br&gt;
In the past, I hosted it on S3 + CloudFront, so I thought I’d do the same this time. I went ahead and created the resources using the AWS Management Console, but then I caught myself thinking:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;What settings did I use last time?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Did I misconfigure something this time?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Clicking through the console is such a hassle…&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s when I decided to look into &lt;strong&gt;how to provision AWS resources with IaC (Infrastructure as Code)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In this post, I’ll walk through the main IaC tools available on AWS, compare their strengths, and share recommendations for different development scenarios—frontend and backend.&lt;/p&gt;


&lt;h2&gt;
  
  
  Why IaC?
&lt;/h2&gt;

&lt;p&gt;Using IaC comes with some clear benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reproducible setups&lt;/strong&gt;&lt;br&gt;
→ Easily spin up multiple environments (e.g., dev, staging, prod).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Fewer human errors&lt;/strong&gt;&lt;br&gt;
→ No risk of misclicking in the console.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Automation-friendly&lt;/strong&gt;&lt;br&gt;
→ Since your infra is code, you can seamlessly integrate it into pipelines (e.g., GitHub Actions).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  IaC Options on AWS
&lt;/h2&gt;

&lt;p&gt;The three main IaC options in the AWS ecosystem are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CloudFormation&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AWS SAM (Serverless Application Model)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AWS CDK (Cloud Development Kit)&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here’s a quick overview:&lt;/p&gt;
&lt;h3&gt;
  
  
  CloudFormation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;AWS’s core IaC service&lt;/li&gt;
&lt;li&gt;Define resources in JSON or YAML&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pros&lt;/strong&gt;: Covers all AWS services, lots of official templates available&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cons&lt;/strong&gt;: Can get verbose; hard to manage at scale&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;→ Best for: &lt;strong&gt;“I want simple templates” or “I want to learn from AWS’s official examples.”&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  AWS SAM
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Built on top of CloudFormation&lt;/li&gt;
&lt;li&gt;Tailored for serverless apps (Lambda, API Gateway, DynamoDB, etc.)&lt;/li&gt;
&lt;li&gt;Handy CLI (&lt;code&gt;sam build&lt;/code&gt;, &lt;code&gt;sam local invoke&lt;/code&gt;, &lt;code&gt;sam deploy&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pros&lt;/strong&gt;: Minimal config for serverless workloads&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cons&lt;/strong&gt;: Not great for non-serverless services&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;→ Best for: &lt;strong&gt;“I want to quickly build &amp;amp; deploy a serverless app.”&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  AWS CDK
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Lets you define infra using programming languages (TypeScript, Python, Java, etc.)&lt;/li&gt;
&lt;li&gt;Compiles down to CloudFormation under the hood&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pros&lt;/strong&gt;: Use loops, conditionals, and abstractions—perfect for complex infra&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cons&lt;/strong&gt;: Slightly steeper learning curve&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;→ Best for: &lt;strong&gt;“I want to use my favorite language” or “I need to manage large/complex setups.”&lt;/strong&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Practical Examples
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Frontend Example: React on S3 + CloudFront
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Recommended&lt;/strong&gt;: CDK or CloudFormation&lt;/li&gt;
&lt;li&gt;Typical setup: Deploy React static files to S3, distribute via CloudFront&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;CDK Example (TypeScript):&lt;/strong&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="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;cdk&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;aws-cdk-lib&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="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;s3&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;aws-cdk-lib/aws-s3&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="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;cloudfront&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;aws-cdk-lib/aws-cloudfront&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;class&lt;/span&gt; &lt;span class="nc"&gt;FrontendStack&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;cdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Stack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;cdk&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="nx"&gt;id&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;props&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;cdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;StackProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&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="nx"&gt;props&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;bucket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Bucket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;FrontendBucket&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;websiteIndexDocument&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&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="na"&gt;publicReadAccess&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="p"&gt;});&lt;/span&gt;

    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;cloudfront&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CloudFrontWebDistribution&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;FrontendCDN&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;originConfigs&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;s3OriginSource&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;s3BucketSource&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="na"&gt;behaviors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;isDefaultBehavior&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="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;
  
  
  Serverless Backend Example: Lambda + API Gateway
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Recommended&lt;/strong&gt;: AWS SAM&lt;/li&gt;
&lt;li&gt;You can write it in CloudFormation, but SAM makes it much easier&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;SAM Example (YAML):&lt;/strong&gt;&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;AWSTemplateFormatVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;2010-09-09'&lt;/span&gt;
&lt;span class="na"&gt;Transform&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AWS::Serverless-2016-10-31&lt;/span&gt;
&lt;span class="na"&gt;Resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;HelloFunction&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AWS::Serverless::Function&lt;/span&gt;
    &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;Handler&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;app.lambda_handler&lt;/span&gt;
      &lt;span class="na"&gt;Runtime&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;python3.11&lt;/span&gt;
      &lt;span class="na"&gt;Events&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;ApiEvent&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Api&lt;/span&gt;
          &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;Path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/hello&lt;/span&gt;
            &lt;span class="na"&gt;Method&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;get&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Non-Serverless Backend Example: ECS + VPC + RDS
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Recommended&lt;/strong&gt;: CDK&lt;/li&gt;
&lt;li&gt;Great for managing complex infra like ECS + VPC + RDS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;CDK Example (ECS Fargate):&lt;/strong&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="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;ecs&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;aws-cdk-lib/aws-ecs&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="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;ec2&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;aws-cdk-lib/aws-ec2&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;vpc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ec2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Vpc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;MyVpc&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;cluster&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ecs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Cluster&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;MyCluster&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;vpc&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ecs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;FargateService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;MyService&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;cluster&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;taskDefinition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ecs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;FargateTaskDefinition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;TaskDef&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;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;CloudFormation&lt;/strong&gt;&lt;br&gt;
→ The fundamental tool for defining AWS infra in YAML/JSON.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;AWS SAM&lt;/strong&gt;&lt;br&gt;
→ Optimized for serverless apps, especially Lambda-heavy projects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;AWS CDK&lt;/strong&gt;&lt;br&gt;
→ Flexible, expressive, and powerful for complex or large-scale infra.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even if you’re used to clicking around in the AWS Console, adopting IaC unlocks big advantages: reproducibility, environment consistency, and automation.&lt;/p&gt;

&lt;p&gt;If you’re new to IaC, I recommend starting small—maybe with your frontend setup—then gradually tying it into CI/CD (like GitHub Actions) for full automation.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>aws</category>
      <category>infrastructureascode</category>
      <category>productivity</category>
    </item>
    <item>
      <title>What is GitHub Actions? A Beginner-Friendly Guide with Examples</title>
      <dc:creator>ak0047</dc:creator>
      <pubDate>Fri, 29 Aug 2025 06:06:25 +0000</pubDate>
      <link>https://forem.com/a-k-0047/what-is-github-actions-a-beginner-friendly-guide-with-examples-me</link>
      <guid>https://forem.com/a-k-0047/what-is-github-actions-a-beginner-friendly-guide-with-examples-me</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;When I was researching how to automate the deployment of a React app, I discovered that it can be done using &lt;strong&gt;GitHub Actions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;But then I thought:&lt;br&gt;
&lt;strong&gt;“What exactly is GitHub Actions?”&lt;/strong&gt;&lt;br&gt;
So I dug into it, and here’s a summary of what I learned.&lt;/p&gt;


&lt;h2&gt;
  
  
  What is GitHub Actions?
&lt;/h2&gt;

&lt;p&gt;GitHub Actions is a &lt;strong&gt;CI/CD platform provided by GitHub&lt;/strong&gt;.&lt;br&gt;
It allows you to define &lt;strong&gt;workflows that run automatically&lt;/strong&gt; in response to events in your GitHub repository—such as pushes, pull requests, or scheduled jobs.&lt;/p&gt;

&lt;p&gt;GitHub also provides the virtual machines (runners) where your workflows execute, so you don’t need to manage servers yourself.&lt;/p&gt;


&lt;h2&gt;
  
  
  What Can You Do with GitHub Actions?
&lt;/h2&gt;

&lt;p&gt;GitHub Actions is not just for deployment automation—it can cover the whole development lifecycle.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Automated Testing (CI)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automatically run tests whenever you push or open a pull request.&lt;/li&gt;
&lt;li&gt;Catch bugs early before merging.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Code Quality Checks&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run linters and formatters automatically.&lt;/li&gt;
&lt;li&gt;Enforce consistent coding style across the team.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Security Checks&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automate vulnerability scans (npm audit, pip-audit, etc.).&lt;/li&gt;
&lt;li&gt;Combine with Dependabot for automatic dependency updates.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Deployment Automation (CD)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deploy automatically to AWS, Vercel, Netlify, or S3 + CloudFront whenever changes are merged into main.&lt;/li&gt;
&lt;li&gt;No more manual uploads.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Scheduled Jobs&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Like cron jobs: run tasks daily, weekly, or on any schedule.&lt;/li&gt;
&lt;li&gt;Example: data collection, report generation, backups.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Notifications&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Send results to Slack, Discord, LINE, Teams, email, or any webhook.&lt;/li&gt;
&lt;li&gt;Get alerted immediately when something fails.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Issue / PR Management&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automatically label pull requests.&lt;/li&gt;
&lt;li&gt;Close inactive issues automatically.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;


&lt;h2&gt;
  
  
  Notifications
&lt;/h2&gt;

&lt;p&gt;GitHub Actions supports more than just GitHub’s built-in notifications. You can integrate with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;GitHub default notifications (UI + email)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Slack&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Discord&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LINE&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Teams / Google Chat&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Email (SMTP)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Custom Webhooks (send data to your own service)&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Writing a Workflow (YAML)
&lt;/h2&gt;

&lt;p&gt;Workflows in GitHub Actions are defined in &lt;strong&gt;YAML files&lt;/strong&gt; inside the &lt;code&gt;.github/workflows/&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;Here’s a minimal example:&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;My First Workflow&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;            &lt;span class="c1"&gt;# Trigger: when to run&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;         &lt;span class="c1"&gt;# Run when code is pushed&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;# Run when PR is opened&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;           &lt;span class="c1"&gt;# Define jobs&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="c1"&gt;# Runner environment&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;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run a command&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo "Hello, world!"&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@v4&lt;/span&gt;   &lt;span class="c1"&gt;# Use an existing action&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What Does &lt;code&gt;uses:&lt;/code&gt; Mean?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;uses:&lt;/code&gt; keyword is for &lt;strong&gt;reusing existing GitHub Actions (action)&lt;/strong&gt;.&lt;br&gt;
An “action” is a small automation script published on GitHub (either official or community-made).&lt;/p&gt;

&lt;p&gt;You can find thousands of actions in the &lt;a href="https://github.com/marketplace?type=actions" rel="noopener noreferrer"&gt;GitHub Marketplace&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Commonly Used Actions&lt;/strong&gt;&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="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@v4&lt;/span&gt;   &lt;span class="c1"&gt;# Checkout repository code into the runner&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/setup-node@v4&lt;/span&gt; &lt;span class="c1"&gt;# Setup a Node.js environment&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using actions lets you add common functionality without reinventing the wheel.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; If an action has multiple versions (e.g., @v4, @v5), it’s usually best to stick to the latest LTS or stable version unless your project requires otherwise.&lt;/p&gt;




&lt;h2&gt;
  
  
  Free Usage Limits
&lt;/h2&gt;

&lt;p&gt;GitHub Actions is free to use, but there are some limits depending on your plan.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Public Repositories&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Unlimited usage for free.&lt;/li&gt;
&lt;li&gt;Perfect for open-source projects.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Private Repositories&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;2,000 minutes per month of runtime for free.&lt;/li&gt;
&lt;li&gt;500 MB of storage included.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;For most hobby projects or small teams, the free tier is more than enough.&lt;/p&gt;




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

&lt;p&gt;To understand how it works, I created a simple workflow that just prints a message whenever I push or open a PR.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Steps:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a new empty repository.&lt;/li&gt;
&lt;li&gt;Inside it, create a &lt;code&gt;.github/workflows/&lt;/code&gt; directory.&lt;/li&gt;
&lt;li&gt;Add the following YAML file:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .github/workflows/hello.yml&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Hello GitHub Actions&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;pull_request&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;say-hello&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;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Say Hello&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo "Hello from GitHub Actions!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, push this repo to GitHub.&lt;br&gt;
You can see the workflow run under the &lt;strong&gt;Actions&lt;/strong&gt; tab in your repository.&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%2Frft86taolpcbi9o4x225.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%2Frft86taolpcbi9o4x225.png" alt="actions_run_image" width="800" height="505"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Example repo: &lt;a href="https://github.com/a-k-0047/actions-tutorial" rel="noopener noreferrer"&gt;actions-tutorial&lt;/a&gt;&lt;/p&gt;




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

&lt;p&gt;GitHub Actions is a &lt;strong&gt;powerful CI/CD platform&lt;/strong&gt; built right into GitHub.&lt;br&gt;
It can automate much more than just deployment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Testing&lt;/li&gt;
&lt;li&gt;Code quality checks&lt;/li&gt;
&lt;li&gt;Security scans&lt;/li&gt;
&lt;li&gt;Scheduled jobs&lt;/li&gt;
&lt;li&gt;Notifications&lt;/li&gt;
&lt;li&gt;Issue/PR management&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other words, it can &lt;strong&gt;automate your entire development workflow&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you have creative or unusual use cases for GitHub Actions, I’d love to hear them!&lt;/p&gt;




&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/features/actions" rel="noopener noreferrer"&gt;GitHub Actions Overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/actions" rel="noopener noreferrer"&gt;GitHub Actions Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>beginners</category>
      <category>github</category>
      <category>githubactions</category>
      <category>cicd</category>
    </item>
    <item>
      <title>My Personal Git Workflow Rules for Portfolio Projects</title>
      <dc:creator>ak0047</dc:creator>
      <pubDate>Mon, 18 Aug 2025 11:57:15 +0000</pubDate>
      <link>https://forem.com/a-k-0047/my-personal-git-workflow-rules-for-portfolio-projects-2hip</link>
      <guid>https://forem.com/a-k-0047/my-personal-git-workflow-rules-for-portfolio-projects-2hip</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;As I started publishing my personal web app projects as part of my portfolio, I decided to create &lt;strong&gt;a Git workflow rule for personal development&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;In this post, I’ll summarize the rules I came up with for my own projects.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I Decided to Set Git Rules
&lt;/h2&gt;

&lt;p&gt;Up until now, I hadn’t often joined projects with well-defined Git workflows, and in my personal projects, I hadn’t really set any rules either.  &lt;/p&gt;

&lt;p&gt;But since I’m publishing repositories as portfolio pieces, branches and commit history will be visible too. That made me realize: &lt;strong&gt;I need a workflow that’s easy for others to understand and easy for me to manage&lt;/strong&gt;.  &lt;/p&gt;




&lt;h2&gt;
  
  
  My Workflow Rules
&lt;/h2&gt;

&lt;p&gt;Here’s what I decided.&lt;/p&gt;

&lt;h3&gt;
  
  
  Branching
&lt;/h3&gt;

&lt;p&gt;I’ll structure branches as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;main&lt;/strong&gt;: always stable and deployable
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;feature/&lt;/strong&gt;*: for adding new features

&lt;ul&gt;
&lt;li&gt;e.g., &lt;code&gt;feature/login-page&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;fix/&lt;/strong&gt;*: for bug fixes

&lt;ul&gt;
&lt;li&gt;e.g., &lt;code&gt;fix/api-endpoint&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;docs/&lt;/strong&gt;*: for documentation updates

&lt;ul&gt;
&lt;li&gt;e.g., &lt;code&gt;docs/update-readme&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;This is inspired by &lt;a href="https://docs.github.com/en/get-started/using-github/github-flow" rel="noopener noreferrer"&gt;GitHub Flow&lt;/a&gt;.  &lt;/p&gt;

&lt;p&gt;There’s also &lt;a href="https://nvie.com/posts/a-successful-git-branching-model/" rel="noopener noreferrer"&gt;Git Flow&lt;/a&gt; by Vincent Driessen, but that’s typically used in larger, long-term projects.  &lt;/p&gt;




&lt;h3&gt;
  
  
  Commit Messages
&lt;/h3&gt;

&lt;p&gt;I’ll write commit messages in English, following &lt;a href="https://www.conventionalcommits.org/en/v1.0.0/" rel="noopener noreferrer"&gt;Conventional Commits&lt;/a&gt;.  &lt;/p&gt;

&lt;h4&gt;
  
  
  Message Format
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;&amp;lt;type&amp;gt;: &amp;lt;short description&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Types I use
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;feat&lt;/code&gt;: add a new feature
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fix&lt;/code&gt;: bug fix
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;docs&lt;/code&gt;: documentation only
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;style&lt;/code&gt;: formatting (no code changes)
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;refactor&lt;/code&gt;: refactoring
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;chore&lt;/code&gt;: configs, dependencies, etc.
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Examples
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;feat: add weather API integration
&lt;/li&gt;
&lt;li&gt;fix: correct date formatting issue
&lt;/li&gt;
&lt;li&gt;docs: add system architecture diagram to README
&lt;/li&gt;
&lt;li&gt;style: apply prettier formatting
&lt;/li&gt;
&lt;li&gt;refactor: extract API call into separate module
&lt;/li&gt;
&lt;li&gt;chore: update dependencies
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Commit Timing
&lt;/h3&gt;

&lt;p&gt;Here’s when I commit:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First commit:&lt;/strong&gt;&lt;br&gt;
After setting up the initial folder structure and dependencies (e.g., &lt;code&gt;package.json&lt;/code&gt;).  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Second commit:&lt;/strong&gt;&lt;br&gt;
Once the app has taken some shape.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After that:&lt;/strong&gt;&lt;br&gt;
Commit by feature or task unit.  &lt;/p&gt;

&lt;p&gt;This means there’s usually a gap between the first and second commit. That’s intentional: in the early stages I tend to experiment a lot with architecture and setup, and I don’t want those messy trial-and-error steps cluttering the history.  &lt;/p&gt;




&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;For my personal portfolio repositories, I decided to follow these rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Branching:&lt;/strong&gt; GitHub Flow style
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Commit messages:&lt;/strong&gt; Conventional Commits + English
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Commit timing:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;First commit: when the environment setup is ready
&lt;/li&gt;
&lt;li&gt;Second commit: when the app has taken shape
&lt;/li&gt;
&lt;li&gt;Afterwards: per task or feature
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;I’ll start with this workflow and adjust or expand it as needed.  &lt;/p&gt;

&lt;p&gt;If you have suggestions for even better Git practices, I’d love to hear them!  &lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
      <category>portfolio</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Managing Multiple Environments in AWS SAM (dev/prod)</title>
      <dc:creator>ak0047</dc:creator>
      <pubDate>Wed, 13 Aug 2025 10:49:18 +0000</pubDate>
      <link>https://forem.com/a-k-0047/managing-multiple-environments-in-aws-sam-devprod-4o6k</link>
      <guid>https://forem.com/a-k-0047/managing-multiple-environments-in-aws-sam-devprod-4o6k</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Separating development and production environments is essential&lt;/strong&gt;—even for personal projects.&lt;/p&gt;

&lt;p&gt;With &lt;a href="https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/what-is-sam.html" rel="noopener noreferrer"&gt;AWS SAM (Serverless Application Model)&lt;/a&gt;, it’s fairly easy to manage multiple environments by tweaking your template and configuration files.&lt;/p&gt;

&lt;p&gt;In this post, I’ll walk you through the exact method I use to separate and deploy &lt;code&gt;dev&lt;/code&gt; and &lt;code&gt;prod&lt;/code&gt; environments using AWS SAM.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Separate Environments?
&lt;/h2&gt;

&lt;p&gt;Here’s why I always create separate environments—even for solo projects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Prevent production issues before they happen&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reflect real-world projects where multi-environment setups are the norm&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This approach makes development, testing, and deployment safer and more realistic—especially when you're preparing for actual client work.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Manage Environments in AWS SAM
&lt;/h2&gt;

&lt;p&gt;By combining a few key features in AWS SAM, you can clearly separate deployments by environment.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Use &lt;code&gt;Parameters&lt;/code&gt; and &lt;code&gt;!Sub&lt;/code&gt; for Environment-Aware Naming
&lt;/h3&gt;

&lt;p&gt;In your &lt;code&gt;template.yaml&lt;/code&gt;, use the &lt;code&gt;Parameters&lt;/code&gt; section to define environment-specific values. Then apply those values dynamically with &lt;code&gt;!Sub&lt;/code&gt;.&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="c1"&gt;# template.yaml&lt;/span&gt;
&lt;span class="na"&gt;Parameters&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;Environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;String&lt;/span&gt;
    &lt;span class="na"&gt;Default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dev&lt;/span&gt;

&lt;span class="na"&gt;Resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;WeatherAppFunction&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AWS::Serverless::Function&lt;/span&gt;
    &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;FunctionName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Sub&lt;/span&gt; &lt;span class="s"&gt;weather-function-${Environment}&lt;/span&gt;
      &lt;span class="na"&gt;CodeUri&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lambdas/function/&lt;/span&gt;
      &lt;span class="na"&gt;Handler&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;app.lambda_handler&lt;/span&gt;
      &lt;span class="na"&gt;Runtime&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;python3.13&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;By passing &lt;code&gt;dev&lt;/code&gt; or &lt;code&gt;prod&lt;/code&gt; as a parameter, the resource names (like Lambda functions) are automatically environment-specific.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  2. Use &lt;code&gt;Globals&lt;/code&gt; for Shared Settings
&lt;/h3&gt;

&lt;p&gt;Common configurations across all Lambda functions—such as timeout or runtime—can be set using the &lt;code&gt;Globals&lt;/code&gt; section:&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="c1"&gt;# template.yaml&lt;/span&gt;
&lt;span class="na"&gt;Globals&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;Function&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt;
    &lt;span class="na"&gt;Runtime&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;python3.13&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;This helps you avoid repeating boilerplate settings across multiple functions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  3. Configure &lt;code&gt;samconfig.toml&lt;/code&gt; per Environment
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;samconfig.toml&lt;/code&gt; is a config file SAM reads when deploying. You can define environment-specific sections like &lt;code&gt;[dev.deploy.parameters]&lt;/code&gt; and &lt;code&gt;[prod.deploy.parameters]&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="c"&gt;# samconfig.toml&lt;/span&gt;
&lt;span class="nn"&gt;[dev.deploy.parameters]&lt;/span&gt;
&lt;span class="py"&gt;stack_name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"weather-app-dev"&lt;/span&gt;
&lt;span class="py"&gt;s3_prefix&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"weather-app-dev"&lt;/span&gt;
&lt;span class="py"&gt;region&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"ap-northeast-1"&lt;/span&gt;
&lt;span class="py"&gt;parameter_overrides&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="py"&gt;"Environment&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="err"&gt;dev&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;
&lt;span class="nn"&gt;[prod.deploy.parameters]&lt;/span&gt;
&lt;span class="py"&gt;stack_name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"weather-app-prod"&lt;/span&gt;
&lt;span class="py"&gt;s3_prefix&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"weather-app-prod"&lt;/span&gt;
&lt;span class="py"&gt;region&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"ap-northeast-1"&lt;/span&gt;
&lt;span class="py"&gt;parameter_overrides&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="py"&gt;"Environment&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="err"&gt;prod&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;parameter_overrides&lt;/code&gt; passes values to the &lt;code&gt;Parameters&lt;/code&gt; defined in &lt;code&gt;template.yaml&lt;/code&gt;, enabling you to reuse the same template across multiple environments.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To deploy with the appropriate config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Deploy to development&lt;/span&gt;
sam deploy &lt;span class="nt"&gt;--config-env&lt;/span&gt; dev

&lt;span class="c"&gt;# Deploy to production&lt;/span&gt;
sam deploy &lt;span class="nt"&gt;--config-env&lt;/span&gt; prod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Tip: Run &lt;code&gt;sam deploy --guided&lt;/code&gt; the first time to generate a &lt;code&gt;samconfig.toml&lt;/code&gt; file interactively.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  How Many Environments Should You Use?
&lt;/h2&gt;

&lt;p&gt;In my case, I keep it simple with two environments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;dev&lt;/code&gt;: for development and testing changes&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;prod&lt;/code&gt;: for production-ready deployments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unless your app handles sensitive data or requires complex staging, this setup is usually enough for personal projects.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Be mindful of cost—each environment may create its own resources.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;Even in serverless projects using AWS SAM, &lt;strong&gt;environment management is crucial&lt;/strong&gt;.&lt;br&gt;
Starting with clear separation between dev and prod will save you headaches later.&lt;/p&gt;

&lt;p&gt;If you have tips for structuring or automating environments in AWS SAM, I’d love to hear them!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>beginners</category>
      <category>cloud</category>
      <category>serverless</category>
    </item>
  </channel>
</rss>
