IndieCoder
https://indiecoder.vercel.app/
Recent Posts on IndieCoderHugoen[email protected] (Hein Thant)[email protected] (Hein Thant)indiecoderSat, 03 Jan 2026 00:00:00 +0000My 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’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’ve been using <code>kickstart.nvim</code> for over a year, and now I’m finally ready to start my own Neovim journey. By <em>“my own”</em> I mean I’m writing configs myself, but I’ll still be copying from everywhere because that’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’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’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’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’m a <em>vibe-driven productivity</em> guy. Which just means I am ambitious, but lazy, inconsistent and have low discipline. Some days I’m in flow, giving my all, but on others, I’m just floating through. I’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 “2025-01-10”, the bot will respond with basic calendar information, fetched events and birthdays from Wikipedia, and a APOD image from NASA api.</p>
<p>I’ll walk you through how I built it, and for the sake of simplicity, I’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’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">"Pop!_OS"</span>
</span></span><span style="display:flex;"><span><span style="color:#40ffff">VERSION</span>=<span style="color:#ed9d13">"22.04 LTS"</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">"ubuntu debian"</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 & Mouse > 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 && 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 "emulator" "platform-tools" "platforms;android-36" "system-images;android-36;google_apis;x86_64"</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 "system-images;android-36;google_apis;x86_64" -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’ll share the code and explain how it works.</p>
<p>My code is in GO but I’ll explain with pseudo-code so that you can easily implement in any language.</p>
<h2 id="prims-algorithm">Prim’s Algorithm</h2>
<p>There are many algorithms for generating mazes, but one of the simplest and most efficient is Prim’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’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’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’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’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>