<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Natt Nguyen</title>
        <link>https://natt.sh</link>
        <description>My writings on tutorials, technologies, personal development, and reflective insights.</description>
        <lastBuildDate>Wed, 02 Sep 2026 01:23:35 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <image>
            <title>Natt Nguyen</title>
            <url>https://natt.sh/favicon.png</url>
            <link>https://natt.sh</link>
        </image>
        <atom:link href="https://natt.sh/rss.xml" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Testing React components with Bun]]></title>
            <link>https://natt.sh/blog/2024-12-09-testing-react-components-bun</link>
            <guid>https://natt.sh/blog/2024-12-09-testing-react-components-bun</guid>
            <pubDate>Tue, 10 Dec 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Learn how to test React components with Bun]]></description>
            <content:encoded><![CDATA[<p><img src="/images/blog/2024-12-09-testing-react-components-bun.png" alt=""></p>
<h2>Introduction</h2>
<p>In my recent exploration of testing React components, I was impressed by how quickly and easily I could set up Bun. The integrated testing functionality in Bun is incredibly fast and works seamlessly with both React and Next.js projects.</p>
<h2>Step 1: Install Required Packages</h2>
<p>To get started, install the necessary packages. Notice that there’s no need to install <code>jest</code> or <code>ts-node</code> with Bun:</p>
<code>bun add -D \<br />@happy-dom/global-registrator \<br />@testing-library/react \<br />@testing-library/dom \<br />@testing-library/jest-dom</code><h2>Step 2: Set Up Your Test Environment</h2>
<p>Create the following setup files to configure your testing environment.</p>
<code>// happydom.ts<br /><br />import { GlobalRegistrator } from "@happy-dom/global-registrator"<br /><br />GlobalRegistrator.register()</code><code>// testing-library.ts<br /><br />import * as matchers from "@testing-library/jest-dom/matchers"<br />import { cleanup } from "@testing-library/react"<br />import { afterEach, expect } from "bun:test"<br /><br />expect.extend(matchers)<br /><br />afterEach(() => {<br />  cleanup()<br />})</code><code>// testing-library.ts<br /><br />import * as matchers from "@testing-library/jest-dom/matchers"<br />import { cleanup } from "@testing-library/react"<br />import { afterEach, expect } from "bun:test"<br /><br />expect.extend(matchers)<br /><br />afterEach(() => {<br />  cleanup()<br />})</code><code># bunfig.toml<br /><br />[test]<br />preload = ["./happydom.ts", "./testing-library.ts"]</code><code>// matchers.d.ts<br /><br />import { TestingLibraryMatchers } from "@testing-library/jest-dom/matchers"<br />import "bun:test"<br /><br />declare module "bun:test" {<br />  interface Matchers<T><br />    extends TestingLibraryMatchers<typeof expect.stringContaining, T> {}<br />  interface AsymmetricMatchers extends TestingLibraryMatchers {}<br />}</code><h2>Step 3: Write Your Test</h2>
<p>With everything set up, you&#39;re now ready to test your components.</p>
<code>// button.test.tsx<br /><br />import Button from "@/components/button"<br />import { render } from "@testing-library/react"<br />import { describe, expect, it } from "bun:test"<br /><br />describe("Button Component", () => {<br />  it("renders a button with the correct default type and class name", () => {<br />    const { getByRole } = render(<Button />)<br />    const button = getByRole("button")<br />    expect(button).toHaveAttribute("type", "button")<br />  })<br />})</code><p>With these steps, you can quickly set up Bun for testing React components and enjoy fast, efficient test runs with minimal configuration.</p>
]]></content:encoded>
            <enclosure url="https://natt.sh/images/blog/2024-12-09-testing-react-components-bun.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[How to find the font name of any website]]></title>
            <link>https://natt.sh/blog/2024-09-02-website-inspect-font</link>
            <guid>https://natt.sh/blog/2024-09-02-website-inspect-font</guid>
            <pubDate>Tue, 03 Sep 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[A quick guide to uncovering the fonts used on any webpage.]]></description>
            <content:encoded><![CDATA[<p><img src="/images/blog/2024-04-14-database-server-proximity/thumbnail.png" alt=""></p>
<h2>Introduction</h2>
<p>Ever wondered what font a website is using? This blog post will teach you how to identify the fonts used on any website, whether you&#39;re a designer seeking inspiration or just a typography enthusiast.</p>
<h2>Browser extension</h2>
<p>I discovered this amazing tool called <a href="https://fontanello.app">Fontanello</a>, a browser extension to find out what font a webpage is using.</p>
<h2>Inpecting font file</h2>
<p>Sometimes a website would rename the font from the orginal name making it harder to identify even with Fontanello. If you open Chrome Developer Tools and go to &quot;Network&quot; tab and fitler &quot;Font&quot;, select a font. Right click on the font file name, and click on &quot;Open in Sources Panel&quot;. Once in &quot;Sources&quot; tab, right click once more and click on &quot;Open in new tab&quot;.</p>
<p>Now that you have downloaded the font file. There is another tool called <a href="https://fontdrop.info">FontDrop!</a> which makes it easy to get the meta data from the font file.</p>
]]></content:encoded>
            <enclosure url="https://natt.sh/images/blog/2024-04-14-database-server-proximity/thumbnail.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Speed up API endpoints by making database and server region closer]]></title>
            <link>https://natt.sh/blog/2024-04-14-database-server-proximity</link>
            <guid>https://natt.sh/blog/2024-04-14-database-server-proximity</guid>
            <pubDate>Mon, 15 Apr 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Improve API response times by positioning the database and server closer in proximity.]]></description>
            <content:encoded><![CDATA[<p><img src="/images/blog/2024-04-14-database-server-proximity/banner.png" alt=""></p>
<p>While I was watching Theo&#39;s <a href="https://www.youtube.com/watch?v=d5x0JCZbAJs">Modern React Tutorial video</a>(excellent video btw, I highly suggest watching), I didn&#39;t realize I can improve my API response times by going into Vercel&#39;s project settings and changing the region to be closer to my database region. I am not using edge compute so doing this would improve the API response times.</p>
<p>Originally, Vercel&#39;s Serverless Functions was set the &quot;Washington, D.C., USA (East) – iad1&quot; and my Supabase Postgres &quot;West US (North California) (us-west-1)&quot;. The distance is across the United States. There isn&#39;t a way to change the region on Supabase but I can change it on Vercel (in a project, under Settings =&gt; Functions =&gt; Function Region).</p>
<p><img src="/images/blog/2024-04-14-database-server-proximity/vercel.png" alt="Vercel&#39;s project settings"></p>
<p>Vercel&#39;s project settings</p>
<p><img src="/images/blog/2024-04-14-database-server-proximity/supabase.png" alt="Supabase&#39;s project settings"></p>
<p>Supabase&#39;s project settings</p>
<p>By changing Vercel&#39;s setting from USA East to USA West, the distance travelled is shorten from across the United States to across state. That was an easy optimization.</p>
]]></content:encoded>
            <enclosure url="https://natt.sh/images/blog/2024-04-14-database-server-proximity/banner.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Improve Next.js filenames readability in VSCode with custom tab labels]]></title>
            <link>https://natt.sh/blog/2024-04-13-vscode-custom-tab-labels</link>
            <guid>https://natt.sh/blog/2024-04-13-vscode-custom-tab-labels</guid>
            <pubDate>Sun, 14 Apr 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[When working with multiple files of the same name open in Next.js, distinguishing the different tabs can be hard.]]></description>
            <content:encoded><![CDATA[<p><img src="/images/blog/2024-04-13-vscode-custom-tab-labels/banner.png" alt=""></p>
<blockquote>
<p>I like names that are descriptive, that do not hide your code&#39;s true intent but illuminate it.
— Linus Torvalds</p>
</blockquote>
<p>Working with Next.js, it can be hard to identify which <code>page.tsx</code> belongs to which directory. Luckily VSCode has a way to have a <a href="https://code.visualstudio.com/docs/getstarted/userinterface#_customize-tab-labels">custom display label</a> to the tabs.</p>
<h2>1. UI way</h2>
<p>In VSCode, use the shortcut to open UI settings:</p>
<ol>
<li><code>command ⌘</code> + <code>shift</code> + <code>p</code></li>
<li>Type and go in &quot;Preferences: Open Settings (UI)&quot;</li>
<li>Type in search: &quot;Custom Labels&quot;</li>
<li>Add item</li>
<li>Type in:<ul>
<li>Item: <code>**/**.tsx</code> | Value: <code>${dirname}/${filename}</code> =&gt; <code>route.ts</code></li>
<li>Item: <code>**/**.ts</code> | Value: <code>${dirname}/${filename}</code> =&gt; <code>layout.tsx</code>, <code>page.tsx</code>, <code>template.tsx</code></li>
</ul>
</li>
</ol>
<h2>2. JSON way</h2>
<p>In VSCode, use the shortcut to open JSON settings:</p>
<ol>
<li><code>command ⌘</code> + <code>shift</code> + <code>p</code></li>
<li>Type and go in &quot;Preferences: Open User Setting (JSON)&quot;</li>
<li>Copy this config to your setting</li>
</ol>
<code>"workbench.editor.customLabels.patterns": {<br />  "**/**.ts": "${dirname}/${filename}", // route.ts<br />  "**/**.tsx": "${dirname}/${filename}" // layout.tsx, page.tsx, template.tsx<br />}</code><h2>Before and after</h2>
<p>Before:</p>
<p><img src="/images/blog/2024-04-13-vscode-custom-tab-labels/before.png" alt="iTerm2 setting theme"></p>
<p>After:</p>
<p><img src="/images/blog/2024-04-13-vscode-custom-tab-labels/after.png" alt="iTerm2 setting theme"></p>
<p>It is way easier to distinguish which file belongs to which directory.</p>
]]></content:encoded>
            <enclosure url="https://natt.sh/images/blog/2024-04-13-vscode-custom-tab-labels/banner.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Prevent Supabase project from pausing with GitHub Actions]]></title>
            <link>https://natt.sh/blog/2024-03-17-supabase-activity-scheduler</link>
            <guid>https://natt.sh/blog/2024-03-17-supabase-activity-scheduler</guid>
            <pubDate>Mon, 18 Mar 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Schedule a workflow in GitHub Actions to prevent your Supabase project from pausing in free tier.]]></description>
            <content:encoded><![CDATA[<p><img src="/images/blog/2024-03-17-supabase-activity-scheduler/banner.png" alt=""></p>
<blockquote>
<p>I never sleep, cause sleep is the cousin of death.
— Nas</p>
</blockquote>
<p>As an indie software builder, I have been searching for a database for my hobbyist projects. I appreciate Supabase&#39;s generous free tier, the speed of the database, and the clean user interface. Projects under the <a href="https://supabase.com/pricing">free tier plan</a> will pause after one week of inactivity, with Supabase sending warning emails before and when this occurs. You can easily unpause your Supabase project through the dashboard to get your apps up and running again. Opting for the paid tiers eliminates the pausing of inactive projects.</p>
<p>In this article, I&#39;ll show you how to create a <a href="https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows">GitHub Actions scheduled workflow</a> to call your API and prevent your Supabase project from pausing in the free tier. I will be using <a href="https://nextjs.org/docs/app/building-your-application/routing/route-handlers">Next.js App Router Route Handlers</a> to create an API to fetch data from the database to prevent Supabase project from pausing.</p>
<h2>GitHub Actions scheduled workflow</h2>
<code># .github/workflows/supabase-activity-scheduler.yml<br /><br />name: Supabase Activity Scheduler<br /><br />on:<br />  schedule:<br />    - cron: "0 0 * * 0,3" # Runs every Sunday and Wednesday<br />  workflow_dispatch:<br /><br />jobs:<br />  send-http-request:<br />    runs-on: ubuntu-latest<br /><br />    steps:<br />      - name: Send HTTP Request<br />        run: curl https://<YOUR_DOMAIN_NAME>/api/etc/supabase-activity-scheduler</code><p>The runtime of the workflow takes around 2 seconds to complete but you are billed for the entire minute. Keep in mind, the project will pause after one week of inactivity. Assuming this workflow runs at least once a week, you&#39;ll be consuming approximately 4.35 minutes out of the 2,000 minutes or 0.22% total monthly usage allotted in the <a href="https://docs.github.com/en/billing/managing-billing-for-github-actions/about-billing-for-github-actions">GitHub Free plan</a>. I would schedule twice a week just to be on the safer side.</p>
<h2>Next.js Route Handler (API)</h2>
<code>// app/api/etc/supabase-activity-scheduler/route.ts<br /><br />import { createClient } from "@supabase/supabase-js"<br /><br />const supabaseUrl = "<YOUR_SUPABASE_URL>"<br />const supabaseKey = "<YOUR_SUPABASE_KEY>"<br />const supabase = createClient(supabaseUrl, supabaseKey)<br /><br />export async function GET() {<br />  try {<br />    // Fetch data to prevent Supabase project from pausing<br />    const { data, error } = await supabase.from("user").select()<br />    if (error) throw new Error(error.message)<br />    return Response.json(data)<br />  } catch (error) {<br />    const message = (error as Error).message ?? "An error occurred."<br />    return Response.json({ error: message }, { status: 400 })<br />  }<br />}</code><p>Run of the mill API to fetch users.</p>
<p>With this step up, you don&#39;t need to worry about your apps not working from a paused Supabase project in free tier.</p>
<h2>Further notes</h2>
<p>If you aim to fully integrate into Supabase&#39;s ecosystem, you can conveniently <a href="https://supabase.com/docs/guides/functions/schedule-functions">schedule Supbase&#39;s edge functions</a> using <code>pg_cron</code> and <code>pg_net</code> extension directly from the dashboard.</p>
<p>If you are looking for a cron provider with a generous free tier, Vercel has a few listed <a href="https://vercel.com/guides/how-to-setup-cron-jobs-on-vercel#alternative-cron-providers">here</a>.</p>
]]></content:encoded>
            <enclosure url="https://natt.sh/images/blog/2024-03-17-supabase-activity-scheduler/banner.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Save time generating your git commit message]]></title>
            <link>https://natt.sh/blog/2023-02-13-generate-git-commit-message</link>
            <guid>https://natt.sh/blog/2023-02-13-generate-git-commit-message</guid>
            <pubDate>Tue, 14 Feb 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[No more time wasted crafting the perfect commit message.]]></description>
            <content:encoded><![CDATA[<p><img src="/images/blog/2023-02-13-generate-git-commit-message/thumbnail.png" alt=""></p>
<h2>Introduction</h2>
<blockquote>
<p>There are only two hard things in Computer Science: cache invalidation and naming things.
— Phil Karlton</p>
</blockquote>
<p>Developers should have good git commit messages for several reasons:</p>
<ul>
<li><strong>Clarity</strong>: Good commit messages provide clear and concise information about the changes made in the commit. This makes it easier for other developers to understand what changes were made and why.</li>
<li><strong>Documentation</strong>: Commit messages serve as documentation for the project, allowing developers to understand the history and evolution of the codebase.</li>
<li><strong>Collaboration</strong>: Good commit messages facilitate collaboration between developers by making it easier to track changes and resolve conflicts.</li>
<li><strong>Debugging</strong>: Clear commit messages can help with debugging, as they provide context and information about changes made to the code.</li>
<li><strong>Code maintenance</strong>: Well-written commit messages make it easier to maintain the codebase over time, as they provide a clear record of changes and the rationale behind them.</li>
</ul>
<p>Developers can now save time by generating your commit message using <strong>AI Commits</strong> by <a href="https://www.elmghari.com">Hassan El Mghari</a>.</p>
<h2>Installation</h2>
<p>We need a package manager and an Open AI API key. You can find the offical way to install <code>aicommits</code> <a href="https://github.com/Nutlope/aicommits#installation-and-usage">here</a>. In this order, we first need to globally install <code>aicommits</code>.</p>
<code>---<br />title: "Terminal"<br />lineStyleType: "terminal"<br />---<br /><br /># https://github.com/Nutlope/aicommits<br />npm install -g aicommits</code><p>Then we need a Open AI account to get an API key. After logging in or creating a free account, click on the profile popover on the top right or navigate to this link <a href="https://platform.openai.com/account/api-keys">here</a>.</p>
<p><img src="/images/blog/2023-02-13-generate-git-commit-message/open_ai_profile_popover.png" alt="Open AI profile popover">
<img src="/images/blog/2023-02-13-generate-git-commit-message/open_ai_create_api_key.png" alt="Open AI create API key">
<img src="/images/blog/2023-02-13-generate-git-commit-message/open_ai_copy_api_key.png" alt="Open AI copy API key"></p>
<p>Make sure you don&#39;t share your API key with others, or expose it in the browser or other client-side code. After copy the Open AI API key, paste in this command as so.</p>
<code>---<br />title: "Terminal"<br />lineStyleType: "terminal"<br />---<br /><br /># To activate Open AI with AI Commits<br />export OPENAI_API_KEY=PASTE_IN_YOUR_OPEN_AI_KEY_HERE</code><p>Now we are all set up. To use Commit AI, we need to git add all then run the following command in your git workflow:</p>
<code>---<br />title: "Terminal"<br />lineStyleType: "terminal"<br />---<br /><br /># Example git workflow<br />git add .<br /><br />aicommits<br /># ▲ Welcome to AICommits!<br /># ▲ Generating your AI commit message...<br /><br /># ▲ Commit message: Update README with TODOs and additional resources.<br /># ? Would you like to use this commit message? (Y / n)</code><h2>Final word</h2>
<p>There are compelling reasons to have good commit messages, especially when working in a team. Commit AI by <a href="https://www.elmghari.com">Hassan El Mghari</a> saves time in generating the perfect commit message.</p>
<p>The commit message for writing and creating this article is &quot;Add files and setup Open AI for Commit AI blog post.&quot; How cool is that!</p>
<p>We&#39;re finally done writing commit messages.</p>
]]></content:encoded>
            <enclosure url="https://natt.sh/images/blog/2023-02-13-generate-git-commit-message/thumbnail.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Slash Vercel deployment time in half with pnpm]]></title>
            <link>https://natt.sh/blog/2023-02-12-pnpm-vercel-deployment</link>
            <guid>https://natt.sh/blog/2023-02-12-pnpm-vercel-deployment</guid>
            <pubDate>Mon, 13 Feb 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Developers can focus on creating better user experiences and delivering high-quality projects, rather than waiting for long deployment times on Vercel with pnpm.]]></description>
            <content:encoded><![CDATA[<p><img src="/images/blog/2023-02-12-pnpm-vercel-deployment/thumbnail.png" alt=""></p>
<h2>Introduction</h2>
<p>pnpm halved my web project deployment time on Vercel. It went from a little more than a minute to less than half a minute, <strong>around 50% faster</strong>. That is incredible! Considering there isn&#39;t a significant negative tradeoff. Switching from npm feels like a free speed upgrade on Vercel.</p>
<p>But what is pnpm?</p>
<p>pnpm (performance NPM) is a fast, disk space-efficient, and dependable package manager for JavaScript and Node.js. It is an alternative to the popular npm (Node Package Manager) and Yarn package managers, and it aims to improve the performance and reliability of dependency management in Node.js projects.</p>
<p>pnpm uses a novel method of storing packages and their dependencies in a shared store, which allows it to achieve faster install times, reduce disk space usage, and improve consistency across different projects. pnpm also supports most of the npm CLI commands and works seamlessly with existing npm projects, making it easy to adopt and use.</p>
<h2>Installation</h2>
<p>You can find the offical way to install <code>pnpm</code> <a href="https://pnpm.io/installation">here</a>. I prefer installing software with Homebrew when I can.</p>
<code>---<br />title: "Terminal"<br />lineStyleType: "terminal"<br />---<br /><br /># Install on Windows with PowerShell<br />iwr https://get.pnpm.io/install.ps1 -useb | iex<br /><br /># Install on POSIX systems with curl<br />curl -fsSL https://get.pnpm.io/install.sh | sh -<br /><br /># Install on POSIX systems with wget<br />wget -qO- https://get.pnpm.io/install.sh | sh -<br /><br /># Install on Alpine Linux with bash<br />wget -qO- https://get.pnpm.io/install.sh | ENV="~/.bashrc" SHELL="$(which bash)" bash -<br /><br /># Install on Alpine Linux with sh<br />wget -qO- https://get.pnpm.io/install.sh | ENV="~/.shrc" SHELL="$(which sh)" sh -<br /><br /># Install on Alpine Linux with dash<br />wget -qO- https://get.pnpm.io/install.sh | ENV="~/.dashrc" SHELL="$(which dash)" dash -<br /><br /># Install with npm<br />npm install -g pnpm<br /><br /># Install with Homebrew<br />brew install pnpm</code><p>Then in your web project, delete <code>package.lock.json</code> or <code>yarn.lock</code>.</p>
<code>---<br />title: "Terminal"<br />lineStyleType: "terminal"<br />---<br /><br /># npm install<br />pnpm install<br /><br /># npm install <package><br />pnpm add <package><br /><br /># npm run dev<br />pnpm dev</code><p>In the future, <code>pnpm</code> might ship with the shorter <code>pn</code> alias (<a href="https://twitter.com/pnpmjs/status/1624078742439043073">Twitter</a>). You can use the shorter <code>pn</code> alias now with the <code>alias</code> command on terminal.</p>
<code>---<br />title: "Terminal"<br />lineStyleType: "terminal"<br />---<br /><br />alias pn=pnpm</code><h2>Final word</h2>
<p>It will have <code>pnpm-lock.yaml</code> in your root directory in your web project. Vercel is smart and automatically detect the change of package management making it a intuitive and wonderful developer experience. After two deployments, you will see the pnpm caching on Vercel and the deployment speed boost.</p>
<p>If you find yourself overwhelmed with different web project and its own package manager, there is <code>@antfu/ni</code> (<a href="https://github.com/antfu/ni">GitHub</a>), which helps you automatically use right package manager.</p>
<p>Get ready to experience lightning fast deployments with pnpm on Vercel.</p>
]]></content:encoded>
            <enclosure url="https://natt.sh/images/blog/2023-02-12-pnpm-vercel-deployment/thumbnail.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[How to stash untracked or new files]]></title>
            <link>https://natt.sh/blog/2023-02-03-stash-untracked-files</link>
            <guid>https://natt.sh/blog/2023-02-03-stash-untracked-files</guid>
            <pubDate>Sat, 04 Feb 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Most senior engineers do not know about this flag when stashing their work.]]></description>
            <content:encoded><![CDATA[<p><img src="/images/blog/2023-02-03-stash-untracked-files/thumbnail.png" alt=""></p>
<h2>Introduction</h2>
<p>You have just worked hard on a new software feature. You know for sure that there are new changes on <code>main</code> branch since you have last pulled down.</p>
<ol>
<li>You want to create a new pull request with the latest on <code>main</code> branch to avoid merge conflicts.</li>
<li>You type in <code>git pull</code> but you recieved an error message that you need to commit your work first before pulling.</li>
<li>You tried <code>git stash</code> but the command does not stash the new files.</li>
<li>So what you do is open Notes or copy the new files somewhere so you could include the new file back after retreiving the latest updates.</li>
</ol>
<p>Or you might run a series of command do just that. You thought to yourself why doesn&#39;t <code>git stash</code> just include new files keep doing your process to create a merge request.</p>
<h2>The better way</h2>
<p>By adding the <code>--include-untracked</code> flag with <code>git stash</code>, you can also stash untracked or new files.</p>
<code>---<br />title: "Terminal"<br />lineStyleType: "terminal"<br />---<br /><br /># Reference: https://git-scm.com/docs/git-stash<br />git stash --include-untracked<br /><br /># or<br /><br />git stash -u</code><h2>Optimizing</h2>
<p>I don&#39;t know about you but I would never remember this unless I frequency run this command. You can have this command line shortcut with an alias. An alias lets you create a shortcut name for a command, file name, or any shell text.</p>
<code>---<br />title: "Terminal"<br />lineStyleType: "terminal"<br />---<br /><br />alias stashall="git stash --include-untracked"</code><p>You can totally be creative when comming up with you own alias name that appeals to you like <code>stasha</code> or <code>sa</code> instead of <code>stashall</code>.</p>
<p>There is also a GUI way of doing stashing if you use Visual Studio Code. I tend to stash my changes using this method.</p>
<p><img src="/images/blog/2023-02-03-stash-untracked-files/gui-stash-include-untrack.png" alt="iTerm2 setting theme"></p>
<h2>Final thoughts</h2>
<p>I was a bit embarrassed that I have been using <code>git</code> for as long as I have and never came across this flag for this command. To my astonishment, no one in my team of junior, mid, and mostly senior level engineers in my massive tech company knew about it either.</p>
<p>This may be small, but I noticed people who are optimized, tend achieve more during the day.</p>
]]></content:encoded>
            <enclosure url="https://natt.sh/images/blog/2023-02-03-stash-untracked-files/thumbnail.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Simple Homebrew command list and iTerm2 configuration]]></title>
            <link>https://natt.sh/blog/2023-01-28-terminal-configuration</link>
            <guid>https://natt.sh/blog/2023-01-28-terminal-configuration</guid>
            <pubDate>Sun, 29 Jan 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[My setup would speed up your onboarding on your new work MacOS machine and migrate risk of incorrectly installing a program as while having a beautiful terminal.]]></description>
            <content:encoded><![CDATA[<p><img src="/images/blog/2023-01-28-terminal-configuration/thumbnail.png" alt=""></p>
<h2>Introduction</h2>
<blockquote>
<p>Speed, it seems to me, provides the one genuinely modern pleasure.
-- Aldous Huxley</p>
</blockquote>
<p>Junior web developers often download and install programs through a website. My setup would speed up your onboarding on your new work MacOS machine and migrate risk of incorrectly installing a program as while having a beautiful terminal. I will show you my personal setup and configuration for terminal and Visual Studio Code in MacOS. One of the first thing I do with a new Mac machine is install Homebrew.</p>
<h2>Homebrew</h2>
<p>Homebrew is a package manager for macOS that allows users to easily install and manage software on their computers. Some benefits of using Homebrew include:</p>
<ul>
<li><strong>Easy installation and management of software</strong>: Homebrew makes it easy to install and manage software on macOS. Users can easily search for, install, and update software using simple command-line commands.</li>
<li><strong>Access to a wide variety of software</strong>: Homebrew offers a large and growing collection of software packages, including many that are not available through Apple&#39;s App Store or other package managers.</li>
<li><strong>Consistency across different systems</strong>: Homebrew helps to ensure that software is installed and configured consistently across different systems, making it easier to manage and maintain software in a multi-user or multi-system environment.</li>
<li><strong>Open-source</strong>: Homebrew is an open-source project, which means that it is developed and maintained by a community of contributors. This can help to ensure that the software is well-maintained and regularly updated.</li>
</ul>
<p>So let&#39;s open <code>terminal.app</code> and run these command to install:</p>
<code>---<br />title: "Terminal"<br />lineStyleType: "terminal"<br />---<br /><br /># Reference: https://brew.sh<br /><br /># Install Homebrew<br />/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"<br /><br /># ...<br /># ==> Checking for `sudo` access (which may request your password)...<br /># After pressing return, enter your Mac password<br /><br /># ...<br /># Press RETURN/ENTER to continue or any other key to abort:<br /># You will be prompted to press return when the terminal tells you it will install Xcode Command Line Tools<br /><br /># Downloading and installing Xcode Command Line Tools would take the most time<br /><br /># After Homebrew is installed, I would opt out of analytics<br />brew analytics off</code><p>Sweet! Now that Homebrew is installed, we can start downloading and installing programs through the terminal. You can see the list of things you can install:</p>
<ul>
<li>formulae (packages like <code>node</code>): <a href="https://formulae.brew.sh/formula">https://formulae.brew.sh/formula</a></li>
<li>cask (Apps like <code>Google Chrome.app</code>): <a href="https://formulae.brew.sh/cask">https://formulae.brew.sh/cask</a></li>
</ul>
<p>Let&#39;s get iTerm2.</p>
<code>---<br />title: "Terminal"<br />lineStyleType: "terminal"<br />---<br /><br /># Reference: https://formulae.brew.sh/cask/iterm2<br />brew install --cask iterm2</code><p>What just happen after running that command successfully is now we have iTerm2 installed on your computer. If you search with Spotlight or navigate to Applications in Finder, you will see <code>iTerm2.app</code>.</p>
<p>I don&#39;t use the native MacOS terminal, unstead use iTerm2 as a complete replacement for Terminal mainly because of customizability and plugin support. Often times when you see a aesthetically pleasing terminal on MacOS, they are using iTerm2. Many developers like customizating their terminal because they spend a lot of time looking at it and some theme do hold utility like color constrast and status information. The plugin support allows me to be proficient with my commands or typing.</p>
<p>Open <code>iTerm2.app</code> and let&#39;s install fonts to customize terminal and later Visual Studio Code.</p>
<code>---<br />title: "Terminal"<br />lineStyleType: "terminal"<br />---<br /><br /># Reference: https://github.com/Homebrew/homebrew-cask-fonts<br />brew tap homebrew/cask-fonts<br />brew install --cask font-inter<br />brew install --cask font-jetbrains-mono-nerd-font</code><h2>iTerm2</h2>
<blockquote>
<p>Sometimes, homely things are done for the best reasons in the world and thus achieve a beauty of their own.
-- Gene Weingarten</p>
</blockquote>
<p>Awesome! We just installed font through the terminal. Let&#39;s customizise the look of iTerm2 to how I would. Navigate to <code>iTerm2 &gt; Settings &gt; Appearance &gt; General</code> and let&#39;s change the theme dropdown from the default regular to minimal. I like the uniform look.</p>
<p><img src="/images/blog/2023-01-28-terminal-configuration/iterm2_setting_theme.png" alt="iTerm2 setting theme"></p>
<p>We are going to change the font of iTerm2 now. Navigate to <code>iTerm2 &gt; Settings &gt; Profile &gt; Text</code> and let&#39;s change the font dropdown to <code>JetBrainsMono Nerd Font Mono</code>.</p>
<p><img src="/images/blog/2023-01-28-terminal-configuration/iterm2_setting_font.png" alt="iTerm2 setting font"></p>
<p>The final thing in iTerm2&#39;s setting I configure is key mappings. You know how in Google Documents or any text editor, we can do <code>command + &lt;-</code> or <code>command + -&gt;</code> to go to front and back of the line. I want natural key mapping in my terminal instead of the default. Navigate to <code>iTerm2 &gt; Settings &gt; Profile &gt; Keys &gt; Key Mappings</code> and let&#39;s change the preset dropdown to <code>Natural Text Editing</code>.</p>
<p><img src="/images/blog/2023-01-28-terminal-configuration/iterm2_setting_keys.png" alt="iTerm2 setting keys"></p>
<p>When you change the key preset, it will prompt you whether to remove all key mappings before loading preset and I would remove.</p>
<p><img src="/images/blog/2023-01-28-terminal-configuration/iterm2_setting_keys_remove.png" alt="iTerm2 setting keys remove"></p>
<p>Nice! Now we have natural key mapping in your terminal. My favorite commands are:</p>
<ul>
<li>Delete whole line: <code>command + delete</code></li>
<li>Jump word: <code>option + &lt;-</code> <code>option + -&gt;</code></li>
<li>Jump line: <code>command + &lt;-</code> <code>command + -&gt;</code></li>
</ul>
<p>Next up, we are going to add some utility to our terminal. The utility I am going to add is Starship. Starship shows status infomation like project name, icon, branch and node version in projects. The second utility is autosuggestions. It would show suggestions, and you can press tab to accept the suggestion command. These two utilities are great addition to our developers experience.</p>
<p><img src="/images/blog/2023-01-28-terminal-configuration/iterm2_utilities.png" alt="iTerm2 utilities"></p>
<code>---<br />title: "Terminal"<br />lineStyleType: "terminal"<br />---<br /><br /># Reference: https://formulae.brew.sh/formula/starship<br />brew install starship<br /><br /># Reference: https://formulae.brew.sh/formula/zsh-autosuggestions<br />brew install zsh-autosuggestions</code><p>After we install those things, we need to configure the <code>.zshrc</code> file. It is unintuitive to write out Neovim or Vim commands to edit a file. The easiest way I edit the files is through Visual Studio Code with the <code>code</code> command.</p>
<p>Let&#39;s install Visual Studio Code.</p>
<code>---<br />title: "Terminal"<br />lineStyleType: "terminal"<br />---<br /><br /># Reference: https://formulae.brew.sh/cask/visual-studio-code<br />brew install --cask visual-studio-code</code><p>Excellent, now that we have Visual Studio Code installed, we have access to the <code>code</code> command to edit the <code>.zshrc</code> file.</p>
<code>---<br />title: "Terminal"<br />lineStyleType: "terminal"<br />---<br /><br /># Opens `.zshrc` file in Visual Studio Code<br />code ~/.zshrc</code><p>Opening files and editing files is a useful developer skill. Newer generation developers tend to go the user interface route like editing with Visual Studio Code instead through terminal.</p>
<p>Let&#39;s add these configuration to complete the utility setup.</p>
<code>---<br />title: ".zshrc"<br />lineStyleType: "code"<br />---<br /><br /># Starship<br />eval "$(starship init zsh)"<br /><br /># Autosuggestions<br />source $(brew --prefix)/share/zsh-autosuggestions/zsh-autosuggestions.zsh</code><p>We need to restart our terminal for the configurations to take effect. Quit iTerm2 with the shortcut <code>command + q</code> and then reopen it. And voila, your terminal looks ballin.</p>
<h2>Homebrew list</h2>
<p>I have this snippet on my Notion to fast track software installation if I reset or receive a MacOS machine.</p>
<code>---<br />title: "Terminal"<br />lineStyleType: "terminal"<br />---<br /><br /># Install Homebrew<br />/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"<br /><br /># Opt out of analytics<br />brew analytics off<br /><br /># Install must-haves<br /># Software<br />brew install --cask figma<br />brew install --cask google-chrome<br />brew install --cask iterm2<br />brew install --cask raycast<br />brew install --cask visual-studio-code<br /><br /># Fonts<br />brew tap homebrew/cask-fonts<br />brew install --cask font-jetbrains-mono-nerd-font<br />brew install --cask font-inter<br /><br /># Utility<br />brew install starship<br />brew install zsh-autosuggestions<br /><br /># zshrc configuration<br /># code ~/.zshrc<br /><br /># # Starship<br /># eval "$(starship init zsh)"<br /><br /># # Autosuggestions<br /># source $(brew --prefix)/share/zsh-autosuggestions/zsh-autosuggestions.zsh<br /><br /># iTerm2 settings<br /># iTerm2 > Settings > Appearance > General<br /># Theme: Minimal<br /><br /># iTerm2 > Settings > Profile > Text<br /># Font: JetBrainsMono Nerd Font Mono<br /><br /># iTerm2 > Settings > Profile > Keys > Key Mappings<br /># Preset: Natural Text Editing<br /><br /># Potential level 1<br />brew install --cask airbuddy<br />brew install --cask cleanshot<br />brew install --cask ledger-live<br />brew install --cask minecraft<br />brew install --cask raindropio<br />brew install --cask spotify<br /><br /># Potential level 2<br />brew install --cask firefox<br />brew install --cask microsoft-edge<br />brew install --cask tableplus</code>]]></content:encoded>
            <enclosure url="https://natt.sh/images/blog/2023-01-28-terminal-configuration/thumbnail.png" length="0" type="image/png"/>
        </item>
    </channel>
</rss>