Progressive Web Applications – From Zero to Hero (Blazor, ASP.NET Core, Vue.js, Angular Examples)

Posted by: Daniel Jimenez Garcia , on 9/24/2020, in Category ASP.NET Core
Views: 627408
Abstract: Progressive Web Applications (PWA) have become an interesting choice for web developers. Most of the popular frameworks (ASP.NET Core, Blazor, JavaScript) for writing web applications now offer support for PWAs, making life as a developer easier. Is PWA for you? Find out in this detailed tutorial.

Progressive Web Application (PWA) is a name coined in 2015 for describing web applications that take advantage of the latest browser APIs to provide an experience similar to a Native application.

With Google pushing hard for it in Android, other vendors followed suit. By 2017 they were finally supported by iOS, and in 2019, Windows 10 did the same.

This means starting 2019, when you create a web application using well known languages and technologies, you can turn it into a PWA that feels like a native application in either mobile or desktop platforms.

PWA is a great opportunity for web developers, which also comes with its own set of challenges, like dealing with offline behavior. Luckily for us, as we will see through the article, there is plenty of support for PWA in the common web application frameworks you might be already used to.

What is a Progressive Web Application (PWA)?

Defining Progressive Web Applications

Progressive web applications (PWAs) can be described as a set of techniques that take advantage of modern browser APIs and OS support to provide an experience similar to a native application.

While this started as a way for web applications to offer an experience closer to traditional iOS/Android applications, it has expanded onto traditional desktop applications. For example, now Windows 10 provides ample support for PWAs!

Unfortunately, there is no single formalized standard that defines what Progressive Web Applications are, nor which functionality must be implemented by platforms that support them. This means you can read different definitions depending on where you look. See for example:

Of this, I feel like Mozilla MDN is the one that summarizes it best, even though their page is a draft!

Progressive Web Apps are web apps that use emerging web browser APIs and features along with traditional progressive enhancement strategy to bring a native app-like user experience to cross-platform web applications. Progressive Web Apps are a useful design pattern, though they aren’t a formalized standard. PWA can be thought of as similar to AJAX or other similar patterns that encompass a set of application attributes, including use of specific web technologies and techniques.

We will also go through the minimum technical requirements for a web application to be considered as a PWA. This is important, since otherwise operating systems like iOS, Android or Windows 10 won’t consider it a PWA, and thus won’t allow installing it!

These requirements are:

  • Usage of HTTPS, since they have to be secure.
  • Usage of service workers, which lets them be fast and provide an experience closer to native applications, like push notifications or offline mode.
  • Described through a manifest file, so that at the time of installation, the OS knows about the name, icon and other useful metadata.

Note that these requirements don’t mean apps have to work offline or provide push notifications. It also doesn’t mean you have to implement them using JavaScript SPA frameworks. As long as you use HTTPS, a service worker and a manifest, you have a PWA.

How you implement it and the functionality it offers, is entirely up to you!

Progressive Web Applications

Image Adaptation:

A Progressive Web Application example: Vue.js docs site

Enough with the theory, let’s look at an example using the Vue.js docs site: I am going to use the latest Edge for Windows, but feel free to try it on your Android/iOS phone as well!

When you open a PWA in your browser, the browser will notice and provide an option for installing it. For example – using Edge on Windows 10 (you can also install from Chrome; steps might vary slightly):


Figure 1, install the Vue.js docs as an application in Windows 10 using Edge

You can also use the browser developer tools (Ctrl + Shift + I) to inspect both the manifest and the service worker of the PWA.

If you open the Edge developer tools, go to the Application tab as shown in Figure 2 and 3:


Figure 2, inspecting the manifest.json file of the Vue.js docs site

inspecting-service -worker

Figure 3, inspecting the service worker of the Vue.js docs site

Once you install the PWA, notice it shows up in your start menu in Windows. You can manage it as any other app, pinning it to the start menu, pinning to the taskbar or inspecting its properties.

Interestingly, if you inspect the application properties, you can see how this is a shortcut for a web application that runs on Edge:

C:\Program Files (x86)\Microsoft\Edge\Application\msedge_proxy.exe"  --profile-directory=Default --app-id=ooalagpdddfhdaoiahpgohglonkmabgf

