Coding Stephan

Teams Hacktogether: Blazor

In the previous post I shared my first experience with the teams toolkit. For the Teams Hacktogether, we started our Teams Tab in Blazor. What is Blazor, what flavours are there and what about hosting your app?

What is Blazor

Blazor allows developers to create web apps in C#, so all the code to create the page is C# (combined with html of course). No JavaScript required, apart from the default code in the template to render the loading screen.

Blazor server

The Blazor Teams Tab template gives you a Blazor Server project. This is one of two flavors of Blazor apps.

A Blazor Server project runs at a webserver (ASP.NET Core) where you can fetch remote data, access the database, you name it. The server side generated html is send to the client over WebSockets (if available).

  • Code rendered server side
  • Needs webapplication (ASP.NET Core) to host
  • Remote data is fetched by the server
  • Client only talks to your server, so their IP is not communicated with third party servers.

Blazor WebAssembly

Since most Teams apps are client side applications, I was hoping for a Blazor WebAssembly template. Blazor WebAssembly is also blazor, but instead of fetching all the data and rendering the HTML for each client, server side, these apps will run in the browser. This means you can effectively use the “free” processing power of each browser to render your page and fetch external data.

This also means you’ll have to build an api, if you want your app to access data in your database. But in the case of our Teams app, we only wanted data from already existing api’s like the Graph API and the internal MyApps api.

We would not have to build any api and our app could run totally in the browser or Teams app at the client.

  • Code rendered client side
  • Needs just static file hosting
  • Remote data is fetched by the browser (and will expose the clients IP to those api’s)
  • Access to a database would require building and hosting an api yourself
  • You need a way to exchange tokens from Teams to tokens for the external api.


As said a Blazor server app, needs a ASP.NET core application to run on a webserver. In Azure the go-to way, would be to create a new App Service, as the toolkit does when you click “deploy to cloud”.

Blazor server uses websockets by default to send over user inputs and rendered html, if websockets are unavailable it switches to “long-polling” which drastically reduced app smoothness.

Because of the server-side rendering and keeping the connection open, your server has to have around 273 KB of memory for each concurrent user source. This is something you have to take into account, when planning the deployment of your Teams app.

The App Service provisioned by the Teams Toolkit (in the template I used) it the F1 tier, meaning the Free version. The Free version has a maximum of 5 concurrent websockets available, if enabled (which is not done by the template).

A Blazor WebAssembly project does not need a web application, it only needs static webhosting of the file that are generated at build time. That allows you to host your blazor app on a Storage account, an (external) CDN or Azure Static Webapps.

Just hosting the files is much cheaper then hosting a web application. And scaling is much easier, up-scaling the web applications vs just paying for more bandwidth.

What’s next

I would like to explore how I could migrate our newly created teams tab to Blazor WebAssembly. Doing so would have to following (positive) changes:

  • No more user data on our server, the app is loaded from a static host, it connects to Microsoft API’s right from the browser.
  • It would (possibly) run faster on newer devices, since it would render client side instead of server side.
  • No longer fetching remote data from our server, paying double for bandwidth (getting data and forwarding to client)

Not sure if that is possible, but you should follow along if you want to see the results.

According to Yannick there is someone how might be able to help out.

Series: Teams Hacktogether