He began his career with Roma in 2012, and later spent a season on loan with Sampdoria in 2014, before moving to Milan in 2015. At the start of the 2018–19 Serie A season, he was named the team’s captain following Leonardo Bonucci’s return to Juventus.
A product of Roma youth academy, Romagnoli was included in the first team squad by new head coach Zdeněk Zeman at age 17. He made his senior debut on 11 December 2012 against Atalanta, playing the full game in Coppa Italia as a starter. He made his Serie A debut 12 days later, as a substitute in the final minutes of a league game against Milan. He scored his first goal in Serie A on 3 March 2013 against Genoa.
He found more first-team opportunities in the second half of the 2013–14 season under new manager Rudi Garcia, both at full-back and in the centre of defence. On 31 May 2014, Romagnoli signed a new four-year contract with Roma.
Loan to Sampdoria
On 1 September 2014, Romagnoli was loaned to Sampdoria for €500,000, with an option to purchase for €2 million, as well as a counter-option of €750,000. Romagnoli made his Sampdoria debut as a late substitute in a 2–0 victory against Torino on 14 September. He scored his first goal for Sampdoria on 24 September 2014 in a 2–1 defeat of Chievo. In June 2015, Roma activated the buy-back clause and he returned to the club.
On 11 August 2015, he was sold to Milan for a fee of €25 million, signing a five-year contract. In addition, there is a sell-on clause entitling Roma to 30% over the value of €25 million. He made his official debut for Milan on 18 August, keeping a clean sheet in a 2–0 win over Perugia in Coppa Italia. Six days later, he made his first appearance in the league with the club, as Milan lost 2–0 to Fiorentina. On 1 March 2016, he scored his first goal for Milan in a 5–0 win against Alessandria in Coppa Italia. This match sent Milan to the final for the first time since 2003. He concluded his first season with Milan with 40 appearances in all competitions and one goal.
Romagnoli made his first appearance of the 2016–17 season in a 3–2 victory in Serie A against Torino. On 23 December, Romagnoli helped lead Milan to victory in the Supercoppa Italiana, playing the full 120 minutes as Milan beat Juventus 4–3 in the penalty shoot-out following a 1–1 draw after extra time. On 15 April 2017, Romagnoli scored his first ever Serie A goal for Milan in the Derby della Madonnina.
After missing Milan’s first 4 games of the season due to injury, he returned to the squad and he made his return to play the second leg of Europa league play offs against Shkëndija. On 19 September 2017, he made his first appearance of the Serie A season against Udinese.
Following Leonardo Bonucci’s return to Juventus, Romagnoli was appointed as Milan’s team captain. Romagnoli scored stoppage-time winning goals two times in five days for Milan, earning his club a 2-1 win over Genoa and a 1-0 over Udinese.