Despite their limited lifespan and reduced cost, nano-satellite missions have proved to be suitable platforms for Earth observation, scientific experiments and technology demonstration. During the last years, the number of nanosatellite missions has noticeably increased, posing the need to improve several system characteristics to ultimately endorse the full potential of this class of spacecraft. In this context, this paper presents three design guidelines that can be applied in nano-satellite software in order to improve the system robustness, modularity and autonomy. The design guidelines presented in this paper, namely, hierarchy-enabled robustness, payload-oriented modularity, and on-board planning capabilities, are complemented with a structured review of complementary software techniques and architectural concepts that have been found in the literature. The paper justifies that these system-wide qualities are some of the most critical when designing flight software for CubeSat-like spacecraft and explores how they can improve mission performances and operability, enhance the system's tolerance to failures and ease the development cycles. Finally, this paper illustrates the application of the design guidelines by detailing the on-board software architecture for the 3 Cat-1, a CubeSat program carried out at the Nano-Satellite and Payload Laboratory of the Technical University of Catalonia (UPC BarcelonaTech).