Create nice-looking JSF 2.3 applications with PrimeFaces

Last Updated:  January 23, 2022 | Published: May 1, 2019

With the release of PrimeFaces 7.0 (JSF component library) in March 2019, the PrimeTek team introduced over 500 improvements featuring new components. Furthermore, they added new modern free themes, font icons, better performance various enhancements on accessibility and security. The new modern free themes were the first thing I noticed while browsing through the PrimeFaces component showcase page especially the Nova-Light theme. Besides the premium themes (e.g. Barcelona, Poseidon, Omega …) you'll now get nice-looking themes for your JSF application free.

Update: The application is now running with a more recent PrimeFaces release: PrimeFaces 8.0

To not only show you how this new theme looks like but to demonstrate how easy & fast you can create applications with JSF and PrimeFaces components, I created a small demo application. The application contains a form for entering data, a feature-rich data table, a chart, and some general UI elements like a header and a footer and was made within 2 hours (some troubleshooting with the components included). I won't go into a technical explanation of the source code in this blog post and will rather focus on demonstrating the productivity with JSF and the PrimeFaces components (the source code is available on GitHub).

The following technologies were used: Java 8, Java EE 8, OmniFaces 3.6, PrimeFaces 8.0 running on Payara 5.201.

Getting started with JSF and PrimeFaces

A good place to start is the PrimeFaces showcase page where you get an overview of all available components with sample code snippets to show you how the component looks like and how to use it. You'll both get the required XHTML code alongside the backing bean for the component demo.

For my demo application, I decided to structure the content like the following: header, content, footer. JSF provides a simple way to insert commonly used markup templates and therefore I created a header.xhtml and footer.xhtml file and include it on every page. The header contains a menu bar to navigate through the application and was made with the Menubar component of PrimeFaces. I could pick the showcase Menubar, adjust the menu items and was ready. For the footer, I decided to just show some text on every page.

The main page contains three PrimeFaces Panels to structure the content a little bit. Common charts like BarChart, LineChart, PieChart, etc. are also part of the component library of PrimeFaces. At the latest when integrating charts while using SPA frameworks, you would now need to evaluate a new library. Next, include it to your project, learn its specific API, see how it integrates. On the backend you'll create an interface to provide the data. With JSF you just have to expose the chart's data model object with a backing bean, prepare the data basis with custom Java code (e.g. fetch data from a database via JPA) and you are done:


Data representation with PrimeFaces components

The most common use case for nearly every web application is to visualize data in a table. Furthermore, you usually filter, search and modify it. Achieving this with a JavaScript-based application, you now have to find the next library and put up with the pros and cons of integrating external libraries. With the feature-rich DataTable component from PrimeFaces, I was able to visualize data with the following features: pagination, context menu, column filtering, column sorting, column selection in under 30 minutes.

CRUD (Create, Read, Update, Delete) operations are also quite easy to achieve with this component. Given these components and the way JSF works you don't have to design and implement any RESTinterfaces. You can find a blog post about a CRUD table with JSF, PrimeFaces, and JPA here.

primeFacesJSFTable primeFacesJSFTableOverview

Entering data with JSF and PrimeFaces input elements

Just visualizing data without creating it, is boring. With JSF, no problem!

The Input components from PrimeFaces cover nearly every use case. To show you a selection of them, I decided to use a dropdown input with searching capability. Next, an input with masking (e.g. tax id, card numbers), a slider, a toggle switch, and a date picker. Some of the input fields are backend by server-side data and some are static.

For validating the input you can make use of Bean Validation (@NotNull, @Future, @Size …) within your backing bean and get validation out of the box. Compared to a SPA application, where you have to double-check the data (at the input/before sending and at the interface) this to this is really pleasant.

primeFacesJSFInputViewEnteringData primeFacesJSFInputView

Final thoughts on JSF with PrimeFaces

Don't get me wrong, I don't want to badmouth any SPA framework or JavaScript library. I just want to show you a (maybe forgotten) way to create nice-looking applications. But also make you aware of carefully considering the pros and cons.

If you've not yet tried JSF, I would recommend it. With some basic HTML + CSS knowledge, you can easily create a simple application in minutes. PrimeFaces also gives you a wide variety of ready-to-use components and you can focus on business logic. Writing just Java code (except some HTML) for your whole application is also a nice advantage. You don't have to maintain the frontend in a different language. The integration with other Java EE standards (e.g. CDI, EJB, Security …) is also an advantage. This makes e.g. authorization and authentication for your application easier. Once you are familiar with the concepts of JSF (read this book for an excellent JSF intro & deep-dive), you'll be way more productive and can rely on only one tech stack.

Most of the time I would prefer JSF for a company internal application (no fancy animations/graphics/pixel-perfect UIs required). Similarly, I would at least consider the technology for an application with external users.

Further JSF resources

For more information, just browse through my other blog posts about JSF or subscribe to my newsletter. Here is a list of my JSF posts:

The full codebase for this example is available at GitHub with instructions on how to run it on your machine.

Have fun using JSF with PrimeFaces,


    • Hey Sam,

      did you try to run the code on GitHub or your own project? Try to open the developer console in your browser (F12 if you are using Chrome on Windows) and switch to the network tab to see which theme is loaded. You can also push your code to GitHub and send me the link so that I can have a look at it.

      Have a nice day,

  • Hi Phil,

    i want to create a web app for private purposes and found your example application, but i have no docker installed. Can i manually download payara and execute your application with intellij ultimate? How do i configure the run configuration?

    I’ve tried to add a local glassfish server and chose the payara folder, which containts the extracted files. But im getting the follow error:

    HTTP Status 404 – /nice-looking-jsf-apps-with-prime-faces-7/index.xhtml Not Found in ExternalContext as a Resource

    type Status report

    message/nice-looking-jsf-apps-with-prime-faces-7/index.xhtml Not Found in ExternalContext as a Resource

    descriptionThe requested resource is not available.
    Payara Server 5.193 #badassfish


    • Hi Dennis,

      yes, you can start the application with a local Payara installation and IntelliJ (follow this tutorial for the setup: The application you mentioned contains a payara-web.xml with configured root path /. So in the deployment tab of IntelliJ when you select the .war file, also configure / as context path and once everything is up- and running, visit http://localhost:8080.

      Kind regards,

      • Hi Philip,

        first of all thanks for your fast reply. When changing the context root path to “/test” the welcome page is displayed correctly. But when i am using “/” as the context root path a “welcome to wildfly” page is shown. I have no wildfly running on this port… Do you know any reason for this?

        Kind Regards,

        • Hi Philip,

          i am just dumb, sorry. I had to reset the browser cache, because i had a wildfly running on this port in the past. With your solution to set the custom context root path to “/” everything work fine now. Thanks a lot and sorry for wasting your time.


  • {"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}