RSSAmplifier

Blog

Jake Worth

Recent content on Jake Worth

jakeworth.comRSS feed ↗452 posts

Latest posts

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

Vim view all your maps

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…

Saving TSX's Evaluated Commands to File

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

Writing Prose with Vale

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.

12 Startups in 12 Months

In the next twelve months, I’m launching twelve software startups.

tsx, a REPL for TypeScript

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

Enumerate on promise resolved

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:…

Opaque IDs, editable titles in TIL URLs

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).

4321 is Astro

Astro’s default port is 4321. Like Vite , this project is trying to convey its (rocket-launch) branding, even in this small detail.

Node's Timeout _destroyed Private Method

Node Timeout timers have a private boolean attribute called _destroyed . It tells you if the function has been cleared: timer . _destroyed ;

Uncheck Buttons With JavaScript

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 ());

JavaScript Reflection with toString

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…

Focus a JS Test

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 Deprecations in TypeScript

JSDoc has a @deprecated tag that you can use in TypeScript, too. Here’s an example.

Unknown Value in Brackets

I&rsquo;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

NPM List Packages

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

Rust Erroring Code Visual Aid

Today while reading the Rust Documentation , I encountered a fantastic UX touch. The authors provide this image with each code block that intentionally doesn&rsquo;t compile:

Resized Images in Hugo Markdown

Images in Hugo can be a bit tricky. Here&rsquo;s how I&rsquo;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' > }}

Unalias an Alias

Sometimes I want to iterate on an alias. You can unalias an alias like this: unalias aliasname

Vim Scriptout and Scriptin

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.

Concatenate Non-Printing Characters

I&rsquo;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%

Vite Hot Module Replacement

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&rsquo;s Hot Module Replacement API.

Prettier in Fenced Code Blocks

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 .

TypeScript Type-Only Imports and Exports

If you&rsquo;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&rsquo;s a better way to import! // app.tsx import type { Color } from './utils' ;

Non-Null With Root Import

New Vite TypeScript/React apps create themselves like this: createRoot (document. getElementById ( 'root' ) ! ). render (< App />); What&rsquo;s going on with that ! ?

Genuinely Care

I often reflect on a conversation from years ago with a former Army boss. It&rsquo;s foundational to how I understand leadership. He said that being a leader means you have to &ldquo;Genuinely care.&rdquo;

Consulting

After more than a decade in the field as an engineering leader and hands-on practitioner, I&rsquo;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&rsquo;m good at: Raising code quality (tooling,…

5173 is Vite

Vite&rsquo;s default port, 5173, is leet code for the project&rsquo;s name: 5 = &ldquo;V&rdquo; (Roman numerals 😉) 1 = &ldquo;I&rdquo; 7 = &ldquo;T&rdquo; 3 = &ldquo;E&rdquo;

Cursor on Current Directory

To load Cursor with context of the current directory, use: cursor .

The Outbox Pattern

Today I learned about the Outbox Pattern.

Leave a Trace

Always leave something behind. If you find something interesting, leave a trace that you were there.

Node REPL, No Preview

After version v12.17.0, Node&rsquo;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&rsquo;t want that? Here&rsquo;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

NVM Install and Use Latest LTS

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)

You Learn a Codebase by Changing It

How do I &ldquo;get up to speed&rdquo; in a new codebase? Changing it.

Avoid Hasty Caching

Approach caching with caution.

Law of Demeter Origin Story

The Law of Demeter is important in object-oriented programming. But where does &ldquo;Demeter&rdquo; come from?

Filled Emoji With CSS

Today I learned how to fill in an emoji with CSS. Here&rsquo;s an example: . filledEmoji { color : transparent ; text-shadow : '0 0 0 #86efac' ; }

JavaScript Wraparound Index

What I call &ldquo;wraparound&rdquo; are repeatable indices on an array. The common use case is a carousel. Here&rsquo;s how it&rsquo;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 ;

JavaScript String Concatenation

Here&rsquo;s a periodic reminder that JavaScript supports string concatenation with a plus sign: > 'foo' + 'bar' 'foobar'

JavaScript Spread a String Into An Array

Need an array of letters? Here&rsquo;s a trick: > const alpha = [... 'abcdefghijklmnopqrstuvwxyz' ]

JavaScript Array Join Comma Default Separator

When you join an array in JavaScript, the default separator is a comma: node > [ 'j' , 'a' , 'k' , 'e' ]. join () 'j,a,k,e'

JavaScript Bitwise AND

The JavaScript bitwise AND operator ( & ) can be used for some real-world tasks, like testing if a number is odd or even.

Become a Product-First Software Engineer

I think many engineers would be better contributors if they started to think more about the customer impact of their work.

Vim :Tutor Command

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

AI Policy

This page summarizes my usage of LLMs (&ldquo;AI&rdquo;) on this website.

On commenting and approving pull requests

After reviewing a lot of pull requests, I&rsquo;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.

Incremental Dependency Upgrades

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&rsquo;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…

Dependencies Go Forward

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&rsquo;ve been on v4.0 before and know it is compatible. Even if we aren’t sure that v6.0 is…

Catastrophic Mistakes Are a Team Failure

If people can make catastrophic mistakes on your team, the process is broken.

CI/CD and Engineer Morale

Why do software teams push continuous deployment so strongly? One of the most important and least discussed reasons is engineer morale.