The relevance of IoT-based solutions in everyday life is continuously increasing. The capability to sense the world, activate computation based on data gathered by sensors, and possibly produce reactions on the world itself results in an almost never-ending identification of novel IoT solutions and application scenarios. Nonetheless, IoT’s intrinsic nature, which includes a high degree of variability in used devices, data formats, resources, and communication protocols, complicates the design, development, reuse and customisation of IoT-based software systems. In addition, customers require personalised solutions strongly based on their specific requirements. Reducing the complexity of building customised solutions and increasing the reusability of developed artefacts are among the topmost challenges for enterprises and IoT application developers. Upon these challenges, we propose a model-driven approach organising the modelling and development of IoT applications in different steps, handling the complexity in representing the IoT domain variability, and empowering the reusability of design decisions and artefacts to simplify the derivation of customised IoT applications. Our proposal is named FloWare. It follows the typical path of an MDE solution, providing modelling support through feature models to fully represent and handle the possible variability of devices in a specific IoT application domain. Once a specific configuration has been selected, this will be complemented with specific information about the deployment context to automatically derive fragments of the IoT applications, that will be successively combined by the developer within a low-code development environment. The approach is fully supported by a toolchain that has been released for public use.