Stokes slammed 204 not out as England reached 513 for five at lunch. He scored 130 runs before lunch, a Test record, as England added 196 runs to their overnight total of 317 for five.
Jonny Bairstow provided solid support, making 95 not out as he shared an unbeaten partnership of 290 with Stokes, an England record for the sixth wicket.
The left-handed Stokes needed only 12 balls to go from his overnight 74 to his third Test century, which he made off 105 deliveries with 16 fours and a six. He quickly went past his previous highest Test score, 120 against Australia at Perth two seasons ago.
Stokes joined a select group of players who have scored a century before lunch in Test cricket. The previous highest number of runs before the break was 123 by Leslie Ames for England against South Africa at The Oval in 1935.
Also Read
Stokes was the main aggressor as 45 runs were hit off the first four overs of the day, bowled by Morne Morkel and Chris Morris, in a continuation of the assault against the second new ball late on the first afternoon.
By the end of the first hour, which yielded 103 runs off 13 overs, there were five men on the boundary.
The two hours before lunch yielded 196 runs despite South Africa bowling only 25 overs.
By lunch Bairstow was in reach of a maiden Test century, having equalled his highest score of 95, made against South Africa at Lord's in 2012.