GLOWbe Studio - Initial Software Architecture
Date Proposed: 2025-06-13
Date Decided: 2025-06-16
Status: Decided
Context
We need to select a primary technology stack for the GLOWbe Studio software application. Since GLOWbe Studio is primarily for creating, editing and rendering potentially complex light effects, including possibly a 3D viewport to render effects on objects in real-time, this requires a highly custom and performant UI. GLOWbe Studio must run cross-platform on Windows, macOS, iOS, and Android. Idially, the core business logic should be shared across all platforms, and the design langua og the GLOWbe shoudl be consistent across platforms, which is preferred over using the native component designs of each platform.
Decision Drivers
- Performance: The application must feel "snappy." UI responsiveness and real-time 3D rendering are relevant.
- UI/UX Control: Need for a highly customized UI (e.g., timeline) that is consistent across all platforms and not bound by native OS look-and-feel.
- Cross-Platform Reach: A single codebase must target desktops (Windows, macOS) and mobile (iOS, Android).
- 3D Rendering Capability: The framework must integrate a performant 3D viewport.
- Hardware Communication: The application will have to communicate with the GLOWhub device. Options must be available for USB, Bluetooth and Wifi.
- Licensing: The chosen technology must (ideally) allow for a closed-source, commercially distributed application.
- Ecosystem Maturity: As we are developing a commercial product, the framework should be stable, well-documented, and have a strong community.
Considered Options
The following options are considered:
- C++ Ecosystem: Qt Framework
- .NET Ecosystem: Avalonia
- Web Ecosystem: Electron / React Native
- Web + Rust Ecosystem: Tauri
- Rust Ecosystem: Slint / Iced
- Game Engines: Unreal Engine / Unity / Godot
- Direct Graphics API: C++/Rust with OpenGL/Vulkan
- Fully Native Stacks: Shared C++ Core with Native UIs
Option 1: C++ Ecosystem - Qt
A mature C++ framework for creating cross-platform applications with a strong focus on custom UIs and native performance.
Pros:
- Performance: Compiles directly to native code, offering excellent performance for both UI and computation.
- UI/3D: Provides two paths for 3D: the high-level Qt 3D module and direct, low-level integration with graphics APIs like OpenGL/Vulkan. This is ideal for a custom renderer.
- Maturity & Stability: Battle-tested for decades and used in professional-grade creative software.
- Complete Ecosystem: Offers a vast set of libraries for everything from networking to multimedia, managed within a cohesive framework.
Cons:
- Licensing Complexity: Requires a choice between a paid Commercial license for simplicity and static linking, or strict adherence to LGPLv3 rules for the free open-source version.
- Development Speed: The C++ compile-link cycle is inherently slower than that of scripting languages or .NET.
Option 2: .NET Ecosystem - Avalonia
A modern, open-source .NET framework for creating cross-platform applications using C# and a XAML-based UI definition language.
Pros:
- Developer Experience: C# is a modern, productive language. Tooling is excellent.
- Good Performance: As a compiled .NET language, performance is very strong, though it may not match heavily optimized C++ in all cases.
Cons:
- 3D is Less Mature: Integrating high-performance, custom 3D rendering is less straightforward than in Qt or a game engine. It often requires hosting a DirectX/OpenGL context within an Avalonia control, which can be complex.
- Ecosystem Age: While mature and stable, it doesn't have the same multi-decade track record as Qt in high-end graphics applications.
- Ecosystem Longevity: Avalonia is newer than Qt and may not have the same level of community support or long-term longevity.
Option 3: Web Ecosystem - Electron / React Native
A framework for building desktop applications using web technologies (HTML, CSS, JavaScript/TypeScript).
Pros:
- Fast UI Development: Leverages the rapid development cycle of web technologies.
- Tooling: Familiar web tooling is available
Cons:
- 3D Rendering is Limited: All 3D rendering is confined to WebGL within the browser view. This lacks the power and direct GPU access of native graphics APIs.
- UI Performance Concerns: Webview will always be inherintly slower than compiled C++ or .NET applications, especially for complex UIs and real-time rendering.
- Hardware Communication: Limited to web API's for hardware communication (Electron).
- No Fully Cross-Platform Focus: Electron is focussed on desktop while React Native on mobile.
Option 4: Web + Rust Ecosystem - Tauri
Framework that allows for building cross-platform desktop and mobile applications using web technologies for the frontend and Rust in the backend.
Pros:
- Small Bundle Size: Reuses the OS's WebView, avoiding the need to bundle Chromium, which results in much smaller and more memory-efficient apps than Electron.
- Safety: Compile-time memory safety guarantees.
- Tooling: Rust's build system and package manager (Cargo) are modern and highly regarded.
Cons:
- Mobile is Immature: As of Tauri v2, the mobiel integration is still in beta.
- Hardware Communication: Possible less mature as Qt
- 3D Rendering is Limited: All 3D rendering is confined to WebGL within the browser view. This lacks the power and direct GPU access of native graphics APIs.
Option 5: Rust Ecosystem - Slint / Iced
Native UI toolkits for the Rust programming language, which is known for its performance and memory safety.
Pros:
- Performance & Safety: Combines the performance of C++ with compile-time memory safety guarantees.
- Tooling: Rust's build system and package manager (Cargo) are modern and highly regarded.
Cons:
- Ecosystem Immaturity: The GUI frameworks are much newer than alternatives. They lack the feature completeness, stability, and extensive widget libraries of Qt or Avalonia.
- Complex 3D Integration: Similar to Avalonia, integrating a custom 3D viewport is a significant, low-level task without the mature helper classes Qt provides.
Option 6: Game Engines - Unreal / Unity / Godot
Using a real-time 3D engine as the foundation for the entire application.
Pros:
- 3D Performance: This is their primary purpose. The rendering pipeline is world-class and ready for any lighting effect.
- Excellent UI Tools: Modern game engines have sophisticated UI editors (e.g., Unreal's UMG) capable of creating complex, animated, and custom interfaces.
Cons:
- Heavyweight: Applications come with the overhead of a full game engine, leading to larger file sizes and memory usage.
- Non-Standard Paradigm: Building a traditional desktop application (with native-style file dialogs, window management, etc.) can be awkward and requires working against the grain of the engine's design.
- Licensing (Unreal/Unity): While they have free tiers, commercial use for non-game applications often requires expensive "Pro" or "Enterprise" licenses.
Option 7: Direct Graphics API - OpenGL / Vulkan
Forgoing a comprehensive UI framework entirely (C++/Rust with OpenGL/Vulkan). This approach involves writing a custom C++ application that uses a library like GLFW or SDL to create a window and receive input. All UI elements (buttons, sliders, text, windows) would be rendered manually using OpenGL primitives. A library like Dear ImGui is often used in this approach to provide an immediate-mode UI layer on top of the graphics context.
Pros:
- Control & Performance: You have direct, unabstracted control over the entire rendering pipeline. There is zero framework overhead, which can lead to the smallest possible memory footprint and CPU usage.
- No Licensing Constraints: You are in full control of your dependencies, making it easy to remain entirely within permissive licenses (MIT, Zlib, etc.).
- Excellent for Tooling/Debug UIs: The Dear ImGui library is exceptionally good and fast for creating developer tools, debug overlays, and simple editor interfaces.
Cons:
- Development Effort: You are effectively building a custom UI engine from the ground up. Features that a framework like Qt provides for free—such as complex layouts, rich text editing, accessibility, animations, high-DPI scaling, and a mature widget set—would need to be implemented from scratch. This could add years to the development timeline.
- Poor for "Polished" UIs: While Dear ImGui is fantastic for functional UIs, creating a polished, consumer-facing application with the aesthetic quality of Adobe or modern creative software is extremely difficult and not what it's designed for.
- Cross-Platform Complexity: While libraries like SDL handle windowing and input across desktops, extending this to mobile (iOS/Android) is a massive leap in complexity. You would have to write significant amounts of platform-specific Objective-C/Swift and Java/Kotlin to bootstrap the application, handle touch input, and manage the app lifecycle. This is a task that full-featured frameworks handle for you.
Option 8: Fully Native Stacks
This approach uses a shared C++ core library for the common business logic, but the entire User Interface for each platform is built using the OS vendor's recommended native language and UI toolkit.
- Windows: C# with WinUI 3 or C++ with MFC/WinAPI.
- macOS: Swift/Objective-C with SwiftUI or AppKit.
- iOS: Swift/Objective-C with SwiftUI or UIKit.
- Android: Kotlin/Java with Jetpack Compose or Android Views.
Pros:
- Best Platform Integration & Fidelity: Unmatched access to every native OS feature, API, and service (e.g., system-level file pickers, accessibility tools, share sheets). The app can conform perfectly to each platform's design guidelines.
- Highest Performance Ceiling: The UI layer is built with the platform's most optimized, first-party toolkits. Clear Talent Pools: It is straightforward to hire specialized native developers (e.g., an "iOS developer" or "Windows developer").
Cons:
- Contradicts a Core Requirement: This approach makes it exceptionally difficult to achieve the user's stated goal of a consistent, custom UI design across all platforms. The fundamental purpose of native toolkits is to create UIs that look and feel like the host OS.
- Duplication of Effort: The entire UI—every button, panel, layout, and animation—must be implemented independently for each target platform. This multiplies development time, cost, and maintenance effort by a factor of 3-4x.
- Complex "Glue" Code: Requires a robust Foreign Function Interface (FFI) to connect the shared C++ core to each native language (C# P/Invoke, Swift C interop, Kotlin JNI). This boundary layer is complex to write, debug, and maintain.
Conclusion
We choose to go with the C++ Qt Framework. This decision is based on the following rationale:
- Performance Profile: Qt offers better performance than any of the web frameworks. Customizability:
- Maturity and Suitability: Qt is the de facto industry standard for this exact type of application (professional, creative, cross-platform tools). Its architecture is proven, stable, and built for the task. This significantly de-risks the project.
- Directly Meets Core Requirements: It directly addresses the need for a custom, cross-platform UI, a powerful integrated 3D scene, hardware interfacing, and the performance ceiling required for an effects editor. While game engines offer superior 3D, Qt provides a far better foundation for a traditional desktop application structure. While Avalonia offers possibly a better developer experience, its 3D integration story is not as mature. The Web and Rust ecosystems are not yet suitable due to maturity and longevity concerns, and possibly limitations in 3D rendering capabilities for this class of application.
Note that compatibility with the web is not a requirement and not a driving factor in this decision. Compilation to webassembly in mind, like Avalonia provides, is this not something that sways the decision.
The licensing question of Qt is manageable by either purchasing a reasonably priced small business license for maximum simplicity or by adhering to the clear rules of the LGPLv3 license.
Note on Tauri:
Tauri is another strong contender, as it is assumed that its native webview integration will also satisfy the UI performance criteria, and the Rust language is considered a highly desirable language. Currently, a deal breaker is the beta state of its mobile integration, and a general impression of immaturity for mobile.
Possible migration path to Rust:
Initially going with Qt for its maturity still allows for a somewhat streamlined migration path in case the Rust ecosustem matures enough. This could look like:
- Migrate the core logic to Rust, and use Qt Rust language bindings
- Migrate the GUI code to a mature Rust GUI (Slint, ...) or Web (Tauri) framework.