Today I Learned

A collection of useful things I’ve picked up along the way.

Shell & Terminal

  • cd with no args takes you to your home directory.
  • cd - takes you to the previous directory.
  • !! repeats the last command. Useful with sudo !!.
  • !$ refers to the last argument of the previous command.
  • ctrl+r lets you search through command history.
  • ctrl+a moves cursor to start of line, ctrl+e to end.
  • ctrl+u clears everything before the cursor.
  • ctrl+k clears everything after the cursor.
  • ctrl+w deletes the word before the cursor.
  • alt+. inserts the last argument from the previous command.
  • pbcopy and pbpaste on macOS let you use the clipboard from terminal.
  • cat file | pbcopy copies file contents to clipboard.
  • open . on macOS opens Finder in the current directory.
  • command -v checks if a command exists (portable alternative to which).
  • Wrapping a command in $() captures its output: echo "Today is $(date)".
  • && runs the next command only if the previous succeeded.
  • || runs the next command only if the previous failed.
  • ; runs commands sequentially regardless of success/failure.
  • > file overwrites, >> file appends.
  • 2>&1 redirects stderr to stdout.
  • tee writes to both stdout and a file: command | tee output.txt.
  • watch -n 2 command runs a command every 2 seconds.
  • time command shows how long a command takes to run.
  • history | grep pattern searches your command history.
  • fc opens your last command in an editor.
  • jobs lists background processes, fg brings one to foreground.
  • nohup command & keeps a process running after terminal closes.
  • disown detaches a running job from the terminal.

Git

  • git checkout - checks out the previous branch.
  • git switch - also switches to the previous branch (newer syntax).
  • git stash saves uncommitted changes for later.
  • git stash pop applies and removes the most recent stash.
  • git stash list shows all stashes.
  • git stash show -p shows the diff of the most recent stash.
  • git diff --staged shows changes that are staged for commit.
  • git log --oneline shows compact commit history.
  • git log --graph --oneline --all visualises branch history.
  • git blame file shows who changed each line and when.
  • git show commit:file shows a file at a specific commit.
  • git cherry-pick commit applies a single commit to current branch.
  • git rebase -i HEAD~3 lets you edit the last 3 commits.
  • git commit --amend updates the last commit.
  • git reset HEAD~1 undoes the last commit, keeping changes.
  • git reset --hard HEAD~1 undoes the last commit, discarding changes.
  • git reflog shows history of HEAD movements (useful for recovery).
  • git clean -fd removes untracked files and directories.
  • git bisect helps find which commit introduced a bug.
  • git worktree lets you check out multiple branches simultaneously.
  • git shortlog -sn shows commit count per author.
  • git config --global alias.co checkout creates command aliases.
  • git diff --word-diff shows inline word-level diffs.
  • git log -p -- file shows the history of changes to a specific file.
  • git remote -v shows remote repository URLs.
  • git fetch --prune removes references to deleted remote branches.

JavaScript & TypeScript

  • Array.at(-1) gets the last element of an array.
  • ?? (nullish coalescing) only falls back for null or undefined, not falsy values.
  • ?. (optional chaining) safely accesses nested properties.
  • Object.fromEntries() converts an array of key-value pairs to an object.
  • structuredClone() creates a deep copy of an object.
  • Array.from({ length: 5 }, (_, i) => i) creates [0, 1, 2, 3, 4].
  • Destructuring with defaults: const { name = 'Anonymous' } = user.
  • Promise.allSettled() waits for all promises regardless of rejection.
  • AbortController can cancel fetch requests and other async operations.
  • new Set([...arr]) removes duplicates from an array.
  • Object.hasOwn(obj, prop) is safer than obj.hasOwnProperty(prop).
  • Template literals support tagged templates for custom processing.
  • for...of iterates values, for...in iterates keys (usually avoid for...in).
  • globalThis works in browsers, Node, and workers.
  • queueMicrotask() schedules code to run after current task but before rendering.
  • Arrow functions don’t have their own this, arguments, or super.
  • Number.isNaN() is stricter than global isNaN().
  • Object.freeze() makes an object immutable (shallow only).
  • Reflect.ownKeys() returns all keys including symbols.
  • new URL() and URLSearchParams make URL manipulation much easier.

CSS

  • aspect-ratio: 16/9 maintains element proportions without padding hacks.
  • gap works in flexbox, not just grid.
  • min(), max(), and clamp() enable responsive values without media queries.
  • scroll-behavior: smooth enables smooth scrolling site-wide.
  • scroll-margin-top offsets scroll position for fixed headers.
  • ::marker pseudo-element styles list bullets.
  • :is() and :where() reduce selector repetition.
  • :has() is a parent selector (finally!).
  • inset: 0 is shorthand for top: 0; right: 0; bottom: 0; left: 0.
  • place-items: center centres in both directions (grid/flexbox).
  • isolation: isolate creates a new stacking context.
  • accent-color styles form controls like checkboxes.
  • color-scheme: light dark tells the browser your site supports both modes.
  • prefers-reduced-motion media query respects user accessibility settings.
  • content-visibility: auto can significantly improve rendering performance.
  • text-wrap: balance creates more visually balanced text wrapping.

Node.js

  • node --watch file.js auto-restarts on file changes (Node 18+).
  • npm pkg get version prints the package version.
  • npm outdated shows packages that need updating.
  • npm ls shows the dependency tree.
  • npm why package explains why a package is installed.
  • npx runs packages without installing them globally.
  • process.env.NODE_ENV distinguishes development from production.
  • import.meta.url gives the current module’s URL in ES modules.
  • node --inspect enables the Chrome DevTools debugger.
  • NODE_OPTIONS='--max-old-space-size=4096' increases memory limit.

VS Code

  • cmd+shift+p opens the command palette.
  • cmd+p opens quick file search.
  • cmd+shift+f searches across all files.
  • cmd+d selects the next occurrence of current selection.
  • cmd+shift+l selects all occurrences of current selection.
  • alt+click creates multiple cursors.
  • cmd+shift+k deletes the current line.
  • alt+up/down moves lines up or down.
  • shift+alt+up/down duplicates lines.
  • cmd+/ toggles line comments.
  • cmd+b toggles the sidebar.
  • cmd+j toggles the terminal panel.
  • F2 renames a symbol across all references.
  • cmd+. shows quick fixes and refactoring options.
  • cmd+shift+o navigates to symbols in current file.

Docker

  • docker system prune removes unused data.
  • docker compose up -d starts services in detached mode.
  • docker compose logs -f follows container logs.
  • docker exec -it container sh opens a shell in a running container.
  • docker cp container:/path ./local copies files from container.
  • COPY --chown=node:node sets ownership during build.
  • Multi-stage builds dramatically reduce image size.
  • .dockerignore works like .gitignore for build context.
  • docker stats shows real-time resource usage.
  • docker history image shows how an image was built.

General

  • Rubber duck debugging actually works - explain the problem out loud.
  • Taking a break often solves problems faster than pushing through.
  • Writing tests first clarifies what you’re actually trying to build.
  • Code is read far more often than it’s written.
  • The best code is often the code you delete.
  • “Make it work, make it right, make it fast” - in that order.
  • Naming is one of the hardest problems in programming.
  • If you can’t explain it simply, you don’t understand it well enough.
  • Most bugs are caused by incorrect assumptions.
  • Version control everything, including configuration.