A Bit of Vyuh
Understanding the Vyuh Framework fundamentals - features, plugins, and content system
Before diving into the Entity System, let's understand the Vyuh Framework fundamentals. The Entity System is built on top of these core concepts, so understanding them will help you work more effectively.
What is Vyuh?
Vyuh is a feature-based framework for building modular, Content-driven Flutter applications at scale. It provides a structured approach to decomposing complex applications into independent, reusable features that can be assembled together.
Core Philosophy
Vyuh treats everything as content - from simple text blocks to complex business entities. This unified content model enables:
- Building applications by assembling features
- Driving UI from a Content Source (such as a CMS or a Database)
- Creating reusable components across projects
- Managing complexity through modular architecture
The Feature System
Features as Building Blocks
In Vyuh, applications are composed of features - self-contained modules that encapsulate related functionality. A feature can be described with a simple manifest that contains:
- Domain models and business logic
- UI components and layouts
- Routes and navigation
- Extensions to the framework
// A simple feature
final inventoryFeature = FeatureDescriptor(
name: 'inventory',
title: 'Inventory Management',
description: 'Manage products, orders, and stock',
icon: Icons.inventory,
routes: () async => [/* feature routes */],
extensions: [/* feature extensions */],
);Features as Building Blocks
You can keep the feature in your application as a separate folder or as a completely separate Flutter package.
Assembling Features into Applications
Applications are created by combining features:
import 'package:vyuh_core/vyuh_core.dart' as vc;
void main() {
vc.runApp(
initialLocation: '/',
features: () => [
// Core features
authFeature,
dashboardFeature,
// Business features
inventoryFeature,
orderManagementFeature,
reportingFeature,
],
plugins: vc.PluginDescriptor(
content: ContentPlugin(),
navigation: NavigationPlugin(),
network: NetworkPlugin(),
others: [
EntitySystemPlugin(),
// ... other custom plugins
],
),
);
}This composition model allows you to:
- Develop features independently as separate packages
- Reuse features across multiple applications
- Enable/disable features based on configuration
- Test features in isolation before integration
The Content System
At the heart of Vyuh is a powerful content system that treats all displayable items as content. This includes everything from simple text to complex entities.
Core Components
Every content item in Vyuh requires three key pieces:
1. TypeDescriptor
Defines the type identity and JSON serialization:
class Product extends EntityBase {
static const schemaType = 'inventory.products';
static final typeDescriptor = TypeDescriptor(
schemaType: schemaType,
title: 'Product',
fromJson: Product.fromJson,
);
// ... fields and methods
}The TypeDescriptor:
- Identifies the content type via
schemaType - Provides human-readable
title - Enables JSON deserialization via
fromJson
2. Layout Configuration
Defines the visual representation:
class ProductDetailLayout extends LayoutConfiguration<Product> {
static final typeDescriptor = TypeDescriptor(
schemaType: 'inventory.product.layout.detail',
title: 'Product Detail Layout',
fromJson: ProductDetailLayout.fromJson,
);
ProductDetailLayout() : super(schemaType: typeDescriptor.schemaType);
static ProductDetailLayout fromJson(Map<String, dynamic> json) =>
ProductDetailLayout();
@override
Widget build(BuildContext context, Product content) {
return ProductDetailView(product: content);
}
}The LayoutConfiguration:
- Extends
LayoutConfiguration<T>where T is the content type - Specifies how to render the content
- Can have multiple layouts for the same content type
- Supports CMS-driven layout selection
3. ContentBuilder
Connects content to its layouts:
ContentBuilder(
content: Product.typeDescriptor,
defaultLayout: ProductDetailLayout(),
defaultLayoutDescriptor: ProductDetailLayout.typeDescriptor,
)The ContentBuilder:
- Maps a content type to its available layouts
- Defines the default layout
- Enables runtime layout switching (CMS-driven)
Content Registration
Content is registered within features via extensions:
final inventoryFeature = FeatureDescriptor(
name: 'inventory',
title: 'Inventory Management',
icon: Icons.inventory,
extensions: [
ContentExtensionDescriptor(
contents: [
ContentDescriptor(
type: Product.typeDescriptor,
layouts: [
ProductCardLayout.typeDescriptor,
ProductDetailLayout.typeDescriptor,
],
),
],
),
],
);Extension System
Features extend the framework through extensions. Common extension types:
1. ContentExtensionDescriptor
Registers content types and their layouts:
ContentExtensionDescriptor(
contents: [
ContentDescriptor(
type: Article.typeDescriptor,
layouts: [CardLayout.typeDescriptor, FullLayout.typeDescriptor],
),
],
)2. EntityExtensionDescriptor (Entity System)
Registers business entities with CRUD operations:
EntityExtensionDescriptor(
entities: [
EntityRegistration<Product>(
productConfig, // EntityConfiguration
ContentBuilder(
content: Product.typeDescriptor,
defaultLayout: ProductDetailLayout(),
defaultLayoutDescriptor: ProductDetailLayout.typeDescriptor,
),
),
],
)Notice how the Entity System builds on top of the content system - entities are just specialized content with CRUD capabilities!
Plugins
Plugins provide cross-cutting capabilities for the entire application. They are
configured using PluginDescriptor when initializing the app with vc.runApp():
vc.runApp(
features: () => [/* features */],
plugins: vc.PluginDescriptor(
// Core framework plugins
content: ContentPlugin(), // Content rendering
navigation: NavigationPlugin(), // Routing and navigation
network: NetworkPlugin(), // API communication
auth: AuthPlugin(), // Authentication
telemetry: TelemetryPlugin(), // Analytics and logging
// Custom/domain-specific plugins
others: [
EntitySystemPlugin(), // Entity management
CustomDomainPlugin(), // Your custom plugin
],
),
);The PluginDescriptor organizes plugins by their role:
- content - Content rendering and CMS integration
- navigation - Routing and navigation behaviors
- network - HTTP client and API configuration
- auth - Authentication and authorization
- telemetry - Logging, analytics, error tracking
- others - Custom plugins like EntitySystemPlugin
How It All Fits Together
Here's the complete picture:
// 1. Define your content model
class Product extends EntityBase {
static final typeDescriptor = TypeDescriptor(
schemaType: 'inventory.products',
title: 'Product',
fromJson: Product.fromJson,
);
final String name;
final double price;
// ... other fields
}
// 2. Create layout(s) for your content
class ProductDetailLayout extends LayoutConfiguration<Product> {
static final typeDescriptor = TypeDescriptor(
schemaType: 'inventory.product.layout.detail',
title: 'Product Detail Layout',
fromJson: ProductDetailLayout.fromJson,
);
ProductDetailLayout() : super(schemaType: typeDescriptor.schemaType);
static ProductDetailLayout fromJson(Map<String, dynamic> json) =>
ProductDetailLayout();
@override
Widget build(BuildContext context, Product content) {
return ProductDetailView(product: content);
}
}
// 3. Register content in a feature
final inventoryFeature = FeatureDescriptor(
name: 'inventory',
title: 'Inventory Management',
icon: Icons.inventory,
extensions: [
EntityExtensionDescriptor(
entities: [
EntityRegistration<Product>(
productConfig,
ContentBuilder(
content: Product.typeDescriptor,
defaultLayout: ProductDetailLayout(),
defaultLayoutDescriptor: ProductDetailLayout.typeDescriptor,
),
),
],
),
],
);
// 4. Assemble features and plugins into your app
void main() {
vc.runApp(
initialLocation: '/',
features: () => [
inventoryFeature,
// ... other features
],
plugins: vc.PluginDescriptor(
content: ContentPlugin(),
navigation: NavigationPlugin(),
network: NetworkPlugin(),
others: [
EntitySystemPlugin(),
// ... other custom plugins
],
),
);
}Key Takeaways
Understanding these Vyuh fundamentals is essential:
1. Everything is a Feature
Decompose your application into independent features. Features are self-contained modules that can be developed, tested, and deployed separately.
2. Content is the Foundation
All visual elements are content with:
- A TypeDescriptor (identity + serialization)
- Layouts (visual representation)
- A ContentBuilder (connecting the two)
3. Plugins for Cross-Cutting Capabilities
Plugins provide application-wide capabilities that span across features:
- Organized by role via
PluginDescriptor(content, navigation, network, auth, telemetry) - Shared infrastructure - Authentication, logging, API clients used by all features
- Framework integration - Extend core Vyuh capabilities at the platform level
4. Extensions Enable Composition
Extensions allow you to build independent pieces and compose them together:
- ContentExtensionDescriptor - Register displayable content independently
- EntityExtensionDescriptor - Register business entities as separate modules
- Independent development - Build extensions in isolation, then compose into features
- Reusable components - Share extensions across multiple features and applications
5. Composition Over Inheritance
The classic software engineering principle applied throughout Vyuh:
- Features - Compose independent domain modules into applications
- Plugins - Compose cross-cutting capabilities into a unified system
- Extensions - Compose specialized capabilities into features
- Result - Flexible, maintainable architectures that scale
Decompose complexity into features and plugins, build independently, then assemble through composition.
Why This Matters for Entity System
The Entity System you're about to learn is built entirely on these foundations:
- Entities are content - They use
TypeDescriptorandContentBuilder - Entity features - Registered via
EntityExtensionDescriptorextension - Entity layouts - Multiple views (list, detail, analytics) of entity content
- Feature composition - Entity features compose with other features
Now that you understand how Vyuh works, you're ready to dive into the Entity System and see how these concepts power enterprise-grade CRUD applications!
Next Steps
- Getting Started - Create your first entity
- Philosophy - Deep dive into Entity System design