Lightly grease a baking dish with butter and set it aside. Fill a glass with ice water and place it near your stovetop. Prepare your sink by filling it with a few inches of cold water—this will be used later to cool the fudge quickly.
In a heavy-bottomed saucepan, combine the milk, sugar, cocoa powder, and salt. Whisk thoroughly until the mixture is mostly smooth; a few small lumps are fine as they’ll dissolve once heated.
Set the saucepan over medium-low heat and allow the mixture to come to a steady boil. Stir intermittently with a heat-resistant spatula, but avoid frequent stirring, which can lead to a gritty texture. Keep the flame low and consistent to prevent the bottom from burning.
Let the mixture boil gently for around 10 minutes. During this time, the texture will begin to change. You'll notice larger bubbles give way to a uniform field of smaller, tighter ones—this is your cue to start testing.
To check for doneness, use a candy thermometer—when it hits 235°F, it's ready. If you prefer the traditional method, let a small spoonful drip into the ice water. If it forms a soft and malleable ball, the fudge has reached the soft-ball stage and is good to go.
Remove the saucepan from the heat and immediately stir in the vanilla extract and butter. Stir gently to combine. Carefully transfer the pan to the sink, setting it into the cold water bath without letting water splash into the fudge. It may sizzle slightly. Hold the pot securely and beat the mixture with a wooden spoon or heatproof spatula until it thickens slightly and begins to lose its glossy sheen.
Quickly pour the mixture into the prepared baking dish. It should spread out evenly on its own. Let it sit undisturbed at room temperature until fully cooled—about 30 minutes.
Once the fudge is firm, slice it using a sharp, thin-bladed knife. For cleaner cuts, dip the blade in hot water and dry it before each slice.