UI5 Web Components, like all modern JavaScript code, are shipped as ES6 modules published on NPM. This does not make it easy for newcomers, as this setup requires build tooling and some upfront knowledge. It is not as easy as opening a text editor and seeing the results from the documentation.

In this post, I will walk you step by step through what I consider the easiest way to get started with UI5 Web Components. The best part is, this setup is fully suitable for productive usage. All the steps required for learning and trying things out are directly contributing to a final production-ready solution.

Note: in The Fastest Way to Get Started with UI5 Web Components, I described a similar solution which was lacking a production build step.

Not everyone needs an application framework

It is quite common these days to create static pages sprinkled with some JavaScript for interactivity, or even simple applications that do not require lots of third-party code to make them work, just the Fiori look and feel with UI5 Web Components. In case you are not using React, Vue, or similar frameworks that enable ES6 module builds, you still need a project setup to consume ES6 modules from NPM.

Enter Vite – a Next Generation Frontend Tooling. Vite solves many problems elegantly, but the two biggest reasons to use it as a starting point are:

  • it has a great scaffolding tool – just use one command line tool with an interactive UI to get a project started
  • it has an insanely fast development workflow – the dev server starts in well under 1 second and code changes are more or less instantly visible in the browser

Creating the project

To create the project structure, run the following command (you need to have nodejs installed for this)

$ npm init @vitejs/app

Next, follow the steps from the wizard:

    • Select a project name: my-webcomponents-app
    • Select a framework: vanilla
    • Select a variant: JavaScript

You will see the similar output, make sure to run the commands:

Done. Now run:
cd my-webcomponents-app
npm install
npm run dev​

That was all – with just one command (and following the instructions), we were able to get a fully running project in the browser.

  vite v2.3.4 dev server running at:

  > Local: http://localhost:3000/
  > Network: use `--host` to expose

  ready in 212ms.

It doesn’t get easier than that.

Adding UI5 Web Components

Consuming UI5 Web Components from NPM means that you need to add them to your project as a dependency. Go ahead and add @ui5/webcomponents as a project dependency

$ npm install @ui5/webcomponents --save

This command downloads the published source code of UI5 web components to the node_modules folder. Now we need to use them in our code to get them on the page. Thanks to Vite, we can simply write the imports and let Vite figure out what is necessary.

Open src/main.js and add an import for the ui5-button web component:

import "@ui5/webcomponents/dist/Button.js"

This line runs the code that registers the <ui5-button> tag with the browser. Now when the browser sees such a tag, it knows how to render it.

Next, change the application markup in the same file to display the button:

document.querySelector('#app').innerHTML = `
  <ui5-button>Hello UI5 Web Components</ui5-button>

And if you navigate to the browser, you should already see a button with the Fiori 3 styling and behaviour (no restart of the dev server was necessary which is quite nice).

Herein lies the second great feature of Vite’s development workflow – unlike earlier build tools that used to generate the same bundle file for production and development (minus the code minification), Vite is taking advantage of the fact that browsers can consume ES6 modules natively. The only step needed is a module path rewrite (which is just a string replace and very fast), as browsers need to know how to get from:

import "@ui5/webcomponents/dist/Button.js"

to the corresponding node_modules path

import "/node_modules/.vite/@ui5_webcomponents_dist_Button_js.js?v=80b35f38

This is what Vite is doing – it starts a web server (that serves both the app, as well as the `node_modules` folder), rewrites bare module specifiers (like @ui5/webcomponents) to the corresponding relative path (like /node_modules/...) and lets the browser take care of the module imports. This is called bundleless development and is how Vite can be both so easy to setup and insanely fast – a great combination in my book.

Go ahead, check the network trace in your browser to see the individual files consumed directly as ES6 modules without bundling.

But single requests will hurt page performance for my users

True, even with HTTP/2 and newer, the browser still incurs some overhead for processing too many individual files and a bundle is always faster. For development, it is acceptable to serve single files as page refreshes upon changes are almost instant (compared with a bundle that takes a couple of seconds to build which is enough to distract). For productive usage however, we want to serve a bundle for the best possible user experience.

Luckily, Vite takes care of that. It uses rollup under the hood which has a very powerful configuration and a rich feature set. Vite provides very good defaults out of the box, so the only thing you need to do after stopping the development server is to type:

$ npm run build
vite v2.3.4 building for production...
✓ 99 modules transformed.
dist/assets/favicon.17e50649.svg 1.49kb
dist/index.html 0.51kb
dist/assets/index.ccce2ca3.css 0.16kb / brotli: 0.10kb
dist/assets/index.4116dceb.js 0.12kb / brotli: 0.09kb
dist/assets/vendor.c05c7785.js 114.92kb / brotli: 24.30kb

You can see very nice file size reporting and hashes appended to the filenames out of the box. This enables aggressive caching on the server, as an application change will result in different file names.

The dist folder is now ready to be deployed with your project – be it static site hosting, or a nodejs application with server side templating, or anything else for that matter.

Why no CDN?

We get that question a lot – why don’t you host a bundle with the web components somewhere, so I can just embed a script in my page.

There are a few big issues with this (all apparent from the build output above which is quite optimal):

  • bundle size
  • versioning and caching
  • assets locations

1. A bundle with all web components is easily above 200kb, and no application ever needs all web components (close to 60 at the time of writing). Having a specialised bundle per application is so much better for performance.

2. When Vite creates new hashes for the bundles due to changes, it automatically adjusts the imports in the .html files so there is no manual work on the consumption side when updates are made.

3. UI5 Web Components come with a lot of assets (like theme data, i18n texts and more) which ultimately are different from JavaScript and a URL needs to be known for them at runtime. A build tool helps with this mapping instead of requiring too much runtime configuration.


Ultimately, the CDN question boils down to ease of consumption. With Vite, the consumption hurdle is as low as with CDN, with the added benefit of much improved development experience and great production-ready performance. Browser standards like ES6 modules and frontend tooling have come a long way to enable both great development experience as well as productive build qualities with the same setup.

How to take it further from here? Start adding more components to the project, or create a new project and choose different options from the wizard. The end result will always be a best-practice project setup, even if it starts out only for a quick sample.

Don’t forget to check out the other available web components in the playground. Also give the project a star on github if you’d like to show your appreciation for our work so far. Feel free to open an issue on github for any problems, suggestions or improvements you might want to see.

Tags: SAPUI5
Randa Khaled

Randa Khaled

Author Since: November 19, 2020

0 0 votes
Article Rating
Notify of
Inline Feedbacks
View all comments
Would love your thoughts, please comment.x