If you launch the application, it feels like a regular Windows 10 application, even though it’s just a web application running inside a sandbox environment:


Figure 4, running the Vue.js docs as a Windows 10 app

Let’s now see if it works offline as promised!

Launch the application from the Windows 10 start menu (or from the installed apps in your iOS/Android phone). Once the app has launched, disconnect from your network. Notice how the application keeps working, thanks to the service worker.

If you want, you can even open the developer tools for the app and inspect the network tab while navigating the docs (You can also try this in your browser to test the offline mode). Notice how the requests are being served from cache by the service worker, while requests such as ads or the Vimeo player, will fail.

inspecting- network-requests-service-worker

Figure 5, the service worker intercepts the network requests and serves them from cache

We can go a bit further and see how the manifest and service worker are actually registered in a web application. If you open the developer tools and navigate to, you can inspect the HTML index document.

Within the <head> element you will see the manifest file being registered:

<link rel="manifest" href="/manifest.json">

At the end of the <body> element you will see the service worker being installed:

'use strict';
'serviceWorker'in navigator&&navigator.serviceWorker.register('service-worker.js').then( // rest of the code omitted

The way these are registered is a perfect example of what the term progressive in PWA means. The manifest is just a link with a special attribute that browsers which don’t provide PWA support, will ignore.

The script that registers the service worker first checks that the browser actually supports the service workers API. This way browsers/platforms that support the latest APIs get all the features, while older browsers ignore them.

If you have never looked at PWAs before, hopefully this sneak peek has been enough to pique your interest. Let’s now see how we can create PWA using different frameworks.

Developing Progressive Web Applications

In order to create a PWA, all you have to do is to add a manifest file and a service worker to your web application, and serve it over HTTPS. It’s no surprise then that many of the frameworks to create web applications, help developers creating these.

This is particularly helpful for the service workers. Armed with the knowledge about the inner workings of each framework, they can better tailor the service worker with suitable default behavior.

You can find the code for each of these examples on GitHub.

Developing PWAs using Blazor WebAssembly

Now that Blazor WebAssembly is officially released, it is a good time to explore how you can take advantage of it and convert it into a PWA.

Why not use server-side Blazor, which has been officially available for a while? Since server-side Blazor relies on a permanent SignalR connection with the server, it’s harder to find the use case of PWA together with the server-side Blazor. However, if you don’t care about the offline functionality and you just like the idea of launching and executing it as a native app, it is technically possible! See this article.

Blazor WebAssembly was officially released with .NET Core 3.1.300 and alongside came a project template for it. Said project template allows you to initialize your Blazor application with PWA support.

If you use the dotnet CLI, you just need to use the –pwa flag as in:

dotnet new blazorwasm --pwa --hosted -o BlazorPWATest

Alternatively, make sure to check the PWA option when creating a new Blazor Web Assembly project using Visual Studio:


Figure 6, creating a new Blazor Web Assembly project with PWA support

In both cases, make sure you use the right version of .NET Core. Also note the selection of the hosted deployment model, which makes it easier to test the PWA functionality.

When the project is generated, you will notice a manifest.json file located inside the Client’s wwwroot folder.

  "name": "BlazorPWATest",
  "short_name": "BlazorPWATest",
  "start_url": "./",
  "display": "standalone",
  "background_color": "#ffffff",
  "theme_color": "#03173d",
  "icons": [
      "src": "icon-512.png",
      "type": "image/png",
      "sizes": "512x512"

There are also two service workers:

– One is used during development and is called service-worker.js. As explained in the comments, reflecting code changes would be harder if we are using a real service worker during development.

– The other one is called service-worker.published.js and contains the real service worker used when published. It is the service worker that provides the caching of static resources and offline support.



Figure 7, inspecting the service worker added by the Blazor WebAssembly template

The offline support that the template provides is described in great detail in the official documentation. To summarize the main points:

  • The service worker applies a cache first strategy. If an item is found in the cache, it is returned from it, otherwise it will try to make the request through the network.
  • The service worker caches the assets listed in a file named service-worker-assets.js which is generated during build time. This file lists all the WASM modules and static assets such as JS/CSS/JSON/image files part of your Blazor application, including the ones added via NuGet packages.
  • The published list of assets is also critical for ensuring the new content is refreshed. Each of the items in the list includes its contents hash and the service worker will work through the latest version of the list every time the application starts.
  • Non-AJAX HTTP GET requests for HTML documents other than index.html are intercepted and interpreted as a request to index.html. What this tries to do is intercept full requests for pages of the Blazor SPA (Single Page Application), so the browser loads the index.html alongside the JS/WASM that initialize the Blazor application which then renders the required page.

It’s also worth highlighting that the offline working logic is under control of the developer. You can either modify the provided service worker file, and/or use the ServiceWorkerAssetsManifestItem MSBuild elements. (See the official documentation for more info)

Let’s see it working in action. After generating your Blazor project, publish it to a folder as in:

dotnet publish -c Release

This will publish both client and server projects (remember we choose the hosted model when initializing the project) to corresponding subfolders. The server should be published to a folder like Server/bin/Release/netcoreapp3.1/publish. If you navigate to that folder, you can then start the published server by running the command dotnet BlazorPWATest.Server.dll:


Figure 8, running the published Blazor application

Now open the address in the browser and install it as an app:


Figure 9, Installing the Blazor PWA

In the terminal where you were running the published server, stop the server. Notice how you can still launch the installed application! If you open the developer tools, you can see how the required files are being loaded from the service worker cache:

testing-blazor -pwa-offline-mode

Figure 10, testing the offline capabilities of the installed Blazor PWA

If you run into trouble, feel free to check the sample project on GitHub.

This concludes the brief overview of the PWA support available out of the box for Blazor WebAssembly projects. For more information, you can check this excellent article from Jon Galloway and the official Blazor documentation.

Developing PWAs using ASP.NET Core

When writing traditional ASP.NET Core applications, there is no Microsoft provided PWA support. Creating a manifest is just about providing some metadata, but a useful service worker is a different matter altogether. You could attempt to create your own, but the caching policy for offline mode can be surprisingly tricky to get right.

After all, caching is one of the hard problems!

Luckily for everyone, there are community driven NuGet packages to help you turn your ASP.NET Core application into a PWA. Let’s take a look at WebEssentials.AspNetCore.PWA by Mads Kristensen.

Note the package hasn’t been fully updated to ASP.NET Core 3.1 at the time of writing. While I had no trouble getting it to work on a brand new MVC project, your mileage might vary (I’ve noticed issues in brand new Razor pages projects). See the status of this GitHub issue for updates.

Start by creating a new ASP.NET Core MVC application using:

dotnet new mvc -o ASPCorePWATest

Then install the NuGet package with:

dotnet add package WebEssentials.AspNetCore.PWA

A minor inconvenience is that you need to write the manifest, and add any icons it references! You can easily write a manifest yourself, either from that NuGet package instructions, taking inspiration from the earlier Blazor example or just googling online. For example:

  "name": "ASPCorePWATest",
  "short_name": "ASPCorePWATest",
  "start_url": "./",
  "display": "standalone",
  "background_color": "#ffffff",
  "theme_color": "#03173d",
  "icons": [
      "src": "icon-192.png",
      "type": "image/png",
      "sizes": "192x192"
      "src": "icon-512.png",
      "type": "image/png",
      "sizes": "512x512"


Note that you will also need to provide the icons referenced in the manifest, and that at the very least, you should provide both a 192×192 and a 512×512 version of the icon. The easiest way is to generate your own icons using websites such as (Which will also provide a code snippet to be added in your manifest file).

The last thing you need to do is to register the package by adding the following line inside the ConfigureServices method of the Startup class.

public void ConfigureServices(IServiceCollection services)

Now that everything is wired, launch the application with the familiar dotnet run command (Or use Visual Studio, whatever you prefer).

You will see the now familiar interface to install it as an application (see Figure 11). You can also see in the browser developer tools that the manifest and the service worker have been correctly recognized.


Figure 11, adding PWA support to a traditional ASP.NET Core MVC application

If you run into trouble, feel free to check the sample project on GitHub.

If you use dotnet run, and have tried the earlier Blazor example, it is possible that all the Blazor files are still cached by the browser. If you still see the previous Blazor site when you open the ASP.NET Core MVC site, clear the browser cache or force reload (On PC: Ctrl+F5 and CMD + R on Mac).

Feel free to take a look at the library documentation on GitHub. Beyond the library installation and basic setup, it details the options provided to customize behavior such as the service working and/or the strategy for caching assets.


Developing PWAs using SPA JavaScript frameworks

By now it should be clear that in order to create a PWA, you do not need to use a SPA framework. All you need is HTTPS, a manifest file and a service worker.

However, in order to provide a native-like user experience, many developers will choose one of the main SPA JavaScript frameworks.

I wrote on how to develop SPA applications using these frameworks and ASP.NET Core recently (See Developing SPAs with ASP.NET Core v3.0). Let’s now take a quick look at how each of these frameworks lets you add PWA support to your application.

Don’t be surprised if it starts getting a bit repetitive. After all, in order to provide basic PWA functionality, you really just need to add the manifest and service worker!

If you run into trouble, feel free to check the sample projects on GitHub.

Adding PWA support to a SPA created using the Angular CLI

When you create an ASP.NET Core application using the template provided by Microsoft, the ClientApp folder contains nothing but a regular Angular CLI application. This means you can use the Angular CLI in order to enable additional Angular features such as PWA support.

Begin by creating a new Angular SPA project as in:

dotnet new angular -o AngularPWATest

Once initialized, make sure to build the project using dotnet build, or at the very least, install the NPM dependencies inside the ClientApp folder

cd ClientApp && npm install

You will also need the Angular CLI installed. If you haven’t installed it yet, follow the official instructions. It comes down to:

npm install -g @angular/cli  

At this point, you should have your Angular project ready and all the necessary tooling installed.

Now for the interesting part!

In order to add PWA support, all you need to do now is to run a single command using the Angular CLI:

ng add @angular/pwa

That’s it! Now run your project using dotnet run and verify that in fact you have a PWA that can be installed.


Figure 12, adding PWA support to an Angular SPA application

I won’t go into more detail as part of this article. If you want to know more, check out this article on how to get started with PWA in Angular, and also read through the excellent official documentation on service worker support.

Adding PWA support to a SPA created using create-react-app

Let’s switch our attention to React and the Microsoft provided React templates.

As discussed in my previous article, these templates have a standard create-react-app inside the ClientApp folder. This means we can take advantage of the existing PWA support already provided by create-react-app.

In fact, the React application initialized by the React template already has the required PWA support!

Start by creating a new application using the React template:

dotnet new react -o ReactPWATest

Take a moment to inspect the contents of your ClientApp folder. Notice how there is a manifest file inside ClientApp/public/manifest.json. There is also a script prepared to install a service worker, the ClientApp/src/registerServiceWorker.js file.

You will need to make a few small fixes to the provided manifest. If you inspect the manifest in Chrome, you will notice it complains about the icon and start URL. For the purposes of this article, you can copy both the manifest and icon from the Blazor example. If you want to fix by hand, make sure you set "start_url": "./", and provide at least a 512×512 icon.

  "short_name": "ReactPWATest",
  "name": "ReactPWATest",
  "icons": [
      "src": "icon-512.png",
      "type": "image/png",
      "sizes": "512x512"
  "start_url": "./",
  "display": "standalone",
  "theme_color": "#000000",
  "background_color": "#ffffff"

Unlike the service worker generated with Angular template, the one generated with the React template won’t be registered during development. It is only registered during Release builds. This is due to the following guard located inside the registerServiceWorker.js file:

export default function register () {
  if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {

So, in order to see the PWA support in action, we just need to run it in production mode. Publish the project to a folder using the command:

dotnet publish -c Release

Then navigate to the published folder and run the published version:

cd .\bin\Release\netcoreapp3.1\publish\
dotnet ReactPWATest.dll

Now when you open the site in the browser, you will notice the browser recognizes the manifest, that a service worker is registered, and that you have the familiar option to install it.


Figure 13, adding PWA support to a React SPA

As you can see, PWA support is pretty much built-in into the React template. Take a look at the create-react-app documentation for more information.

Adding PWA support to a SPA created using the Vue CLI

Other SPA frameworks like Vue also provide good PWA support. In the case of Vue, the Vue CLI provides a plugin that enables the PWA support in the application.

Let’s create a new project using the React template and convert it into a Vue application as described in my previous article. You can add the PWA plugin while initializing the Vue application by manually selecting the features:


Figure 14, selecting the PWA feature when initializing a Vue CLI application

Otherwise, you can also install it later by running the following command inside the ClientApp folder:

vue add pwa

Note that the PWA support works similar to the one provided by create-react-app. The service worker is only registered during Release builds.

Remember there are a few settings to adapt from the React template in order to get Release builds working with a Vue CLI app. See productions builds for Vue in my previous article.

You can build the application for release and run it using the same commands as in the React SPA example before. Once you load the production site in the browser, notice the manifest and service worker are recognized, and the browser offers the option to install the application.


Figure 15, adding PWA support to a Vue SPA application

For more information, check the official plugin documentation.

Developing PWAs using static site generators

A very interesting use case for PWA are that of static sites such as documentation, portfolios or personal blogs.

Over the last few years, frameworks such as Jekyll, Vuepress and Gatsby.js have become a popular choice for building these type of applications. They take care of most of the heavy lifting needed to create a web application letting the developer concentrate on the content of the site.

It’s no surprise then that enabling PWA support is an out of the box feature that developers can simply enable. Let’s take a look at a quick example using Vuepress, by creating a documentation site for a library or a project you have created.

Let’s quickly setup a vuepress project by running the following commands in a terminal:

mkdir vuepress-pwa
cd vuepress-pwa
npm init
npm install -D vuepress

Edit the generated package.json file and replace the scripts property. You will replace it with the scripts needed so you can run the site in development mode and generate the production build:

"scripts": {
  "dev": "vuepress dev docs",
  "build": "vuepress build docs"

That way, you will be able to run the command npm run dev to start the development server, and npm run build to generate the production package.

Let’s add some contents to the site.

Create a new folder named docs, and inside create a new file named This will serve as the home page of your documentation site:

home: true
heroText: My awesome project
tagline: Sample docs site showcasing vuepress and PWA
actionText: Getting Started
actionLink: /getting-started/

This is _actually_ markdown
You can include any markdown contents, like a code block:
# start development server
npm run dev
# generate production build
npm run build
Links across files work as expected. For example [getting started](/getting-started) 

Note how vuepress (and similar static site generators) has great out of the box support for markdown, which will be converted into static HTML and CSS at build time. This makes them a great fit for blogs and documentation.

Inside docs, create a new getting-started folder, containing another file:

# Getting started
This normally contains the easiest way to get started with your library.

Finally, add a subfolder named .vuepress inside the docs folder. Inside, place a new config.js file. This is where you can configure the vuepress settings, which we will use to define the navigation. Add these contents to the .vuepress/config.js file:

module.exports = {
  title: 'My awesome project',
  description: 'Documentation for my awesome project',
  themeConfig: {
    nav: [
      { text: 'Home', link: '/' },
      { text: 'Getting Started', link: '/getting-started/' },

After all these steps, you should now have a minimal documentation site built using Vuepress. Run the npm run dev command and navigate to the shown address in the browser (Normally http://localhost:8080). You will see something like this:


Figure 16, a sample documentation site built using vuepress

If you run into trouble, feel free to check the sample project in GitHub.

Let’s now see how we can add PWA support using the official PWA plugin. Install it by running the command:

npm install -D @vuepress/plugin-pwa

And configure it by adding this line inside the default export of docs/.vuepress/config.js:

module.exports = {
  // previous contents omitted
  head: [
    ['link', { rel: 'manifest', href: '/manifest.json' }],
  plugins: ['@vuepress/pwa'],

You will then add the manifest and icon files inside a new public folder, added to the existing .vuepress folder, as in docs/.vuepress/public/manifest.json. You could again lift the ones from the initial Blazor example or create your own.

That’s the minimum configuration needed to make your Vuepress documentation site PWA compliant. Now you just need to deploy it using HTTPS.

A simple and nice alternative for public documentation sites is to use GitHub pages, but there are other options as per the official docs.


Figure 17, testing PWA support after deploying to github pages

Remember the tour of the Vue documentation site at the beginning of this article? That is a perfect real-life example of a Vuepress application with PWA enabled!

This barely scratches the surface of what can be done with a framework such as Vuepress. If you are interested, check out the official docs and the awesome-vuepress site. Gatsby.js is also a popular alternative for those who prefer React, and is designed with a broader scope than static sites.

PWA – Testing and Tooling

If you plan on developing PWA, there are a few tools worth having in your toolbox. If you have built web applications focused on mobile devices and/or native applications, you might have come across these. Let’s have a brief look at them.


Google Chrome (and other Chromium based browsers such as the new Edge) provides an excellent auditing tool, Lighthouse.

What Lighthouse does is to audit your site on various categories, including PWA support. It then generates a report with a score, findings and recommended fixes/improvements.

When it comes to PWA, you should make sure to audit your production builds. As we have seen through the article, in many cases the service worker is not enabled during development, or a dummy version of it might be used instead.

Let’s try it for example with the Blazor project.

Make sure to publish it for Release and run the resulting site (You can check the earlier section about Blazor). Once up and running, navigate to the site with your browser and open the developer tools. Go to the Lighthouse tab:



Figure 18, launching a Lighthouse audit

Make sure you select the Progressive Web App category on the right, and mobile as the device type. Then click the Generate report button.


Figure 19, Lighthouse PWA report

Lighthouse is a great tool to improve your web applications, not just for PWA purposes. Make sure to check it out!

Android/iPhone simulators

Whenever the focus of a PWA is mobile devices, testing them on a simulator can be of great help during development and/or debugging.

Be aware that the iPhone simulator does not support WebAssembly, so the Blazor WebAssembly example would not work.

For example, let’s test how our Angular example project behaves in the iPhone simulator. Once we have the application running in Release mode on a Mac, we then fire the simulator and navigate to the app:



Figure 20, testing the Angular example in the iPhone simulator

You can then try to install the application, which will add it to the list of applications:



Figure 21, installing the Angular example in the iPhone simulator

As in the case of Lighthouse, when testing the PWA functionality, you will want to test the published version of your application. That’s not to say the simulator cannot be useful during development to test how your app behaves on a phone.


While simulators can be really handy, testing on a real device is much better. ngrok is a tool that lets you expose a site running in your laptop securely over Internet.

This means you can get your site running on localhost exposed with an HTTPS URL that you can then test on a real device. In certain situations, this can be a life saver!

Remember that one of the main requirements for PWA is the usage of HTTPS. Using ngrok is a great way to get an HTTPS tunnel to your localhost site that can be trusted by real devices and/or simulators.

You can sign in and create a free account, and follow the instructions to download and setup ngrok on your machine. Once installed and configured, let’s see what we can do.

Start the published version of the Blazor example on your local machine, which by default will be running at http://localhost:5001. Then run the following ngrok command:

# windows
ngrok.exe http https://localhost:5001
# mac/unix
ngrok http https://localhost:5001

This will create a tunnel and expose your localhost site over internet:


Figure 22, exposing a site running in localhost over Internet with ngrok

You can then open the site on any device: your laptop, a simulator, or a real phone. As long as the device has access to Internet, it will be able to reach the established tunnel!

For example, Figure 23 and 24 shows the Blazor application on my phone:



installing-blazor-example-real phone-ngrok

Figure 24, installing the Blazor example on a real phone with ngrok

I have found ngrok a brilliant tool to be aware of. For more information, check their official documentation.

Limitations and gotchas of PWAs

As with every other technique, PWAs works better in certain contexts than the others. It is good to be aware of certain limitations and gotchas inherent to PWA, independently of the framework you use to build them.

I will briefly go through some of the most important ones, but if you are seriously considering them, it will be worth to spend some time doing your own research expanding on these topics.

They are not native applications

This might seem obvious, but after all, PWA are not native applications. While they offer a similar experience, this might not be close enough for your use case or it might have too many drawbacks. For example:

  • PWA are not distributed through app stores. You lose certain benefits that you normally get from simply being in the app stores – like discoverability, in-app purchases or insights.
  • You don’t have access to the same functionality that native applications do. You can only use whatever functionality is available in the latest browser APIs and while that is plenty, there are examples like custom URL schemes or access to elements of the hardware, that you won’t have.
  • Performance and battery consumption differ when compared to native applications.
  • Android, iOS and Windows offer different support levels for PWA, with Google and Android being a particular champion for them.

Offline mode requires careful consideration

Being able to add offline support via service workers is great, and works extremely well in the case of static sites such as blogs or documentation.

But what about more interactive sites?

One simple approach could be that your site becomes read-only until the user is back online. If your site is mostly static data, or interactions need to happen in a timely manner, this might be a decent approach that saves you a lot of effort.

A harder alternative is considering the usage of a local storage such as IndexedDB to store the data while offline and sync with the server once the user is back online. This opens a whole new set of problems and user flows that you need to consider.

  • What if there is a data conflict once the data is sent to the server?
  • How about data that does not make sense after certain time elapses?
  • Is your system designed to correctly interpret a sudden rush of changes from the same user? For example, how would that data be merged alongside a data stream window that you have already processed?

Of course, you can consider a mix and match approach, and allow certain changes to happen offline while others become unavailable. In any case, offline work does not happen for free and needs to be carefully considered.

Caching is hard

As seen during the article, pretty much every major web application framework provides some form of PWA support that lets you add a service worker.

This is great!

You then have a service worker that caches your HTML/JS/CSS files so your application can start and function while offline.

Let’s leave the caching of data aside, which we briefly discussed over the previous point. Consider only the caching of HTML/JS/CSS files. Now you need to be careful with invalidating that cache and updating those files!

That is likely going to need a server that can tell you what the latest versions are, and some process that requests the latest versions and reconciles with what you have installed (as we briefly saw Blazor doing).

Combined with offline mode, you might need to assume that there can be multiple versions of your application in the wild. This is significantly more challenging than a traditional web application where you can easily ensure that everyone uses the latest version of your website!

Development experience

Developing a PWA can be more challenging than developing a web application. While testing with device simulators or real devices is a good practice even when developing web applications, a PWA introduces further challenges.

In addition, the need for HTTPS and the fact that many frameworks don’t even enable the service worker during development, introduces additional friction in the development experience.


Progressive Web Applications (PWA) have become a very interesting choice for web developers. You can leverage most of the same skills and tools you are used to, in order to provide a native-like experience across desktop and mobile.

That is not to say every web application should become a PWA!

Certain applications will benefit more from the capabilities offered by PWAs than others. There will be teams who might not find it worth dealing with the extra challenges they bring, so they might not want to convert their application into a PWA. Or they realize a PWA doesn’t yet provide the functionality or experience they need and will prefer to stick with native applications.

However, for those who adopt them, there is no shortage of tooling and support.

Most of the popular frameworks for writing web applications now offer support for PWAs, making their life as a developer easier. They might even partially embrace them, for example making your PWA installable while still requiring an online connection.

Like many other things in technology, the only right answer is It depends.

This article was technically reviewed by Damir Arh.

Download the source code of this article on GitHub

This article has been editorially reviewed by Suprotim Agarwal.

Absolutely Awesome Book on C# and .NET

C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.

We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).

Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.

Click here to Explore the Table of Contents or Download Sample Chapters!

What Others Are Reading!
Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+

Daniel Jimenez Garciais a passionate software developer with 10+ years of experience who likes to share his knowledge and has been publishing articles since 2016. He started his career as a Microsoft developer focused mainly on .NET, C# and SQL Server. In the latter half of his career he worked on a broader set of technologies and platforms with a special interest for .NET Core, Node.js, Vue, Python, Docker and Kubernetes. You can check out his repos.

Page copy protected against web site content infringement 	by Copyscape

Feedback - Leave us some adulation, criticism and everything in between!