Duy NG

フィード

記事のアイキャッチ画像
[Note] Different ways to batch update Nodejs dependencies
Duy NG
Different ways to batch update Node.js dependenciesHere are a few simple ways to batch update all the Node.js dependencies in package.json:yarn v2:yarn upgrade-interactiveThis gives you an interactive list so you can choose exactly which packages to update.npm:npm-check-updates.npm install -g npm-check-updatesncu -i # interactive updateThis automatically updates your package.json with the latest versions.pnpm:pnpm update -i # interactive updatepnpm update --latest # update all to latest versionsbun:bun update --latest # update all to latest versionsdeno:deno outdateed --update --latest # update dependencies to latest versions, ignoring semver requirementstaze:taze is another tool that smartly upgrades your dependencies.CIIf you’d rather automate the whole process on CI, consider integrating tools like Renovate or Dependabot into your workflow. They’ll automatically open pull requests with updates, so you can review and merge changes without extra efforts.
4ヶ月前
記事のアイキャッチ画像
[Note] The fastest way to rewrite Git history
Duy NG
The fastest way to rewrite Git historyEver pushed commits and then realized you messed up?Wrong Git user/email.Bad commit messages.Accidentally committed secrets (API keys, passwords).A huge file is bloating the repo....and more.Many developers try git rebase -i, but it’s slow, manual, and limited. A better way?Use git-filter-repo, it’s faster, more powerful, and works across the entire repo.Examples of Git problems and fixesFix author name/email in all commitsgit filter-repo --commit-callback ' commit.author_name = "Correct Name" commit.author_email = "[email protected]"'Edit commit messages in bulkgit filter-repo --message-callback ' commit.message = commit.message.replace(b"fix typo", b"Fix: corrected typo")'Remove sensitive files from historygit filter-repo --path secret-file.env --invert-pathsDelete large files from old commitsgit filter-repo --strip-blobs-bigger-than 100MErase all commits from a specific authorgit filter-repo --commit-callback ' if commit.author_email == b"wron
5ヶ月前
記事のアイキャッチ画像
[Note] You don't need husky
Duy NG
You don’t need HuskyDo you use husky to manage Git commit hooks? Husky is a popular tool (50M+ downloads per month!), but did you know that Git already has built-in support for hooks?With Githooks, you don’t need to install extra dependencies. Git provides 28 different hooks that allow you to automate git hooks tasks.How to use?Create a .git/hooks or .githooks directory (just like you’d configure .husky)Configure Git to use your hooks scriptsTell Git to use this folder for hooks by adding the following postinstall script in your package.json. This ensures that Git hooks are always active after running npm install (or yarn, pnpm, bun)."scripts": { "postinstall": "git config core.hooksPath ./.githooks || true"}Hook scriptsInside the .githooks folder, create scripts named according to the Git Hooks documentation (e.g., pre-commit, prepare-commit-msg).Example:# .githooks/pre-commit#!/bin/bashnpm run lint# .githooks/prepare-commit-msg#!/bin/bashnpx --no-install commitlint --edit "$1"# .gith
5ヶ月前
記事のアイキャッチ画像
Scripting tools - A Node.js friendly alternative to makefile
Duy NG
Using execa and commander is an alternative that can be considered for replacing makefile in a Node.js project
5ヶ月前
記事のアイキャッチ画像
[Note] Display colors in Makefile
Duy NG
Display colors in MakefileIn a previous note, I shared how to create a help command in a Makefile.This time, let’s make it visually appealing by adding colors to the output.Here’s how to do it:# COLORSYELLOW = \033[33mGREEN = \033[32mWHITE = \033[37mRESET = \033[0mhelp: ##@helper Display all commands and descriptions@awk 'BEGIN {FS = ":.*##@"; printf "\n${WHITE}Usage:${RESET}\n make <target>\n"} \/^[.a-zA-Z_-]+:.*?##@/ { \split($$2, parts, " "); \section = parts[1]; \description = substr($$2, length(section) + 2); \sections[section] = sections[section] sprintf(" ${YELLOW}%-15s${RESET} ${GREEN}%s${RESET}\n", $$1, description); \} \END { \for (section in sections) { \printf "\n${WHITE}%s${RESET}\n", section; \printf "%s", sections[section]; \} \}' $(MAKEFILE_LIST)YELLOW, GREEN, WHITE, and RESET are ANSI escape codes for terminal colors.\033[33m sets the color to yellow, \033[32m to green, and \033[37m to white.\033[0m resets the color to the terminal default.It formats the output with co
5ヶ月前
記事のアイキャッチ画像
[Note] Display all Makefile commands
Duy NG
Display all Makefiles commandsMakefiles can be hard to navigate, especially as they grow. Adding a help command makes it easy to see all available targets and their purposes.The magic help targetAdd this awk snippet to your Makefile:.DEFAULT_GOAL := help.PHONY: helphelp: ##@helper Display all commands and descriptions@awk 'BEGIN {FS = ":.*##@"; printf "\nUsage:\n make <target>\n"} \/^[.a-zA-Z_-]+:.*?##@/ { \split($$2, parts, " "); \section = parts[1]; \description = substr($$2, length(section) + 2); \sections[section] = sections[section] sprintf(" \033[36m%-15s\033[0m %s\n", $$1, description); \} \END { \for (section in sections) { \printf "\n\033[1m%s\033[0m\n", section; \printf "%s", sections[section]; \} \}' $(MAKEFILE_LIST)How it worksUse ##@ to group related targetsAnd place the description of each command after that groupExample Makefilehelp: ##@helper Display all commands and their descriptions@awk 'BEGIN {FS = ":.*##@"; printf "\nUsage:\n make <target>\n"} \/^[.a-zA-Z_-]+:.*?##
5ヶ月前
記事のアイキャッチ画像
[Note] Supercharge Git with fzf
Duy NG
Supercharge Git with fzfWorking with Git branches can be annoying, especially with long names or when cleaning up old ones. Try fzf, a tool that makes managing branches easy.Switch branchesUse fzf to select and switch branches interactively:git branch | fzf --preview 'git log -p main..{-1} --color=always {-1}' | cut -c 3- | xargs git switchDelete branchesDelete branch interactively with fzf:git branch | fzf -m --preview 'git log -p main..{-1} --color=always {-1}' | cut -c 3- | xargs git branch -dI setup them in my shell config to save time:alias gs="git switch"alias gsc="git witch -c"alias gsi="git branch | fzf --preview 'git log -p main..{-1} --color=always {-1}' | cut -c 3- | xargs git switch"alias gbd="git branch | fzf -m --preview 'git log -p main..{-1} --color=always {-1}' | cut -c 3- | xargs git branch -d"
5ヶ月前
記事のアイキャッチ画像
[Note] Better Git log
Duy NG
Better Git logThe default git log output can be hard to read. Here’s how I make it more visual and informative using aliases.Add these aliases to the global .gitconfig:[alias] # Tree-like log with relative dates logs = log --graph --date=relative --pretty=tformat:'%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%an %ad)%Creset' # Limit to 20 commits log = logs -n 20Alternatively, set up aliases in your shell config:alias glog="git log --graph --date=relative --pretty=tformat:'%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%an %ad)%Creset' -n 20"alias glogs="git log --graph --date=relative --pretty=tformat:'%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%an %ad)%Creset'"Example output* c0eb700 - (HEAD -> master, origin/master, origin/HEAD) chore(fish): update alias (woula 26 minutes ago)* 960e14f - chore(nvim): update plugins, active flash, disable cappuchine (woula 16 hours ago)* bc1129d - feat(nvim): add disabled plugins list (woula 3 days ago)* 6e14bad - feat(nix): update config for homebre
5ヶ月前
記事のアイキャッチ画像
[Note] Managing multiple Git accounts
Duy NG
Managing multiple Git accountsWorking with multiple Git accounts (e.g., work, personal, open-source) can be tricky. Here’s how I manage them seamlessly using conditional includes in .gitconfig.Global .gitconfig setupAdd conditional includes to the global .gitconfig:[includeIf "gitdir:~/projects/company1/"] path = ~/projects/company1/.gitconfig[includeIf "gitdir:~/projects/company2/"] path = ~/projects/company2/.gitconfig[includeIf "gitdir:~/projects/oss/"] path = ~/projects/oss/.gitconfigLocal .gitconfigIn each project’s .gitconfig, specify the user and SSH key.Here is example for ~/projects/company1/.gitconfig[user] name = username1 email = [email protected][core] sshCommand = ssh -i ~/.ssh/company1_rsaGit will help us to automatically switch configurations based on the project directory.
5ヶ月前
記事のアイキャッチ画像
[Note] Git aliases
Duy NG
Git aliasesGit aliases are a must have for every developer. They save time, reduce typing, and make your workflow more efficient.You can set them up in two ways: terminal shell aliases or .gitconfig.Terminal shell aliasesHere’s a part how I set up my Git aliases in my shell config (e.g. .zshrc or fish.config ...etc.):# Gitalias g="git"alias gc="git commit -m"alias gca="git commit -a -m"alias gp="git push origin HEAD"alias gpu="git pull origin"alias gpf="git push --force-with-lease"alias gst="git status"alias gs="git switch"alias gsc="git switch -c"alias gdiff="git diff"alias gco="git checkout"alias gcob="git checkout -b"alias gb="git branch"alias gba="git branch -a"alias gadd="git add"alias ga="git add -p"alias gre="git reset".gitconfig aliasOther way to manage git alias with global .gitconfig[alias] # List all aliases aliases = !git config --get-regexp alias | sed -re 's/alias\\.(\\S*)\\s(.*)$/\\1 = \\2/g' # Command shortcuts st = status cm = commit -m co = checkout stl = stash list s
5ヶ月前
記事のアイキャッチ画像
[Note] Run a command if there are unstaged changes
Duy NG
Run a command if there are unstaged changesA quick one-liner to run a command only if there are unstaged changes: the --quiet flag of git diffThe flag does two things:Disables all output of the commandExits with 1 if there are differences, and 0 if there are no differences.That means you can combine it with boolean operators to only run another command if files have (or have not) changed:# Run `command` if there are unstaged changesgit diff --quiet || command# Run `command` if there are NO unstaged changesgit diff --quiet && commandOther tipsCheck for untracked filesgit ls-files --others --exclude-standard | grep -q . && commandInclude staged changesgit diff --cached --quiet || commandCombine with entr for file watchinggit diff --quiet || entr -r commandUse in CI pipelinesgit diff --quiet || echo "Changes detected, running tests..." && npm test
5ヶ月前
記事のアイキャッチ画像
[Note] List all files tracked by Git
Duy NG
List all files tracked by GitSometimes you need a list of all files tracked by Git—for example, when using tools like entr to watch files for changes. Instead of fiddling with find, Git provides a clean and concise command git-ls-files:git ls-filesThis lists all files in the repository that are tracked by Git.Other tipsInclude ignored files:git ls-files --others --ignored --exclude-standardFilter by file type:git ls-files '*.js' # List only JavaScript filesUse with entr to watch files:git ls-files | entr -r your-command
5ヶ月前
記事のアイキャッチ画像
[Note] Git Checkout vs. Git Switch
Duy NG
Git Checkout vs. Git Switchgit checkoutSwitch branches:git checkout <branch> # Switch to an existing branchCreate and switch to a new branch:git checkout -b <new-branch> # Create and switch to a new branchRestore files from a specific commit or branch:git checkout <commit> -- <file> # Restore a file from a specific commitgit switch (modern alternative)Switch branches:git switch <branch> # Switch to an existing branchCreate and switch to a new branch:git switch -c <new-branch> # Create and switch to a new branchKey differencesCommandPurposeNotesgit checkout <branch>Switch branchesOlder, more versatile command.git checkout -b <branch>Create and switch to a new branchCombines branch creation and switch.git checkout <commit> -- <file>Restore a file from a commitUseful for recovering files.git switch <branch>Switch branchesModern, focused alternative.git switch -c <branch>Create and switch to a new branchSimpler and more intuitive.When to use?git checkout:Use for restoring files from a spec
5ヶ月前
記事のアイキャッチ画像
[Note] Git Reset vs. Git Restore
Duy NG
Git Reset vs. Git Restoregit resetUndo commits (keep changes staged):git reset --soft HEAD~ # Move HEAD but keep changes stagedgit reset --soft <commit> # Move to specific commit, keep changes stagedUnstage changes (keep changes in working directory):git reset HEAD~ # Reset --mixed (default), move HEAD and unstage changesgit reset <commit> # Reset --mixed, move to specific commit and unstage changesgit reset HEAD <file> # Unstage a specific fileDiscard commits and changes (destructive):git reset --hard HEAD~1 # Discard commits and changes permanentlygit restoreDiscard working directory changes:git restore <file> # Revert file to its state in the last commitUnstage changes:git restore --staged <file> # Move changes from staging area to working directoryRestore a file from a specific commit:git restore --source=<commit> <file> # Restore file from a specific commitKey differencesCommandBranch pointerStaging areaWorking directorygit reset <commit>MovesResets (unstages)Unchangedgit reset --
5ヶ月前
記事のアイキャッチ画像
[Note] Ingore all .DS_store files globally
Duy NG
Ignore all .DS_Store files globallyIf you use Git on a Mac, you’ve probably accidentally committed a .DS_Store file to a repo at least once. I used to add .DS_Store to every .gitignore file to avoid this, but there’s a better way!You can create a global .gitignore file that applies to all your repositories. Just run this command:git config --global core.excludesFile '~/.gitignore'Then, add .DS_Store to your ~/.gitignore file:echo ".DS_Store" >> ~/.gitignoreThis command adds the following to your ~/.gitconfig:[core] excludesFile = ~/.gitignoreNow, .DS_Store files will be ignored across all your projects, no more accidental commits!You can directly edit the ~/.gitignore file to globally ignore many other files.
5ヶ月前
記事のアイキャッチ画像
[Note] Update all Git submodules to latest commit
Duy NG
Update all Git submodules to the latest commitIf you use Git submodules often, here's the one-liner to update them to the latest commit on origin (since Git 1.8.2):git submodule update --remote --rebasePrefer merging? Swap --rebase for --merge.
5ヶ月前
記事のアイキャッチ画像
[Note] Run Github actions locally
Duy NG
Run Github actions locallyRun GitHub actions locally with act to skip the long feedback loop! It uses Docker to pull images and run workflows right on your machine.# Run the `push` eventact# Run a specific event or jobact pull_requestact -j test_unitNeed a GitHub token? Use the -s flag with the GitHub CLI:act -s GITHUB_TOKEN="$(gh auth token)"Quick, easy, and no more waiting for GitHub to run workflows!
5ヶ月前
記事のアイキャッチ画像
[Note] First attempt at migrating from Homebrew to Nix with Nix Home Manager
Duy NG
First attempt at migrating from Homebrew to Nix with Nix Home ManagerIt didn’t go exactly as planned. I dived into Nix scripts, flakes, and started installing packages with nixpkgs while keeping Homebrew on the side.But... nothing seemed to work correctly. 😵Tools like fish shell, fzf, and ghostty .etc... didn't work.I probably need to configure each program properly, manage environments, and link the ~/.config files with Nix...During the migration, I enabled autoCleanUp Homebrew with "zap" without paying close attention. Big mistake! It wiped out everything I’d installed through Homebrew. 😱 Aie aie aie.Thankfully, I had saved all my tools in a Brewfile in my dotfiles. A quick brew bundle restored everything (though it took time to install).Lesson learned: I need to take it step by step with Nix, learning more about proper configurations before jumping in too deep.For now, I’m sticking with Homebrew but I’ll give Nix another try someday.
5ヶ月前
記事のアイキャッチ画像
[Note] Tilting window management on macOS with aerospace
Duy NG
Tiling window management on macOS with aerospaceIn the past, I was a rectangle user. I used it to move windows into corners or split the screen, basic functionality. Honestly, it never felt transformative. It was fine, but quite basic. I only used it during screen-sharing sessions on Teams calls. I always wanted something more controllable and better organized, with groupings of applications.Recently, I explored raycast, and at first, it seemed like the solution I had been looking for. It offered intuitive window organization, powerful workspace controls, and a lot of cool features.That’s when I came across aerospace, thanks to all the people sharing it on YouTube. And wow! This is the tool I was looking for! (powerful, free, open-source, workspace management simple, entirely keyboard shortcuts)Using aerospace has completely transformed my workflow. I now have workspaces neatly organized by task coding (C), terminal (T), browser (B), music (M)... and switching between them is really si
5ヶ月前
記事のアイキャッチ画像
[Note] Manage better for my dotfiles.
Duy NG
Manage better for my dotfilesUp until now, I’ve been handling my dotfiles manually with a Makefile and shell scripts.I used commands like rsync to mirror files from my ~/.config directory to my ~/dotfiles folder,and then saved everything on GitHub. While this approach worked, it was tedious and had a lot of limitations:rsync wouldn’t handle deletions properly, so if I deleted a file in ~/.config, it wouldn’t be removed from the dotfiles folder.I had to run make sync every time I wanted to update my dotfilesRestoring configurations wasn’t properly handledI also wanted to directly manage the ~/.config folder with Git, but my current setup didn’t make that easy.Then, I stumbled across a YouTube video about using GNU Stow to manage dotfiles.It’s such a simple yet powerful tool! Stow creates symlinks from your dotfiles folder to your ~/.config directory,so there’s no need for manual mirroring. Everything stays organized and up-to-date automatically.Now, I manage my ~/dotfiles easily with St
6ヶ月前
記事のアイキャッチ画像
[Note] CLI tools I love using
Duy NG
CLI tools I love usingI’m a huge fan of Rust, and it’s no surprise that many of the tools I rely on in the terminal are written in rust.Here’s a quick rundown of my favorites:Fzf: Fuzzy finder that makes searching files or commands a breeze.Eza: A modern, colorful alternative to ls that adds more functionality.Zoxide: A smarter cd command that remembers your most-used directories.Fish shell: A user-friendly shell with auto-suggestions and syntax highlighting.Starship prompt: Fast, customizable prompt with support for all major shells.Ripgrep: Lightning-fast search tool, a must-have for large codebases.Sd: Simpler, more intuitive replacement for sed.Fd: Faster, friendlier alternative to find with colorful output.Jq: Power tool for processing JSON data in the terminal.Lazygit: Terminal-based Git interface, perfect for lazy devs.Lazydocker: Easy-to-use terminal tool for managing Docker containers.Bat: Better cat with syntax highlighting and line numbers.Git-delta: Enhanced git diff tool w
6ヶ月前
記事のアイキャッチ画像
[Note] Returning to Neovim for Coding
Duy NG
Returning to Neovim for codingI’ve started using Neovim for coding again.Early in my career, like many others, I tried to learn Vim. At first, it was difficult to get used to, but I found it fun and rewarding. For some, Vim can feel more "professional," and there's something satisfying about the cool things you can do with it.I really liked Vim, but when it came to coding, I ran into many challenges. Configuring Vim with the right plugins, settings, and workflows took a lot of time. Back then, I was working with many different languages—Python, Ruby, JavaScript, TypeScript, HTML, CSS—and I could never quite get Vim to work smoothly across all of them. I faced too many issues, so eventually, I switched to VSCode and IntelliJ for most of my coding, using Vim only for occasional file edits.Now, with modern terminals like Wezterm and Ghostty, I find myself enjoying the terminal environment more. I want to keep my hands on the keyboard as much as possible, so I decided to give Vim another t
6ヶ月前
記事のアイキャッチ画像
[Note] Ghostty?
Duy NG
Ghostty?Ghostty has just released its official production-ready version: 1.0, and it’s causing quite a hype among developers across all platforms. I’m really curious to try it out!Ghostty is a terminal emulator built with Zig. Most terminal emulators I’ve used, like WezTerm, Warp, Alacritty, and Zellij, are written in Rust. So it’s exciting to see a terminal tool developed in Zig instead.(I really like both of 2 this languages: rust and zig)I decided to give it a shot, even though I’ve been happily using WezTerm. And I have to say, I’m impressed.It’s fast—faster than WezTerm in terms of startup time and when opening new tabs. It integrates smoothly with Fish shell, which I love.The keybindings are easy to access, and the setup process is a really simple. Plus, it supports a variety of themes.Some standout features include Quick Terminal and the ability to use Cmd + Triple-click for selection—simple yet powerful.So, I’ve made the switch. My terminal is now Ghostty.
6ヶ月前
記事のアイキャッチ画像
[Note] I’ve started implementing short notes on my website
Duy NG
I’ve started implementing notes on my websiteThe goal is to create a space for sharing shorter updates, thoughts, and progress on ongoing projects. I plan to update this space regularly with useful insights and updates.Stay tuned for more posts soon.
6ヶ月前
記事のアイキャッチ画像
How to build dual package npm from Typescript - the easiest way
Duy NG
Explore an easy way to support dual package TypeScript NPM libraries for both CommonJS and ESM
7ヶ月前
記事のアイキャッチ画像
Essential tsconfig.json options you should use
Duy NG
A guide to essential tsconfig.json options for boosting TypeScript code safety, performance, and reliability.
7ヶ月前
記事のアイキャッチ画像
Migrate to ESLint 9.x
Duy NG
In this article, I share some experiences of migrating to ESLint 9.x, which includes significant breaking changes. We'll use the flat config, integrate ESLint plugins, and specify custom rules for various file types: .js, .cjs, .mjs and .ts
1年前
記事のアイキャッチ画像
Why you might be using Enums in TypeScript wrong
Duy NG
Discover the pitfalls of using Enums in TypeScript and explore a more type-safe alternative with `as const`
1年前
記事のアイキャッチ画像
Should you switch to Deno?
Duy NG
This article highlights key reasons for the change, explores Deno’s features, and helps you decide if it’s the right choice for your projects
1年前
記事のアイキャッチ画像
My blog now offers full-text RSS feeds
Duy NG
Explore the reasons behind this decision
1年前
記事のアイキャッチ画像
Transforming website images into WebP with Rust for faster loading times
Duy NG
Explore the process of enhancing website speed through image conversion to WebP using Rust
1年前
記事のアイキャッチ画像
Dynamic Github profile with Bun and Typescript
Duy NG
Learn how to make your GitHub profile dynamic using Bun and TypeScript as an alternative to Python in my previous article.
1年前
記事のアイキャッチ画像
How I made my GitHub profile README dynamic
Duy NG
Explore the process of making your GitHub profile README dynamic with automated updates of your latest blog posts using GitHub Actions and Python scripting
1年前
記事のアイキャッチ画像
New home for my website
Duy NG
Discover why I switched my website and blog from Jekyll to Zola.
1年前
記事のアイキャッチ画像
Start a new journey
Duy NG
I share my journey from being a BIM engineer to becoming a full-time backend developer
4年前
記事のアイキャッチ画像
Build your personal website without spending any money
Duy NG
Learn how to build your own personal website using Jekyll and GitHub Pages without spending a dime. Dive into the step-by-step process and get your website up and running in no time.
5年前