The river has its headwaters in the Blue Ridge Mountains in southwestern Virginia at Lafayette in Montgomery County where the North Fork and South Fork of the river merge. The North Fork, approximately 30 mi (50 km) long, rises between two mountain ridges and flows initially southwest, then loops back to the northeast. The South Fork, approximately 20 mi (30 km) long, rises in several streams in the mountains on the border of Floyd, Roanoke, and Montgomery counties and flows generally north, joining the North Fork from the south.
The combined stream flows northeast between mountain ridges, approximately 10 mi (15 km) to Salem, then east through the city of Roanoke, emerging from a gorge in the Blue Ridge Mountains southeast of Roanoke and forming the boundary between Franklin and Bedford counties. The river flows generally east-southeast across the Piedmont of southern Virginia and enters northeastern North Carolina, passing north of Roanoke Rapids. The river then flows southeast in a zigzag course across the coastal plain and then briefly turns north as it enters Batchelor Bay on the western end Albemarle Sound.
The river is impounded twice in succession in the Piedmont of southwestern Virginia downstream from Roanoke to form the Smith Mountain Lake and Leesville Lake reservoirs. Farther downstream in southern Mecklenburg County along the North Carolina border, the river is impounded to form the expansive Kerr Lake. In northeastern North Carolina, 3 mi (5 km) west of Roanoke Rapids, the river is impounded to form the Lake Gaston reservoir, which stretches upstream into Virginia to the John H. Kerr Dam.
The name "Roanoke" is said to have originated from an Algonquian word for shell "money". In 1883, the small town of Big Lick on the river was selected as a major shops and terminal point for the new Norfolk and Western Railway to meet the Shenandoah Valley Railroad. Big Lick was renamed Roanoke for the river that bisected it, as the surrounding Roanoke County had been in 1838.