Bonaventura started his senior career at Atalanta in the Serie A in 2007, his impressive performances earning him a €7 million transfer to Milan in 2014. Bonaventura has been a youth national team member since 2008. He made his senior international debut on 31 May 2013, in a friendly match against San Marino.
After playing for San Francesco 93' youth team, he was transferred to Tolentino, where he was noticed by one of Atalanta's scouts, Antonio Bongiorni. Bonaventura made his debut with Atalanta on 4 May 2008, in a match against Livorno. He only played this match in the whole 2007–08 season. He appeared again on 9 November, against Fiorentina.
On 13 January 2009, Atalanta announced he had joined Pergocrema on loan for the remainder of the 2008–09 season. Five days later, he made his debut for Pergocrema, getting on the scoresheet in a match against Sambenedettese. He made three more appearances before returning to Atalanta.
He returned to La Dea, but had to wait until January 2010 to appear again, this time against Palermo. On 1 February, he joined Serie B club Padova on loan until the end of the season. He made his debut for the club on the 20th, against Triestina.
In June 2010, Padova decided not to buy him outright, and Bonaventura returned to Atalanta, signing a contract extension until 2015.
On 9 November, he scored his first Atalanta goal, against Modena. He played a key part for La Dea in 2010–11 season, scoring nine times, with his club being crowned champions. On 11 April 2012, he scored his first Serie A goal, against Napoli, before scoring again in a 2–0 victory against Fiorentina on the 29th of April. He scored his first double on the 3rd March 2013, in a 2–0 victory against Siena.
On 1 September, the last day of the Italian transfer window, Milan announced the signature of Bonaventura from Atalanta for a fee reported to be around €7 million after they failed to sign Jonathan Biabiany. His agent later revealed that Bonaventura cried after signing for Milan as his dream became true. He was given the number 28, which was previously worn by Urby Emanuelson. On September 14, Bonaventura scored a goal on his debut as Milan beat Parma 5–4. Bonaventura scored his second goal for Milan on October 29 against Cagliari and was voted man of the match. On December 12, Bonaventura scored a powerful header and assisted Jérémy Ménez's goal as Milan defeated Napoli 2–0; Bonaventura was also voted man of the match against Napoli and again in the next week against Roma. The following match against Sassuolo, he scored a goal and later in the match he received a second yellow card and was sent off. It was the first time in his career that he was sent off. On 30 May, he scored twice against his former team Atalanta in a 3–1 victory. Bonaventura finished his first season at Milan with 7 goals and 4 assists in all competitions.
On 23 August 2015, Bonaventura made his season debut as Milan lost 2–0 to Fiorentina. The following match against Empoli, Bonaventura came on the pitch as the substitute for Suso in the 55th minute and managed to assist Luiz Adriano's winning goal from a corner kick 15 minutes later. On 19 September, Bonaventura assisted Carlos Bacca's first goal and scored directly from a free-kick in a 3–2 win over Palermo. He also gained another assist and goal in Milan's next game, the 2–3 win over Udinese. Once again, he assisted both Carlos Bacca's and Philippe Mexès' goals against Lazio in the 3–1 away win on 1 November. He continued to perform well under the team's coach Siniša Mihajlović and became a fundamental player for his team throughout the season. After missing a 0–0 draw against his former team Atalanta through suspension, he scored the opener in a 4–1 defeat of Sampdoria on 28 November. He scored again in his next game on 1 December, a 3–1 Coppa Italia defeat of Crotone, via a brilliant 20-yard free kick. On 20 December he assisted Carlos Bacca's goal and scored a late goal as Milan beat Frosinone 4–2. On 17 January 2016, he provided another assist for Carlos Bacca as the Rossoneri beat Fiorentina 2–0. He ended the season with 7 goals and 8 assists in all competitions as Milan finished 7th in Serie A, lost the Coppa Italia final against Juventus at extra time.
At the beginning of the season, Bonaventura switched his number from 28 to 5. He started Milan's opening match of the Serie A season against Torino. In the second half of the match, he was fouled inside the six-yard box by Joel Obi and Milan was given a penalty which was converted by Carlos Bacca to complete his hat-trick in Milan's 3–2 win. He scored his first goal of the season on 2 October in Milan's memorable comeback against Sassuolo as the game finished 4–3. The following week he assisted M'Baye Niang's goal against ChievoVerona in a 3–1 win. He also assisted Suso's first goal in the 2–2 draw against city rivals, Inter. On 23 December 2016, Bonaventura scored the equalising goal in the Supercoppa Italiana against Juventus; he later netted his penalty in the resulting shoot-out, helping Milan to a 4–3 victory. He signed a contract extension through 2020 with Milan on 18 January 2017. On 29 January, Bonaventura suffered an injury in a match against Udinese which ruled him out for the rest of the season following surgery on a thigh injury; earlier in that match, he scored Milan's goal in the 2–1 loss. He returned to the squad for the last game of the season against Cagliari on 28 May, but couldn't make an appearance during the match as Milan lost 2–1. He ended the season with 5 goals and 4 assists in 22 appearances in all competition as Milan finished 6th in Serie A, was knocked out of Coppa Italia in Quarter-finals by Juventus and won the Supercoppa Italiana.
Bonaventura played his first game in Europe in a 1–0 win against CS U Craiova in the first leg of Milan's Europa League qualification match on 27 July 2017. He also featured in the second leg the following week, in which he scored the first goal in their 2–0 win. It was his first goal in a European competition and he was voted Man of the Match thereafter for his performance. On 17 August, he got a late injury in Milan's Europa league playoff match against Shkëndija. On 14 September 2017, Bonaventura made his 100th Milan appearance, in a 5–1 away win against FK Austria Wien.
After featuring with under-19, under-20 levels, Bonaventura made his debut with the senior squad on 31 May 2013, in a 4–0 victory against San Marino under Cesare Prandelli. His second game for Italy was 16 months later in a friendly against Albania which he managed to assist Stefano Okaka's winning goal. He was named to Antonio Conte's Preliminary 30-man Italy squad for UEFA Euro 2016. However he could not make it into the final 23-man and was left out of the squad.
A quick, hard-working, and creative offensive midfielder, with great vision, passing, and technique, Bonaventura is a versatile player who is capable of playing in several midfield positions; in addition to his favoured position behind the strikers, he has also often been deployed as a central midfielder, or as a left winger. He is talented in keeping possession effectively, due to his ball skills, and at creating space or chances for teammates through his movement and awareness. In addition to his ability to assist goals, he is also capable of scoring them, due to his powerful striking ability from distance with his right foot and ability to make attacking runs. He has also stood out for his leadership and maturity as a footballer. Due to his effectiveness in the game, he was nicknamed "Jack" (from poker); because as the card falls on the field, its presence never goes unnoticed.As of 16 September 2017.
As of 12 November 2016
Serie B: 2010–11
Supercoppa Italiana: 2016
Premio Gentleman: 2016