The question Fiori Elements or Freestyle Fiori? occupies many UI developers in the SAP environment. Both approaches have their place - but when is which one right? This article provides a well-founded decision guide with concrete code examples and a clear decision matrix.
Overview: The Two Worlds of Fiori Development
┌────────────────────────────────────────────────────────────────────┐│ SAP Fiori UI Development │├────────────────────────────────────────────────────────────────────┤│ ││ ┌─────────────────────────┐ ┌─────────────────────────────┐ ││ │ Fiori Elements │ │ Freestyle Fiori │ ││ │ (Annotation-based) │ │ (SAPUI5 Custom) │ ││ ├─────────────────────────┤ ├─────────────────────────────┤ ││ │ • Automatic UI │ │ • Full UI control │ ││ │ • CDS Annotations │ │ • XML Views + Controller │ ││ │ • No JavaScript │ │ • JavaScript/TypeScript │ ││ │ • Templates (List, OP) │ │ • Custom Components │ ││ │ • SAP Updates included │ │ • Own maintenance │ ││ └─────────────────────────┘ └─────────────────────────────┘ ││ ││ Effort: ●○○○○ Effort: ●●●●● ││ Flexibility: ●●○○○ Flexibility: ●●●●● ││ │└────────────────────────────────────────────────────────────────────┘Quick Comparison
| Aspect | Fiori Elements | Freestyle Fiori |
|---|---|---|
| Development effort | Low (1-2 days) | High (1-2 weeks) |
| UI flexibility | Limited (templates) | Unlimited |
| Maintenance effort | Minimal | Continuous |
| Learning curve | CDS Annotations | SAPUI5/JavaScript |
| UX consistency | Automatically SAP-compliant | Must be ensured manually |
| Updates | Delivered by SAP | Independent |
| Debugging | More difficult (framework) | Easier (own code) |
What Are Fiori Elements?
Fiori Elements is SAP’s approach for declarative UI development. Instead of writing UI code, you define the interface through annotations in the CDS data model.
How Fiori Elements Works
┌─────────────────────────────────────────────────────────────────┐│ Fiori Elements │├─────────────────────────────────────────────────────────────────┤│ ││ CDS View + Annotations ││ │ ││ ▼ ││ ┌───────────────────┐ ││ │ Fiori Elements │ ──▶ Automatic UI Generation ││ │ Runtime │ ││ └───────────────────┘ ││ │ ││ ▼ ││ ┌───────────────────────────────────────┐ ││ │ Complete Fiori App │ ││ │ • List Report │ ││ │ • Object Page │ ││ │ • Filter, Actions, Navigation │ ││ └───────────────────────────────────────┘ ││ │└─────────────────────────────────────────────────────────────────┘Available Fiori Elements Templates
| Template | Description | Typical Use |
|---|---|---|
| List Report | Table with filters and actions | Master data overviews |
| Object Page | Detail view with facets | Single record editing |
| Analytical List Page | Combination of chart and table | Reporting, dashboards |
| Worklist | Task-oriented list | Approvals, tasks |
| Overview Page | Tile-based dashboard | Management overviews |
| Form Object Page | Form-focused view | Data entry |
Fiori Elements Code Example
CDS Projection View with UI Annotations:
@EndUserText.label: 'Order - Projection'@Metadata.allowExtensions: truedefine root view entity ZC_ORDER provider contract transactional_query as projection on ZI_ORDER{ key OrderId, CustomerId, OrderDate, TotalAmount, Currency, Status,
/* Associations */ _Customer, _Items}Metadata Extension (separate .ddlx file):
@Metadata.layer: #COREannotate view ZC_ORDER with{ /* Header information */ @UI.headerInfo: { typeName: 'Order', typeNamePlural: 'Orders', title: { value: 'OrderId' }, description: { value: '_Customer.CustomerName' } }
/* Facets for Object Page */ @UI.facet: [ { id: 'OrderHeader', purpose: #STANDARD, type: #IDENTIFICATION_REFERENCE, label: 'Order Data', position: 10 }, { id: 'OrderItems', purpose: #STANDARD, type: #LINEITEM_REFERENCE, label: 'Items', position: 20, targetElement: '_Items' } ]
/* Field annotations */ @UI.lineItem: [{ position: 10, importance: #HIGH }] @UI.identification: [{ position: 10 }] @UI.selectionField: [{ position: 10 }] OrderId;
@UI.lineItem: [{ position: 20, importance: #HIGH }] @UI.identification: [{ position: 20 }] @UI.selectionField: [{ position: 20 }] CustomerId;
@UI.lineItem: [{ position: 30 }] @UI.identification: [{ position: 30 }] OrderDate;
@UI.lineItem: [{ position: 40, criticality: 'StatusCriticality' }] @UI.identification: [{ position: 40 }] Status;
@UI.lineItem: [{ position: 50 }] @UI.identification: [{ position: 50 }] @Semantics.amount.currencyCode: 'Currency' TotalAmount;}Result: A complete List Report + Object Page application without a single line of JavaScript!
What Is Freestyle Fiori?
Freestyle Fiori means manual development with the SAPUI5 framework. You have full control over every aspect of the user interface.
How Freestyle Fiori Works
┌─────────────────────────────────────────────────────────────────┐│ Freestyle Fiori │├─────────────────────────────────────────────────────────────────┤│ ││ ┌────────────────┐ ┌────────────────┐ ┌────────────────┐ ││ │ XML Views │ │ Controllers │ │ Models │ ││ │ (Layout) │ │ (JavaScript) │ │ (Data) │ ││ └───────┬────────┘ └───────┬────────┘ └───────┬────────┘ ││ │ │ │ ││ └────────────────────┼────────────────────┘ ││ │ ││ ▼ ││ ┌────────────────────────────────────────────────────────┐ ││ │ Custom Fiori Application │ ││ │ • Custom Components │ ││ │ • Custom Layouts │ ││ │ • Full JavaScript Control │ ││ └────────────────────────────────────────────────────────┘ ││ │└─────────────────────────────────────────────────────────────────┘Freestyle Fiori Code Example
manifest.json (excerpt):
{ "sap.app": { "id": "com.mycompany.orderapp", "type": "application", "title": "Manage Orders", "dataSources": { "mainService": { "uri": "/sap/opu/odata4/sap/zapi_order/srvd_a2x/sap/zui_order/0001/", "type": "OData", "settings": { "odataVersion": "4.0" } } } }}View (XML):
<mvc:View controllerName="com.mycompany.orderapp.controller.OrderList" xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc" xmlns:f="sap.f" xmlns:core="sap.ui.core">
<f:DynamicPage id="orderPage"> <f:title> <f:DynamicPageTitle> <f:heading> <Title text="Orders"/> </f:heading> <f:actions> <Button text="New Order" type="Emphasized" press=".onCreateOrder"/> <Button text="Export" icon="sap-icon://excel-attachment" press=".onExport"/> </f:actions> </f:DynamicPageTitle> </f:title>
<f:header> <f:DynamicPageHeader> <f:content> <FlexBox wrap="Wrap"> <Input id="searchField" placeholder="Search order..." liveChange=".onSearch" width="300px"/> <Select id="statusFilter" change=".onStatusFilterChange" items="{/StatusOptions}"> <core:Item key="{Key}" text="{Text}"/> </Select> <DateRangeSelection id="dateFilter" change=".onDateFilterChange"/> </FlexBox> </f:content> </f:DynamicPageHeader> </f:header>
<f:content> <Table id="orderTable" items="{/Orders}" growing="true" growingThreshold="50" mode="MultiSelect" selectionChange=".onSelectionChange">
<headerToolbar> <OverflowToolbar> <ToolbarSpacer/> <Button text="Delete" icon="sap-icon://delete" enabled="{= ${/SelectedCount} > 0}" press=".onDeleteSelected"/> </OverflowToolbar> </headerToolbar>
<columns> <Column width="10em"> <Text text="Order Number"/> </Column> <Column width="15em"> <Text text="Customer"/> </Column> <Column width="10em"> <Text text="Date"/> </Column> <Column width="8em" hAlign="End"> <Text text="Amount"/> </Column> <Column width="10em"> <Text text="Status"/> </Column> </columns>
<items> <ColumnListItem type="Navigation" press=".onOrderPress"> <cells> <ObjectIdentifier title="{OrderId}" text="{OrderType}"/> <Text text="{CustomerName}"/> <Text text="{ path: 'OrderDate', type: 'sap.ui.model.type.Date', formatOptions: { style: 'medium' } }"/> <ObjectNumber number="{ path: 'TotalAmount', type: 'sap.ui.model.type.Currency', formatOptions: { showMeasure: false } }" unit="{Currency}"/> <ObjectStatus text="{StatusText}" state="{= ${Status} === 'COMPLETE' ? 'Success' : ${Status} === 'CANCELED' ? 'Error' : 'Warning' }"/> </cells> </ColumnListItem> </items> </Table> </f:content> </f:DynamicPage></mvc:View>Comparison: Significantly more code, but also significantly more control over every aspect of the UI!
Decision Matrix: When Which Approach?
Fiori Elements Recommended
| Criterion | Rationale |
|---|---|
| Standard CRUD operations | List Report + Object Page perfectly suited |
| Fast development required | Factor 5-10x faster than freestyle |
| SAP standard UX desired | Automatically Fiori Design Guidelines |
| Little UI expertise in team | No JavaScript knowledge needed |
| Long-term maintainability important | SAP updates automatically integrated |
| Transactional apps (RAP) | Perfect integration with RAP |
| Analytical apps with standard charts | Use Analytical List Page |
Freestyle Fiori Recommended
| Criterion | Rationale |
|---|---|
| Highly individual UI | No template boundaries |
| Custom visualizations | Custom charts, diagrams, maps |
| Complex interaction patterns | Drag & drop, wizards, multi-step |
| Third-party libraries needed | Integration of external components |
| Pixel-perfect design required | Full layout control |
| Gaming/gamification elements | Animations, game mechanics |
| Offline-first requirement | Full offline logic implementable |
Decision Tree
Start: New Fiori App Required │ ▼ ┌──────────────────────┐ │ Is the UI requirement │ │ achievable with │ │ templates? │ └─────────┬────────────┘ │ ┌────────┴────────┐ │ │ ▼ ▼ YES NO │ │ ▼ ▼┌───────────────┐ ┌────────────────┐│ Does the app │ │ → FREESTYLE ││ need complex │ │ FIORI ││ custom logic? │ └────────────────┘└──────┬────────┘ │ ┌────┴────┐ │ │ ▼ ▼ YES NO │ │ ▼ ▼┌─────────────────┐ ┌────────────────────┐│ Can the logic │ │ → FIORI ELEMENTS ││ be implemented │ │ (Purely ││ in ABAP (RAP)? │ │ declarative) │└────────┬────────┘ └────────────────────┘ │ ┌────┴────┐ │ │ ▼ ▼ YES NO │ │ ▼ ▼┌──────────────────┐ ┌────────────────────┐│ → FIORI ELEMENTS │ │ → FREESTYLE FIORI ││ with RAP │ │ or Hybrid ││ Backend │ │ │└──────────────────┘ └────────────────────┘Hybrid Approach: Fiori Elements + Custom Extensions
In many cases, a hybrid approach is the best compromise: Fiori Elements as the base with targeted custom extensions.
Extension Options in Fiori Elements
| Extension Type | Description | Effort |
|---|---|---|
| Header Extension | Custom header content | Low |
| Footer Extension | Custom actions in footer | Low |
| Custom Column | Own column with custom renderer | Medium |
| Custom Section | Own section in Object Page | Medium |
| Controller Extension | Override of controller methods | High |
| Building Block | Reusable UI components | High |
Pros and Cons in Detail
Fiori Elements: Advantages
-
Development Speed
- Up to 80% less code
- No JavaScript development
- Standard patterns immediately available
-
Maintainability
- SAP delivers updates automatically
- Accessibility compliance guaranteed
- Performance optimizations included
-
Consistency
- Automatically Fiori Design Guidelines
- Uniform UX across all apps
- Mobile-ready without extra effort
-
Integration with RAP
- Seamless backend connection
- Draft handling out-of-the-box
- Validations and actions automatically available
Fiori Elements: Disadvantages
-
Limited Flexibility
- Only predefined templates
- Custom layouts difficult to implement
- Complex interactions not possible
-
Debugging Challenges
- Framework-generated code hard to debug
- Annotation errors hard to find
- Less direct control
-
Learning Curve with Annotations
- Many annotations to learn
- Documentation sometimes incomplete
- Trial-and-error for complex scenarios
Freestyle Fiori: Advantages
-
Full Control
- Every UI element individually designable
- Complex interactions possible
- Pixel-perfect designs achievable
-
Third-Party Integration
- External libraries integrable (charts, maps, etc.)
- Custom components reusable
- No framework boundaries
-
Debugging
- Own code easier to debug
- Full browser DevTools support
- Clear error sources
Freestyle Fiori: Disadvantages
-
High Development Effort
- 5-10x more code than Fiori Elements
- JavaScript/TypeScript expertise needed
- Longer development times
-
Maintenance Effort
- Updates must be applied manually
- Accessibility must be ensured yourself
- Performance optimization your responsibility
-
Consistency Risk
- UX inconsistencies possible
- Fiori guidelines must be followed manually
- Team coordination more important
Code Comparison: Same Functionality
Requirement: Order List with Filter and Navigation
Fiori Elements (approx. 50 lines of annotations):
@Metadata.layer: #COREannotate view ZC_ORDER with{ @UI.headerInfo: { typeName: 'Order', typeNamePlural: 'Orders', title: { value: 'OrderId' } }
@UI.lineItem: [{ position: 10 }] @UI.selectionField: [{ position: 10 }] OrderId;
@UI.lineItem: [{ position: 20 }] @UI.selectionField: [{ position: 20 }] CustomerId;
@UI.lineItem: [{ position: 30 }] OrderDate;
@UI.lineItem: [{ position: 40, criticality: 'StatusCriticality' }] @UI.selectionField: [{ position: 30 }] Status;}Freestyle Fiori (approx. 250 lines of code):
- manifest.json: 50 lines
- View.xml: 80 lines
- Controller.js: 120 lines
Conclusion: For standard CRUD scenarios, Fiori Elements is significantly more efficient.
Practical Examples: When Which Approach?
Example 1: Master Data Maintenance (→ Fiori Elements)
Requirement: CRUD for customer master data with address and contacts
Why Fiori Elements:
- Standard CRUD with List Report + Object Page
- Child entities (addresses, contacts) as facets
- Validations via RAP
- Draft handling for long forms
Example 2: Dashboard with Custom Charts (→ Freestyle)
Requirement: Management dashboard with interactive visualizations
Why Freestyle:
- Custom D3.js or Highcharts visualizations
- Drag & drop for widget arrangement
- Real-time updates via WebSocket
- Complex filter interactions
Example 3: Approval Workflow (→ Fiori Elements)
Requirement: Approval process for purchase requisitions
Why Fiori Elements:
- Worklist template ideal for task lists
- Actions (approve, reject) easy to define
- Standard navigation between tasks
- Mobile-ready without extra effort
Example 4: Product Configurator (→ Freestyle)
Requirement: Interactive 3D product configurator
Why Freestyle:
- 3D rendering with Three.js
- Complex interactions (rotation, zoom)
- Dynamic price calculation in frontend
- Custom validation logic
Example 5: Hybrid - Order Management with Tracking
Requirement: Standard order management + delivery tracking with map
Solution: Fiori Elements + Custom Extension
- List Report and Object Page as base
- Custom section with map integration
- Controller extension for tracking API
Migration Between Approaches
From Freestyle to Fiori Elements
In some cases, migration from Freestyle to Fiori Elements can make sense:
| Step | Description |
|---|---|
| 1. Analysis | Which features are standard vs. custom? |
| 2. RAP Backend | Convert backend to RAP |
| 3. Annotations | Create UI annotations for standard features |
| 4. Custom Extensions | Implement non-standard features as extensions |
| 5. Migration | Convert step by step, template by template |
From Fiori Elements to Freestyle
Rarely necessary, but possible when requirements grow significantly:
| Step | Description |
|---|---|
| 1. XML Export | Export generated XML views as base |
| 2. Controller | Take over controller logic from extensions |
| 3. Refactoring | Remove framework dependencies |
| 4. Custom Model | Adjust OData connection |
Best Practices
For Fiori Elements
| DO | DON’T |
|---|---|
| Annotations in separate .ddlx file | Too many annotations inline in CDS |
| Use RAP for complex logic | Pack logic in UI extensions |
| Use standard templates | Excessive customizations |
| Metadata Extensions for readability | Write everything in one file |
| Building Blocks for reuse | Implement each extension individually |
For Freestyle Fiori
| DO | DON’T |
|---|---|
| Follow Fiori Design Guidelines | Invent completely custom design |
| Use sap.ui.core Controls | Native HTML without good reason |
| Use routing for navigation | Build own navigation |
| Models for data binding | Direct DOM manipulation |
| Keep controller logic small | Pack everything in one controller |
Conclusion: The Right Approach for Your Project
Choose Fiori Elements when:
- You’re building standard CRUD applications
- You need to be productive quickly
- You have little frontend expertise
- You prioritize long-term maintainability
Choose Freestyle Fiori when:
- You need highly individual UIs
- You integrate custom visualizations or third-party libraries
- You implement complex interaction patterns
- You need full control over every aspect
Choose Hybrid when:
- 80% standard, 20% custom
- Special sections or columns are needed
- You want to combine the advantages of both worlds
In practice: 80-90% of transactional SAP applications can be effectively implemented with Fiori Elements. The hybrid approach covers another 5-8%. Only for truly special requirements is pure Freestyle Fiori the right path.
See also:
- SAP Fiori Elements: Creating UIs Without Code
- RAP Tutorial Part 1: First Fiori App
- RAP Basics: RESTful ABAP Programming
- CDS Annotations in Detail