Techniques are presented for the design of computer programs that are proved to meet stated specifications. The design strategy is the simultaneous step-wise refinement of both the program and its proof so that at each step the program constructed so far is proved. At each step, the specifications for a single program unit are given, the unit is designed, and then proved, by automatically supportable methods, before going on to successive steps. The proof i) shows that the program unit meets its specifications, ii) exhibits any assumptions the unit makes about the problem domain, and iii) defines the specifications for units to be designed in later steps. The design process is based on the refinement of operational and data abstractions in both the program and its specifications. These abstractions are what allow the proof at each step to be supported by automatic, or interactive, program proving systems. The abstractions also keep the proofs of the individual units at an appropriate level of abstraction and also largely independent, thus significantly reducing the size of the complete proof of the entire program. These techniques of provable programming are illustrated by two examples.