IndieCoder https://indiecoder.vercel.app/ Recent Posts on IndieCoder Hugo en [email protected] (Hein Thant) [email protected] (Hein Thant) indiecoder Sat, 03 Jan 2026 00:00:00 +0000 My Year in Code 2025 https://indiecoder.vercel.app/blogs/dev-wrap-2025/ Sat, 03 Jan 2026 00:00:00 +0000[email protected] (Hein Thant) https://indiecoder.vercel.app/blogs/dev-wrap-2025/ <p>This is my yearly wrap up of the things I built in 2025. I worked on a bunch of side projects again this year, and these are the ones that actually turned into something I&rsquo;m proud of.</p> <p>I learned a lot from some of these projects. Some were pure curiosity. Some were just me building a random idea late at night because it would not leave my head.</p> <h2 id="badee-meditation-app">Badee: Meditation app</h2> <p><img src="https://indiecoder.vercel.app/img/badee.png" alt="App screenshot"></p> Absolute Neovim https://indiecoder.vercel.app/blogs/absolute-nvim/ Tue, 30 Dec 2025 00:00:00 +0000[email protected] (Hein Thant) https://indiecoder.vercel.app/blogs/absolute-nvim/ <p>I&rsquo;ve been using <code>kickstart.nvim</code> for over a year, and now I&rsquo;m finally ready to start my own Neovim journey. By <em>&ldquo;my own&rdquo;</em> I mean I&rsquo;m writing configs myself, but I&rsquo;ll still be copying from everywhere because that&rsquo;s how this works.</p> <p>My goal is to keep things as minimal as I can without loading unnecessary plugins. But if I just really like a plugin or it saves me from boring work, I&rsquo;ll use it.</p> My Rubber Duck Has Read the Docs https://indiecoder.vercel.app/blogs/my-ai-rubber-duck/ Sat, 07 Jun 2025 00:00:00 +0000[email protected] (Hein Thant) https://indiecoder.vercel.app/blogs/my-ai-rubber-duck/ <p>Today while I was building a number memory game with React, I encountered a strange behaviour with input focus.</p> <p>There was a grid of input fields and I wanted to auto-focus next inputs sequentially after entering a number - a standard OTP-input feature. The first input was auto-focused on mount with <code>useEffect</code> so there was no problem. But the auto-focus just wouldn&rsquo;t work on the second input. However, once the second one was focused manually, the rest of the flow worked fine.</p> The 3x5 Life Hack https://indiecoder.vercel.app/blogs/3x5-life-hack/ Sun, 18 May 2025 00:00:00 +0000[email protected] (Hein Thant) https://indiecoder.vercel.app/blogs/3x5-life-hack/ <p>You don&rsquo;t have to wake up at 5 a.m., grind for 3 hrs in the gym, or write a 2-pages essay in your journal to become a better version of yourself. You only need <em>0.01%</em> of your day - <em>just 15 min</em> - to energize your body, gain mental clarity and achieve your goals.</p> <h2 id="3-habits-5-minutes-each">3 habits, 5 minutes each</h2> <p>I&rsquo;m a <em>vibe-driven productivity</em> guy. Which just means I am ambitious, but lazy, inconsistent and have low discipline. Some days I&rsquo;m in flow, giving my all, but on others, I&rsquo;m just floating through. I&rsquo;ve been searching a system that I can stick to, something simple, doable, and actually effective. Then I came up with this idea of <strong>3x5 Life Hack</strong>.</p> Telegram Bot in Go https://indiecoder.vercel.app/blogs/go-telegram-bot/ Sat, 10 May 2025 00:00:00 +0000[email protected] (Hein Thant) https://indiecoder.vercel.app/blogs/go-telegram-bot/ <p>I recently built a simple Telegram bot using Go. The bot is designed to help users find information of a specific date. For example, if you send a message like &ldquo;2025-01-10&rdquo;, the bot will respond with basic calendar information, fetched events and birthdays from Wikipedia, and a APOD image from NASA api.</p> <p>I&rsquo;ll walk you through how I built it, and for the sake of simplicity, I&rsquo;ll skip detailed implementation and just show the necessary parts. You can see the full source code here: <a href="https://github.com/IndieCoderMM/tele-droids/tree/master/chronobot">github.com/IndieCoderMM/tele-droids</a></p> Unhooked from YouTube https://indiecoder.vercel.app/blogs/unhooked-from-youtube/ Thu, 01 May 2025 22:00:00 +0630[email protected] (Hein Thant) https://indiecoder.vercel.app/blogs/unhooked-from-youtube/ <p>I regularly find myself distracted by YouTube. I often start watching a video and then get lost in the endless videos that I never intended to watch. One time, I opened YouTube to search a tutorial while doing a project. But before I could open the search box, the algorithm (who knows me too well) presented a dozen of interesting videos. By the time I noticed, I&rsquo;d watched an hour of unrelated videos and had no clue what I was doing in the first place.</p> My Dev Environment Setup https://indiecoder.vercel.app/blogs/my-dev-env/ Thu, 01 May 2025 09:00:00 +0630[email protected] (Hein Thant) https://indiecoder.vercel.app/blogs/my-dev-env/ <p>I recently installed a new OS on my machine and decided to document my setup process.</p> <h2 id="os">OS</h2> <div class="highlight"><pre tabindex="0" style="color:#d0d0d0;background-color:#202020;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#40ffff">NAME</span>=<span style="color:#ed9d13">&#34;Pop!_OS&#34;</span> </span></span><span style="display:flex;"><span><span style="color:#40ffff">VERSION</span>=<span style="color:#ed9d13">&#34;22.04 LTS&#34;</span> </span></span><span style="display:flex;"><span><span style="color:#40ffff">ID</span>=pop </span></span><span style="display:flex;"><span><span style="color:#40ffff">ID_LIKE</span>=<span style="color:#ed9d13">&#34;ubuntu debian&#34;</span> </span></span></code></pre></div><h2 id="terminal-setup-wezterm">Terminal Setup: Wezterm</h2> <ol> <li>Download wezterm: <a href="https://wezterm.org/install/linux.html#installing-on-linux-using-appimage">Wezterm installation</a></li> <li>Make appimage executable: <code>chmod +x wezterm.appimage</code></li> <li>Move appimage to bin: <code>sudo mv wezterm.appimage /usr/local/bin/wezterm</code></li> <li>Add config file: <a href="https://gist.github.com/IndieCoderMM/96e9582f676ffaa7ce0aa04b65f1e840">Wezterm Config</a></li> </ol> <h2 id="cli-tools">CLI Tools</h2> <ol> <li><strong>NVM</strong> (Node manager): <code>curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.2/install.sh | bash</code></li> <li><strong>LazyGit</strong> (Git TUI): <a href="https://github.com/jesseduffield/lazygit">Repo</a></li> <li><strong>FZF</strong> (Filter program): <code>sudo apt install fzf</code></li> <li><strong>Zoxide</strong> (Better cd): <code>curl -sSfL https://raw.githubusercontent.com/ajeetdsouza/zoxide/main/install.sh | sh</code></li> <li><strong>Bpytop</strong> (Resource monitoring): <code>sudo apt install bpytop</code></li> <li><strong>OneFetch</strong> (Git info): <a href="https://github.com/o2sh/onefetch">Repo</a></li> <li><strong>RipGrep</strong> (Search tool): <code>sudo apt-get install ripgrep</code></li> <li><strong>LazyDocker</strong> (Docker TUI): <a href="https://github.com/jesseduffield/lazydocker">Repo</a></li> <li><strong>DirEnv</strong> (Env manager): <a href="https://github.com/direnv/direnv">Repo</a></li> </ol> <h2 id="shell-setup-oh-my-zsh">Shell Setup: Oh My Zsh</h2> <ol> <li>Download zsh: <code>sudo apt install zsh</code></li> <li>Make it default shell: <code>chsh -s $(which zsh)</code></li> <li>Restart the machine and check: <code>echo $SHELL</code></li> <li>Install oh-my-zsh: <a href="https://github.com/ohmyzsh/ohmyzsh">Repo</a></li> <li>Add config file <em>(Require CLI tools installation)</em>: <a href="https://gist.github.com/IndieCoderMM/96e9582f676ffaa7ce0aa04b65f1e840">Zsh Config</a></li> </ol> <h2 id="editor-setup-neovim">Editor Setup: Neovim</h2> <ol> <li>Download neovim: <a href="https://github.com/neovim/neovim/releases">Latest Neovim releases</a></li> <li>Run: <code>chmod u+x nvim-linux-x86_64.appimage</code></li> <li>Move to bin: <code>sudo mv nvim-linux-x86_64.appimage /usr/local/bin/nvim</code></li> <li>Clone config to <code>~/.config/nvim</code>: <a href="https://github.com/IndieCoderMM/nvim-config">IndieCoderMM/nvim-config</a></li> <li>Run <code>nvim</code> to setup and install deps.</li> </ol> <div class="highlight"><pre tabindex="0" style="color:#d0d0d0;background-color:#202020;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#999;font-style:italic"># Main plugins</span> </span></span><span style="display:flex;"><span>1. Lazy </span></span><span style="display:flex;"><span>2. NeoTree </span></span><span style="display:flex;"><span>3. Mason </span></span><span style="display:flex;"><span>4. Telescope </span></span><span style="display:flex;"><span>5. Nvim-Cmp </span></span><span style="display:flex;"><span>6. Mini (ai, surround, jump2d) </span></span><span style="display:flex;"><span>7. Harpoon </span></span><span style="display:flex;"><span>8. Kulala </span></span><span style="display:flex;"><span>9. GitSigns </span></span><span style="display:flex;"><span>10. NvChad-Ui </span></span><span style="display:flex;"><span>11. FriendlySnippets </span></span><span style="display:flex;"><span>12. TodoComments </span></span><span style="display:flex;"><span>13. Treesitter </span></span><span style="display:flex;"><span>15. WhichKey </span></span></code></pre></div><h2 id="key-swap-capslock-to-esc">Key swap: CapsLock to Esc</h2> <ol> <li>Download gnome-tweaks: <code>sudo apt install gnome-tweaks</code></li> <li>Run gnome-tweaks: <code>gnome-tweaks</code></li> <li>Go to <em>Keyboard &amp; Mouse &gt; Additional Layout</em></li> <li>Change <strong>Caps Lock Behavior</strong></li> </ol> <h2 id="nerd-font">Nerd Font</h2> <ol> <li>Run nerd font installer: <a href="https://github.com/officialrajdeepsingh/nerd-fonts-installer">NF Installer</a></li> <li>Choose font: <a href="https://www.nerdfonts.com/font-downloads">Caskaydia Cove Nerd Font</a></li> </ol> <h2 id="android-development-setup">Android Development Setup</h2> <h3 id="jdk-installation">JDK Installation</h3> <ol> <li>Update and search for JDK: <code>sudo apt-get update &amp;&amp; apt search openjdk</code></li> <li>Install JDK: <code>sudo apt-get install openjdk-21-jdk</code></li> <li>Check installation: <code>java -version</code></li> </ol> <h3 id="android-sdk-setup">Android SDK Setup</h3> <ol> <li>Download the latest version of cmd tools: <a href="https://developer.android.com/studio#command-tools">Android CMD tools</a></li> <li>Make a new Android SDK folder: <code>mkdir -p ~/Android/Sdk/cmdline-tools</code></li> <li>Extract the downloaded file to the new folder. <code>unzip -d ~/Android/Sdk/cmdline-tools ~/Downloads/android-cmd-tools.zip</code></li> <li>Rename the folder: <code>mv ~/Android/Sdk/cmdline-tools/cmdline-tools/ ~/Android/Sdk/cmdline-tools/latest</code></li> <li>Add the following to <code>.zshrc</code> or <code>.bashrc</code>:</li> </ol> <div class="highlight"><pre tabindex="0" style="color:#d0d0d0;background-color:#202020;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span><span style="color:#24909d">export</span> <span style="color:#40ffff">PATH</span>=~/Android/Sdk/cmdline-tools/latest/bin:~/Android/Sdk/emulator:~/Android/Sdk/platform-tools:<span style="color:#40ffff">$PATH</span> </span></span><span style="display:flex;"><span><span style="color:#24909d">export</span> <span style="color:#40ffff">ANDROID_HOME</span>=~/Android/Sdk </span></span></code></pre></div><h3 id="emulator-setup">Emulator Setup</h3> <ol> <li>List available system images: <code>sdkmanager --list</code></li> <li>Install the desired version: <code>sdkmanager &quot;emulator&quot; &quot;platform-tools&quot; &quot;platforms;android-36&quot; &quot;system-images;android-36;google_apis;x86_64&quot;</code></li> <li>List available devices: <code>avdmanager list device</code></li> <li>Setup AVD with a device: <code>avdmanager -v create avd -n Android_API_36_Google -k &quot;system-images;android-36;google_apis;x86_64&quot; -d pixel_c</code></li> <li>Run the emulator: <code>emulator -avd Android_API_36_Google</code></li> <li>Configure the device in <code>~/.android/avd/Android_API_36_Google.avd/config.ini</code>:</li> <li>Enable this line to direct key events to emulator:</li> </ol> <div class="highlight"><pre tabindex="0" style="color:#d0d0d0;background-color:#202020;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>hw.keyboard = yes </span></span></code></pre></div><p><em>Source: <a href="https://blogs.igalia.com/jaragunde/2023/12/setting-up-a-minimal-command-line-android-emulator-on-linux/">Minimal CLI Android Emulator</a></em></p> Awesome Design Resource https://indiecoder.vercel.app/library/ui-resources/ Sat, 22 Mar 2025 00:00:00 +0000[email protected] (Hein Thant) https://indiecoder.vercel.app/library/ui-resources/ <p>I use these resources in my projects to make the UI development process easier and more efficient.</p> <ul> <li><a href="https://devdojo.com/tailwindcss/buttons">Tailwind Button</a> - A collection of beautiful buttons</li> <li><a href="https://ui.aceternity.com/components">Aceternity</a> - Framer motion components in React, Tailwind</li> <li><a href="https://www.fancycomponents.dev/docs/introduction">Fancy components</a> - A collection of React components</li> <li><a href="https://uiverse.io/elements">UI Verse</a> - Tailwind/CSS components</li> <li><a href="https://originui.com/">Origin UI</a> - React + Tailwind components</li> <li><a href="https://cuicui.day/application-ui">CuiCui</a> - Copy-paste UI components and blocks</li> <li><a href="https://www.designspells.com/">Design Spells</a> - Design detail inspiration</li> </ul> Awesome Online Tools https://indiecoder.vercel.app/library/awesome-tools/ Sat, 22 Mar 2025 00:00:00 +0000[email protected] (Hein Thant) https://indiecoder.vercel.app/library/awesome-tools/ <p>Here is a list of online tools that I use from time to time.</p> <ul> <li><a href="https://cobalt.tools/">Cobalt</a> - Download anything by pasting a link</li> <li><a href="https://postspark.app/">Postspark</a> - Generate beautiful screenshots or code</li> <li><a href="https://convertio.co/">Convertico</a> - Convert files to any format</li> <li><a href="https://www.remove.bg/">Remove.bg</a> - Remove background from images</li> <li><a href="https://excalidraw.com/">Excalidraw</a> - Create beautiful diagrams</li> <li><a href="https://carbon.now.sh/">Carbon</a> - Create beautiful code snippets</li> <li><a href="https://dbdiagram.io/">Dbdiagram</a> - Create database diagrams with DBML</li> <li><a href="https://randomkeygen.com/">Randomkeygen</a> - Generate secure keys</li> <li><a href="https://web-check.xyz/">WebCheck</a> - Check website status</li> <li><a href="https://react-svgr.com/playground/">SVGR</a> - Convert SVG to React components</li> </ul> Maze Generation using Prim's Algorithm https://indiecoder.vercel.app/blogs/maze-generator/ Fri, 10 Jan 2025 00:00:00 +0000[email protected] (Hein Thant) https://indiecoder.vercel.app/blogs/maze-generator/ <p>Last week, I was working on a game project that required a maze generator. I decided to write a simple maze generator in Go. In this post, I&rsquo;ll share the code and explain how it works.</p> <p>My code is in GO but I&rsquo;ll explain with pseudo-code so that you can easily implement in any language.</p> <h2 id="prims-algorithm">Prim&rsquo;s Algorithm</h2> <p>There are many algorithms for generating mazes, but one of the simplest and most efficient is Prim&rsquo;s algorithm.</p> About Me https://indiecoder.vercel.app/about/ Wed, 01 Jan 2025 00:00:00 +0000[email protected] (Hein Thant) https://indiecoder.vercel.app/about/ <p>Hello! I&rsquo;m <strong>Hein Thant</strong>, a self-taught developer from <em>Myanmar</em>. I build mobile apps, web apps, and half-finished side projects.</p> <p>I share my knowledge and thought on this blog. I write <strong>about web dev, mobile dev, game dev, algorithms</strong> or anything that comes to my mind actually. I hope you find something useful here.</p> <p>I&rsquo;m currently working as <strong>a full-stack engineer</strong>. I also build side projects and contribute to open-source projects in my free time. My goal is to <strong>keep shipping projects that make life easier</strong> (or just more fun).</p> Upload Files to AWS S3 from React https://indiecoder.vercel.app/blogs/upload-s3/ Thu, 25 Jan 2024 00:00:00 +0000[email protected] (Hein Thant) https://indiecoder.vercel.app/blogs/upload-s3/ <p>In this blog, we’ll walk through how to upload images and videos (any files) directly from a React client to an AWS S3 bucket. The main benefit of this approach is reducing the server load since we don&rsquo;t need to upload files to our server. We only need an endpoint to get direct upload access to S3.</p> <p>In this app, we have 3 parts to set up:</p> <ol> <li><strong>Frontend client</strong> with a file input field where users can upload files</li> <li><strong>Server endpoint</strong> to get signed-URL for giving access to S3 bucket</li> <li>AWS S3 bucket where we can store our files.</li> </ol> <h2 id="backend">Backend</h2> <p>You&rsquo;ll need the following credentials from your AWS S3 Bucket to access the bucket from your server.</p> Custom Theme Switcher Hook in React https://indiecoder.vercel.app/blogs/react-theme-hook/ Wed, 04 Oct 2023 00:00:00 +0000[email protected] (Hein Thant) https://indiecoder.vercel.app/blogs/react-theme-hook/ <p>In this tutorial, I’ll show you how to build a custom theme switcher hook in React. By the end, you’ll have a reusable hook that can add dark/light mode to any React project.</p> <p>We’ll cover:</p> <ol> <li>Creating the hook step-by-step.</li> <li>Saving the user’s theme preference.</li> <li>Adding dark/light mode toggle functionality.</li> </ol> <h2 id="logic">Logic</h2> <p>Here’s how the custom hook works:</p> <ol> <li>It checks for a saved theme in local storage.</li> <li>If no saved theme is found, it checks the system’s dark mode preference.</li> <li>It updates the theme dynamically and stores the user’s choice for the next session.</li> </ol> <h2 id="creating-a-custom-hook">Creating a custom hook</h2> <p>This custom hook will handle the logic for switching between light and dark themes. Let’s create a new file called <code>useThemeSwitcher.js</code> and add the following code:</p> 6 Habits to 10x Coding https://indiecoder.vercel.app/blogs/6-productive-habits/ Sat, 28 Jan 2023 00:00:00 +0000[email protected] (Hein Thant) https://indiecoder.vercel.app/blogs/6-productive-habits/ <p>Being a good coder is not just about writing efficient and error-free code, but also involves staying organized, managing time and attention effectively, and having a balanced lifestyle. In this article, I want to share 6 simple habits that can help you improve your productivity as a coder.</p> <h2 id="1-physical-exercises">1. Physical Exercises</h2> <p>Maintaining a healthy and active lifestyle is essential for staying productive whether you’re a coder or not. But regular exercises are important, especially for coders since we spend most of our time sitting in front of a computer. Exercise not only improves our physical health but also boosts our mental clarity and focus.</p>