abap2UI5
Version 1.144.1

Build UI5 Apps Purely in ABAP

One ABAP class is one UI5 app — no JavaScript, no OData, no frontend project. Install with abapGit, and it runs on anything from NetWeaver 7.02 to ABAP Cloud.

abap2UI5 Logo

Ready for your enterprise ​

abap2UI5 runs inside the security you already have. One HTTP endpoint, standard SAP logon, your own authorizations — and an app is an ABAP class, so transports, ATC and ABAP Unit apply as they do to everything else you ship.

→ More on Enterprise Readiness

Plays well with what you have ​

abap2UI5 complements your UI5 and RAP apps — it does not replace them, and lives right next to your existing solutions. It runs in a browser tab, a Fiori launchpad tile or SAP Build Work Zone.

→ More on Integration

Made for AI agents ​

An app is one ABAP class, so an agent writes the whole thing — UI and logic — in one go, and a working app or a new screen is a matter of minutes. The abap2UI5 linter and the MCP server let the agent double-check its own work before a developer looks at it.

→ More on Developing with AI

And what does it cost? ​

Nothing. MIT licensed, commercial use included — no license key, no subscription, no per-user fee, and no BTP required. It runs on your ABAP stack with the UI5 version already installed, and the license you have is the one you keep.

→ More on Cost Calculator

Try it out now ​

abap
CLASS zcl_app_invoices DEFINITION PUBLIC.
  PUBLIC SECTION.
    INTERFACES z2ui5_if_app.

    TYPES:
      BEGIN OF ty_s_invoice,
        product       TYPE string,
        delivery_date TYPE string,
      END OF ty_s_invoice.

    DATA t_invoices TYPE STANDARD TABLE OF ty_s_invoice WITH EMPTY KEY.
    DATA s_edit     TYPE ty_s_invoice.

  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.

CLASS zcl_app_invoices IMPLEMENTATION.
  METHOD z2ui5_if_app~main.

    IF client->check_on_navigated( ).

      t_invoices = VALUE #(
          ( product = `Pineapple`    delivery_date = `2026-07-15` )
          ( product = `Milk`         delivery_date = `2026-07-20` )
          ( product = `Canned Beans` delivery_date = `2026-08-01` )
          ( product = `Salad`        delivery_date = `2026-08-10` )
          ( product = `Bread`        delivery_date = `2026-08-12` ) ).

      DATA(view) = z2ui5_cl_ui5_view_builder=>factory(
          )->ele( n = `View` ns = `mvc`
              )->a( n = `xmlns`     v = `sap.m`
              )->a( n = `xmlns:mvc` v = `sap.ui.core.mvc` ).

      DATA(tab) = view->ele( `Shell`
          )->ele( `Page`
              )->a( n = `title` v = `Invoices`

              )->ele( `Table`
                  )->a( n = `headerText` v = `Invoices`
                  )->a( n = `items`      v = client->_bind( t_invoices ) ).

      tab->ele( `columns`

          )->ele( `Column`
              )->tag( `Text`
                  )->a( n = `text` v = `Product`

          )->end(
          )->ele( `Column`
              )->tag( `Text`
                  )->a( n = `text` v = `Delivery Date`

          )->end(
          )->ele( `Column`
              )->a( n = `width` v = `10%` ).

      tab->ele( `items`
          )->ele( `ColumnListItem`
              )->ele( `cells`

                  )->tag( `Text`
                      )->a( n = `text` v = `{PRODUCT}`
                  )->tag( `Text`
                      )->a( n = `text` v = `{DELIVERY_DATE}`
                  )->tag( `Button`
                      )->a( n = `icon`    v = `sap-icon://edit`
                      )->a( n = `tooltip` v = `Edit delivery date`
                      )->a( n = `press`   v = client->_event( val = `EDIT` arg = `${PRODUCT}` ) ).

      client->view_display( view->stringify( ) ).

    ELSEIF client->check_on_event( `EDIT` ).

      s_edit = VALUE #( t_invoices[ product = client->get_event_arg( ) ] OPTIONAL ).

      DATA(popup) = z2ui5_cl_ui5_view_builder=>factory(
          )->ele( n = `FragmentDefinition` ns = `core`
              )->a( n = `xmlns`      v = `sap.m`
              )->a( n = `xmlns:core` v = `sap.ui.core`

              )->ele( `Dialog`
                  )->a( n = `title` v = |Edit { s_edit-product }|

                  )->ele( `content`

                      )->tag( `Label`
                          )->a( n = `text` v = `Delivery Date`
                      )->tag( `DatePicker`
                          )->a( n = `value`       v = client->_bind( s_edit-delivery_date )
                          )->a( n = `valueFormat` v = `yyyy-MM-dd`

                  )->end(

                  )->ele( `buttons`

                      )->tag( `Button`
                          )->a( n = `text`  v = `Cancel`
                          )->a( n = `press` v = client->_event( `CANCEL` )
                      )->tag( `Button`
                          )->a( n = `text`  v = `Save`
                          )->a( n = `press` v = client->_event( `SAVE` )
                          )->a( n = `type`  v = `Emphasized` ).

      client->popup_display( popup->stringify( ) ).

    ELSEIF client->check_on_event( `SAVE` ).

      t_invoices[ product = s_edit-product ]-delivery_date = s_edit-delivery_date.
      client->popup_destroy( ).
      client->message_toast_display( |{ s_edit-product } updated.| ).

    ELSEIF client->check_on_event( `CANCEL` ).

      client->popup_destroy( ).

    ENDIF.

  ENDMETHOD.
ENDCLASS.

→ The Tutorial builds this app in twelve steps, through to transport and unit tests.

Build your first app Install with abapGit, run Hello World, then the twelve-step tutorial — through to transport and unit tests. Find a sample for your use case Over 700 working apps, searchable by control, by library and by the UI5 release your system runs. Take an app to production Security, authorizations, the launchpad tile, the transport — what a go-live needs, on one page.
Edit this page on GitHub ↗ Last updated: