Fiori Elements vs. Freestyle Fiori: Which UI Approach Fits Your Project?

Category
UI
Published
Author
Johannes

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

AspectFiori ElementsFreestyle Fiori
Development effortLow (1-2 days)High (1-2 weeks)
UI flexibilityLimited (templates)Unlimited
Maintenance effortMinimalContinuous
Learning curveCDS AnnotationsSAPUI5/JavaScript
UX consistencyAutomatically SAP-compliantMust be ensured manually
UpdatesDelivered by SAPIndependent
DebuggingMore 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

TemplateDescriptionTypical Use
List ReportTable with filters and actionsMaster data overviews
Object PageDetail view with facetsSingle record editing
Analytical List PageCombination of chart and tableReporting, dashboards
WorklistTask-oriented listApprovals, tasks
Overview PageTile-based dashboardManagement overviews
Form Object PageForm-focused viewData entry

Fiori Elements Code Example

CDS Projection View with UI Annotations:

@EndUserText.label: 'Order - Projection'
@Metadata.allowExtensions: true
define 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: #CORE
annotate 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?

CriterionRationale
Standard CRUD operationsList Report + Object Page perfectly suited
Fast development requiredFactor 5-10x faster than freestyle
SAP standard UX desiredAutomatically Fiori Design Guidelines
Little UI expertise in teamNo JavaScript knowledge needed
Long-term maintainability importantSAP updates automatically integrated
Transactional apps (RAP)Perfect integration with RAP
Analytical apps with standard chartsUse Analytical List Page
CriterionRationale
Highly individual UINo template boundaries
Custom visualizationsCustom charts, diagrams, maps
Complex interaction patternsDrag & drop, wizards, multi-step
Third-party libraries neededIntegration of external components
Pixel-perfect design requiredFull layout control
Gaming/gamification elementsAnimations, game mechanics
Offline-first requirementFull 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 TypeDescriptionEffort
Header ExtensionCustom header contentLow
Footer ExtensionCustom actions in footerLow
Custom ColumnOwn column with custom rendererMedium
Custom SectionOwn section in Object PageMedium
Controller ExtensionOverride of controller methodsHigh
Building BlockReusable UI componentsHigh

Pros and Cons in Detail

Fiori Elements: Advantages

  1. Development Speed

    • Up to 80% less code
    • No JavaScript development
    • Standard patterns immediately available
  2. Maintainability

    • SAP delivers updates automatically
    • Accessibility compliance guaranteed
    • Performance optimizations included
  3. Consistency

    • Automatically Fiori Design Guidelines
    • Uniform UX across all apps
    • Mobile-ready without extra effort
  4. Integration with RAP

    • Seamless backend connection
    • Draft handling out-of-the-box
    • Validations and actions automatically available

Fiori Elements: Disadvantages

  1. Limited Flexibility

    • Only predefined templates
    • Custom layouts difficult to implement
    • Complex interactions not possible
  2. Debugging Challenges

    • Framework-generated code hard to debug
    • Annotation errors hard to find
    • Less direct control
  3. Learning Curve with Annotations

    • Many annotations to learn
    • Documentation sometimes incomplete
    • Trial-and-error for complex scenarios

Freestyle Fiori: Advantages

  1. Full Control

    • Every UI element individually designable
    • Complex interactions possible
    • Pixel-perfect designs achievable
  2. Third-Party Integration

    • External libraries integrable (charts, maps, etc.)
    • Custom components reusable
    • No framework boundaries
  3. Debugging

    • Own code easier to debug
    • Full browser DevTools support
    • Clear error sources

Freestyle Fiori: Disadvantages

  1. High Development Effort

    • 5-10x more code than Fiori Elements
    • JavaScript/TypeScript expertise needed
    • Longer development times
  2. Maintenance Effort

    • Updates must be applied manually
    • Accessibility must be ensured yourself
    • Performance optimization your responsibility
  3. 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: #CORE
annotate 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:

StepDescription
1. AnalysisWhich features are standard vs. custom?
2. RAP BackendConvert backend to RAP
3. AnnotationsCreate UI annotations for standard features
4. Custom ExtensionsImplement non-standard features as extensions
5. MigrationConvert step by step, template by template

From Fiori Elements to Freestyle

Rarely necessary, but possible when requirements grow significantly:

StepDescription
1. XML ExportExport generated XML views as base
2. ControllerTake over controller logic from extensions
3. RefactoringRemove framework dependencies
4. Custom ModelAdjust OData connection

Best Practices

For Fiori Elements

DODON’T
Annotations in separate .ddlx fileToo many annotations inline in CDS
Use RAP for complex logicPack logic in UI extensions
Use standard templatesExcessive customizations
Metadata Extensions for readabilityWrite everything in one file
Building Blocks for reuseImplement each extension individually

For Freestyle Fiori

DODON’T
Follow Fiori Design GuidelinesInvent completely custom design
Use sap.ui.core ControlsNative HTML without good reason
Use routing for navigationBuild own navigation
Models for data bindingDirect DOM manipulation
Keep controller logic smallPack 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: