Ripgrep files with matches
I use Ripgrep as my command-line search tool. Something I often want is to return matching filenames only, instead of Ripgrep’s rich colored output, so I can pipe them to xargs . Here’s that flag: rg -l
Recent content on Jake Worth
I use Ripgrep as my command-line search tool. Something I often want is to return matching filenames only, instead of Ripgrep’s rich colored output, so I can pipe them to xargs . Here’s that flag: rg -l
For each way you can map something in Vim, you can inspect those mappings. Check out this table of commands: COMMANDS MODES :map :noremap :unmap Normal, Visual, Select, Operator-pending :nmap :nnoremap :nunmap Normal :vmap :vnoremap :vunmap Visual and Select :smap :snoremap :sunmap Select :xmap :xnoremap :xunmap Visual :omap :onoremap :ounmap Operator-pending :map! :noremap! :unmap! Insert and…
We can save all evaluated commands from our TSX REPL session to a file: $ npx tsx > const name: number = 'Jake' undefined > .save output.ts Session saved to: output.ts
Want to get better at technical writing? I’ve been writing prose (READMEs, wikis, and this blog) with Vale for months. It’s helps me write better, faster. Here’s what I’ve learned.
In the next twelve months, I’m launching twelve software startups.
Today I discovered tsx , a REPL that evaluates TypeScript. You can run it with npx: npx tsx And it evaluates TypeScript. > const onClick = ( input : number ) : void => input + 1 undefined > onClick ( 1 ) 2
For the golfers out there, we can combine these two lines into one: const items = await getCollection (); return items . sort (); This doesn’t work because sort() is being called on the promise returned by getCollection() : return await getCollection (). sort (); // `sort()` runs on the Promise Instead, wrap the await expression in parentheses so sort() is called on the resolved value:…
Today I’d like to highlight something I built with some colleagues that I think is cool: the dynamic paths of Hashrocket’s daily learning site, Today I Learned (TIL).
Astro’s default port is 4321. Like Vite , this project is trying to convey its (rocket-launch) branding, even in this small detail.
Node Timeout timers have a private boolean attribute called _destroyed . It tells you if the function has been cleared: timer . _destroyed ;
Today I used JavaScript to mass-unsubscribe from a website’s email notifications. Here’s the code, followed by what I did and why. document . querySelectorAll ( '[role='switch']' ) . forEach (( element ) => element . click ());
Reflection is an important tool in programming; it lets us examine a language’s structure. Can we reflect in JavaScript? Sort of. Some functions can be reflected with toString() : > const one = () => 1 undefined > one . toString () '() => 1' Very cool! But native functions only return this: > Math. max . toString () 'function max() { [native code] }' You must read the ECMA Script…
A vital testing skill is focusing a test. When iterating on a failing test, we want that test under microscope. The way I do this in JavaScript is .only : import { describe , expect , test } from 'vitest' ; import { sum } from './sum.js' ; test ( 'adds 1 + 2 to equal 3' , () => { expect ( sum ( 1 , 2 )). toBe ( 3 ); }); describe . only ( 'adding fours' , () => { test ( 'adds 4 + 4 to equal 8' , ()…
JSDoc has a @deprecated tag that you can use in TypeScript, too. Here’s an example.
I’m reading How to Open Source by Richard Schneeman (fantastic) and one of his tips is to show documentation code like this (consider documenting ls ): ls <desired-path> Rather than the common: ls /your/path/here
When upgrading a dependency for a security issue, we might upgrade and move on: npm install <dependency>@<version> But wait! Was every <dependency> version upgraded, or just the version in package.json ? Check with: npm list // or npm ls
Today while reading the Rust Documentation , I encountered a fantastic UX touch. The authors provide this image with each code block that intentionally doesn’t compile:
Images in Hugo can be a bit tricky. Here’s how I’ve added images on my projects page that are resized, linked, and have alts: the figure shortcode. {{ < figure src = '/images/yiap.png' alt = 'Yes, It's a Problem' link = 'https://github.com/jwworth/yes-its-a-problem' width = '600' > }}
Sometimes I want to iterate on an alias. You can unalias an alias like this: unalias aliasname
Today I discovered these two Vim flags: vim -w log.txt file vim -s log.txt file The -w flag sends all keystrokes in your session to log.txt . The -s loads Vim and replays all the keystroke back onto that file.
I’ve been writing some non-printing characters to a file. But when I concatenate, it appears empty. cat log.txt # Nothing here 🥺 cat those non-printing characters with -v : cat -v log.txt jjjj:wq^M%
I was doing a Vite demo last week, I changed some markup, and visited the local web server. The markup changed, but the state persisted. What?! This is Vite’s Hot Module Replacement API.
Prettier formats code in fenced code blocks! When I type three backticks and then a code, Prettier evaluates the code in the block and tries to format it per my global .prettierrc .
If you’ve been writing TypeScript for a while, you might have written code like this: // utils.ts export type Color = 'red' | 'blue' | 'green' ; // app.tsx import { Color } from './utils' ; As of TypeScript 3.8, there’s a better way to import! // app.tsx import type { Color } from './utils' ;
New Vite TypeScript/React apps create themselves like this: createRoot (document. getElementById ( 'root' ) ! ). render (< App />); What’s going on with that ! ?
I often reflect on a conversation from years ago with a former Army boss. It’s foundational to how I understand leadership. He said that being a leader means you have to “Genuinely care.”
After more than a decade in the field as an engineering leader and hands-on practitioner, I’m thrilled to be offering a consulting service. I am a strong contributor in three areas: technical consulting, mentorship, and workshops & teaching. Technical consulting I love digging into tough problems in greenfield and legacy code. A few things I’m good at: Raising code quality (tooling,…
Vite’s default port, 5173, is leet code for the project’s name: 5 = “V” (Roman numerals 😉) 1 = “I” 7 = “T” 3 = “E”
To load Cursor with context of the current directory, use: cursor .
Today I learned about the Outbox Pattern.
Always leave something behind. If you find something interesting, leave a trace that you were there.
After version v12.17.0, Node’s REPL provides a useful preview effect. In this example, 2 is shown in gray before I hit enter. > 1 + 1 2 But what if I don’t want that? Here’s a file called repl that disables it as an option: #!/usr/bin/env node const repl = require ( 'node:repl' ); repl . start ({ preview : false }); Then: $ ./repl > 1 + 1 No preview. Docs
With my Node versions managed via NVM, I want to be on the latest LTS. You can ensure that happens with these commands: $ nvm install --lts $ nvm alias default lts/* default -> node (-> v24.16.0)
How do I “get up to speed” in a new codebase? Changing it.
Approach caching with caution.
The Law of Demeter is important in object-oriented programming. But where does “Demeter” come from?
Today I learned how to fill in an emoji with CSS. Here’s an example: . filledEmoji { color : transparent ; text-shadow : '0 0 0 #86efac' ; }
What I call “wraparound” are repeatable indices on an array. The common use case is a carousel. Here’s how it’s done: const items = [ 'first' , 'middle' , 'last' ]; const i = 0 ; // Our iterable index // 'Next' -> const nextIndex = ( i + 1 ) % items . length ; // <- 'Previous' const prevIndex = ( i - 1 + items . length ) % items . length ;
Here’s a periodic reminder that JavaScript supports string concatenation with a plus sign: > 'foo' + 'bar' 'foobar'
Need an array of letters? Here’s a trick: > const alpha = [... 'abcdefghijklmnopqrstuvwxyz' ]
When you join an array in JavaScript, the default separator is a comma: node > [ 'j' , 'a' , 'k' , 'e' ]. join () 'j,a,k,e'
The JavaScript bitwise AND operator ( & ) can be used for some real-world tasks, like testing if a number is odd or even.
I think many engineers would be better contributors if they started to think more about the customer impact of their work.
Longtime Vim users know the vimtutor program, which teaches you Vim in Vim. Vim 9.2 shipped with a new :Tutor command that improves on this. : Tutor
This page summarizes my usage of LLMs (“AI”) on this website.
After reviewing a lot of pull requests, I’ve settled on a simple default: if my comments are all nitpicks, suggestions, questions, or non-blocking issues, I leave them and approve the PR at the same time.
When possible, I prefer to upgrade dependencies incrementally rather than making several version jumps. So, we try not to go from React 16 to 19. We go from 16 to 17, then to 18, and finally to 19. The Risks of Jumping Multiple Versions It’s very tempting to jump to the latest release. It feels like time travel; putting your application on the latest in the fewest number of steps. What’s not…
A policy I favor with dependency management: go forward. Going backward is an exception that we must plan to remedy. Example Consider a CVE in a dependency at version 5.0 (v5.0). We’re advised that v6.0 and v4.0 are safe. Which way should we go, forward or backward? We want to default to forward. Even if we’ve been on v4.0 before and know it is compatible. Even if we aren’t sure that v6.0 is…
If people can make catastrophic mistakes on your team, the process is broken.
Why do software teams push continuous deployment so strongly? One of the most important and least discussed reasons is engineer morale.