He tells a story of a highly experienced baker. This is the baker’s recipe for a chocolate cake:

This is the baker’s recipe for a ginger cake:

He talks about how the recipe for ginger cake is deceptively simple. Ginger and chocolate are two very different ingredients requiring very different preparation and baking methods. The point is that the baker knows this. They do not need to painstakingly rewrite all of the instructions for the ginger cake because they are experienced enough to know what it means to bake with ginger, they instinctively know where the instructions diverge, and how.
This is a pattern for getting started with something quickly.
He tells another story. He sits down with another developer to build a new web component, just like another web component. He thinks to himself, “what we should do is refactor out the bit in common, make it a shared library, and then create this new thing”. The other developer then does:
- Ctrl + A
- Ctrl + C
- Ctrl + V
He copies the whole first component, pastes it into a new file, and then begins deleting away unnecessary stuff. He now has a good starting point for his new component.
This is a far more efficient way of simply getting started with something new, than it would have been to go the traditional “good” way.
This only works, if you are intimately familiar with the code you are copying.
This is the opposite of DRY. DRY has a dark side, and that dark side is coupling. Introducing abstractions and sharing them between components, couples those components together. You can no longer reason about one component, without needing to consider the implications on the other component.
DRY is not a best practice. DRY is a pattern with positives: reducing duplication and negatives: increasing coupling.
Duplication across components is okay, duplication within a component is probably not.