Make the dough. In the stand mixer bowl with the paddle attachment, mix together the bread flour, sugar, instant yeast, and milk until combined. The dough will be crumbly and that's ok. (If using active dry yeast, see notes)
Add eggs and salt. Once mixed together, add in the eggs in at a time and then the salt. Mix until the dough begins to form. The dough will be really sticky at this point.
Switch to your dough hook and knead at medium speed for 7 minutes until the dough is no longer sticky. The dough should be smooth, elastic and should spring back when you press your finger into it.
Add butter. Then add softened butter mixing on medium speed. Mix until incorporated. (If you don't have a stand mixer, see notes)
Increase speed to high (10 speed) and knead for about 15-20 minutes. You will know the dough is done if it passes the window-pane test: pinch a small piece of dough from the ball and stretch it. It should not break easily, and light should be able to shine through it revealing your fingers.
Proof the dough. Roll and tuck the dough under itself to form a smooth ball. Place in a lightly greased bowl, cover with plastic wrap and place the dough in a warm place (oven at 100F) for about 1 hour or double in size.
Remove the dough and knead. Once doubled in size, check to see if the dough is proofed by poking the dough, the dough should not bounce back. Deflate the dough and knead on a lightly floured surface for about 3-4 minutes to relax and smooth the dough.
Divide the dough and shape into balls. Divide the dough into 8 equal pieces. Gently tuck the dough balls under itself to tighten the dough and form smooth buns.
Proof the dough again. On a parchment-lined baking sheet, cover loosely with plastic wrap or a towel and let them rise for 30 minutes.
Brush with egg wash and bake. Bake at 350°F for 18-20 minutes or until golden brown.