Difference between widgets and modules
Architectural differences between widgets (editor-web) and modules (modular-universe)
Difference between widgets and modules
Summary: Widgets are embeddable UI components rendered directly inside
editor-web-lib, while Modules are platform-agnostic feature packages orchestrated by the modular-universe runtime. They share common design goals (reusability, discoverability) but fulfill different contracts.
Widgets (Editor Web)
- Contract: Implement the
Widgetinterface from@libs-foundational/core-modelsand render throughWidgetLibraryComponent/WidgetLivePreviewComponent. - State model:
propertyGroups,propertyValues,responsiveSize,events. Values persist viaWidgetStorageService+ Flash Persistence. - Responsiveness: Driven by
ResponsiveWidgetServiceandlibResponsiveWidgetPropsdirective. Breakpoint changes trigger computed styles and layout adjustments per widget. - Creation workflow: Widget Builder (AI + manual) produces responsive-ready configurations and enforces accessibility metadata.
- Platform scope: Web-first (Angular 20). Flutter/React support is not automatic, but widgets can sit inside modules as embeddables.
- Usage: Drag-and-drop inside the editor canvas, exportable as embeddables for modules.
Modules (Modular Universe)
- Contract: Implement
BrowserModuleContractwith aModuleManifestdescribing regions, lifecycle hooks, permissions, and multi-platform output. - State model:
regionswith named slots (e.g.left,right),embeddableComponents, runtime configuration (ModuleConfigurationService). - Responsiveness: Declared at module level (manifest metadata for web/flutter/react) and executed by modular-universe layout engines. Region layouts adapt cross-platform.
- Creation workflow: Visual Module Workbench (modularity-lib) or NX generators; outputs NX libraries ready for lazy loading and multi-app reuse.
- Platform scope: Platform-agnostic by design (web, Flutter, React Native) with exported renderers per platform.
- Usage: Compose entire feature experiences (dashboards, layouts) and host widgets/embeddables inside module regions.
Key Differences
| Dimension | Widgets | Modules | Notes |
|---|---|---|---|
| Purpose | Fine-grained reusable UI blocks | Feature-grade packages (layouts, flows, business logic) | Widgets can be embedded inside modules |
| Contract | Widget interface + responsive directives |
BrowserModuleContract + manifest |
Different lifecycle & metadata |
| Responsiveness | Per-widget computed breakpoints (ResponsiveWidgetService) |
Layout metadata + region system executed by modular runtime | Need shared language so layouts can react to breakpoints consistently |
| Platforms | Web (Angular) | Web + Flutter + React Native (via adapters) | Layout modules often already supply cross-platform info |
| State persistence | Flash persistence (WidgetStorageService, property values) |
Universe context + module configuration services | Modules track tenant/universe state |
| Composition model | Widgets nest widgets but do not own regions | Modules expose regions that host widgets or other modules | Ensures modules orchestrate experiences |
| Tooling | Widget Builder (AI, property editor) | Module Workbench (visual export) / NX libs | Both publish into unified registry but should be filtered by kind |
Case study: Pricing Widget vs Two Column Equal Renderer
| Aspect | Pricing Widget (@libs-widgets/widgets) |
Two Column Equal Renderer (modules/layout/two-column-equal) |
|---|---|---|
| Rendering | Angular component using responsive directives and widget config | Module embeddable expecting regions input populated by modular runtime |
| Responsive behavior | Breakpoint-aware styles, toggles between layout modes | Manifest metadata describes grid across web/flutter/react |
| Data contract | Plans, features, CTA buttons, property groups | Regions, config, gap—no widget property groups |
| Scope | Inserted directly in editor web | Consumed by modular-universe as layout skeleton |
Observation: Exposing module renderers inside the widget palette without adaptation leads to UX confusion and runtime mismatch. Conversely, widgets lack the cross-platform metadata modules already provide.
What needs to happen next
- Explicitly classify registry entries so editor-web only offers components that satisfy the widget contract, while modular-universe can consume both widgets and layout modules.
- Promote responsiveness to a shared contract (e.g.,
ResponsiveDefinition) so layout modules can reuse the widget breakpoint engine for web, while still emitting platform metadata for Flutter/React. - Ensure widget-builder output is “embeddable-ready” (property groups + manifest metadata) so modules can embed widgets without manual glue.
- Document a bridging strategy (see plan) so layout modules adopt the widget responsive API on web while maintaining their multi-platform regions.
These findings feed directly into the “best of both worlds” plan. See plans/widgets-modules-best-of-both.plan.md for actionable steps.