ServiceStack's Jamstack templates encapsulates the latest technologies at the forefront of modern web development to deliver both a great developer experience and performant end-user UX.
Jamstack (JavaScript, APIs, and Markup) is a modern architecture pattern to build fast, secure and easy to scale web applications where pre-rendering content, enhancing with JavaScript and leveraging CDN static hosting results in a highly productive, flexible and performant system that takes advantage of CDN edge caches to deliver greater performance & efficiency at lower cost.
Jamstack Benefits​
It's become the preferred architecture for modern performant web apps with benefits extending beyond performance to improved:
- Security from a reduced attack surface from hosting read-only static resources and requiring fewer App Servers
- Scale with non-essential load removed from App Servers to CDN's architecture capable of incredible scale & load capacity
- Maintainability resulting from reduced hosting complexity and the clean decoupling of UI and server logic
- Portability with your static UI assets being easily capable from being deployed and generically hosted from any CDN or web server
- Developer Experience with major JavaScript Frameworks embracing Jamstack in their dev model, libraries & tooling
Ultimately, it's hosting your App's pre-rendered static UI assets on Content Delivery Network (CDN) edge caches close to users locations that's primarily responsible for its lightning performance.
$0.40 /month​
Other by-products of generating pre-computed CDN hostable assets, is interchangeable cost-effective hosting and great SEO - characteristics our Jamstack Demos take advantage of with free UI hosting on GitHub Pages CDN leaving their only cost to host its .NET 6 API back-ends, deployed with SSH in Docker compose containers to a vanilla Digital Ocean droplet costing only $0.40 /month each.
Recommended Templates​
These templates represent the best-in class experiences for their respective React, Vue & Blazor WASM ecosystems each, packed with features & examples common in many websites including Integrated Auth, rich Markdown content as well as TODOs MVC and CRUD examples with built-in contextual validation binding. As such they're now recommended over our existing SPA and C# MVC Templates.
We've put together a quick check list to help decide which templates we'd recommend:
Project | Recommendation |
---|---|
Next.js | If you prefer React |
Vue SSG | If you prefer Vue and SEO is important |
Blazor Tailwind | If you prefer a full C# Stack or are developing Line of Business (LOB) Apps |
Vue SPA | If you prefer Vue and happy to trade SEO benefits of SSG for a simpler template |
Still not sure? familiarize yourself with their respective dev models by comparing their functionality equivalent TODOs MVC Examples:
TODOs MVC​
All projects utilize the same back-end ServiceStack Services with TODOs MVC implemented in TodosServices.cs.
As Bookings CRUD is an AutoQuery CRUD API, it defines all its functionality in its declarative Bookings.cs DTOs and serves as a good example for the minimal dev model effort required to implement a typical Authenticated CRUD UI in each framework:
Bookings CRUD​
Once you know the framework you wish to use, create a new App using your preferred Project Name below:
Download new C# Jamstack Project Template
INFO
An updated list of available Jamstack project templates is also at https://jamstacks.net (built with Razor SSG)
Pre-configured Jamstack App Deployments​
All project templates supports CDN hostable UI assets and include the necessary GitHub Actions that takes care of building and SSH deploying a Docker compose production build of your App to any Linux Host with just a few GitHub Action Secrets in your GitHub repo.
The optional DEPLOY_CDN
secret lets you control whether to deploy your App's static /wwwroot
assets to your GitHub Pages CDN by specifying the custom domain to use and is what all JamStack Live demos used to deploy a copy of their UIs to GitHub Pages CDN:
Project Source | GitHub Pages CDN | Digital Ocean Docker .NET API |
---|---|---|
nextjs | nextjs.jamstacks.net | nextjs-api.jamstacks.net |
vue-ssg | vue-ssg.jamstacks.net | vue-ssg-api.jamstacks.net |
blazor | blazor.web-templates.io | blazor.web-templates.io |
vue-spa | vue-spa.jamstacks.net | vue-spa-api.jamstacks.net |
blazor-wasm | blazor-wasm.web-templates.io | blazor-wasm.web-templates.io |
Blazor WebAssembly​
The Blazor WebAssembly (WASM) template offers a pure end-to-end integrated C# solution to building a high performance web application with Blazor and ServiceStack. Due to the integrated dev model we've been able to achieve in Blazor it's become our preferred technology to use to develop Line of Business Apps since it's the only C# Razor solution adopting our preferred API First Development model with Web UIs reusing the same well-defined APIs as Mobile and Desktop Apps.
Great Perceived Performance and SEO​
Typically the large download sizes & slow initial load times of Blazor WASM Apps would make it a poor choice for Internet hosted sites. However, our Blazor WASM template has largely mitigated this with easily maintainable built-in pre-rendering techniques to make every page appear to load quickly, including instant loading of its Markdown Pages courtesy of the GitHub Actions publish task generating & deploying pre-rendered content pages.
You can see the results of this in its live demo when loading the home page, which only has a slight delay:
blazor-wasm.web-templates.io
Learn more​
To find out more watch its YouTube overview and visit the Blazor WASM docs.
Razor SSG​
The razor-ssg ServiceStack template leverages the power of .NET Razor to provide seamless static site generation (SSG) capabilities. It's perfect for building content-rich applications like product websites, blogs, portfolios, and more.
This template streamlines the development process while offering versatility in customizing and extending your project. With GitHub Codespaces integration, you can develop, test, and manage your application all within your browser, eliminating the need for a dedicated development environment and expediting your workflow.
Next.js​
For those preferring working with React, there's a clear choice in Nextjs.org - currently the flagship & most popular Jamstack framework backed by the folks over at Vercel, where it enjoys deep engineering talent committed to maintaining and continually improving it, so you can be confident in the longevity of the technology and the React framework maintained by Meta (Facebook).
Designed as an SSG framework from the start, its pre-defined patterns include static generation and UX focused functionality built-in.
Stale While Revalidate​
Its SWR Data Fetching React Hooks library is one innovative example utilizing the popular stale-while-revalidate UX pattern to help developers balance between immediacy — loading cached content right away — and freshness — ensuring updates to the cached content are used in the future.
To take advantage of this, the nextjs template includes a swrClient
that provides a typed wrapper for making typed SWR API Requests with ServiceStack's generic JsonServiceClient:
import { swrClient } from "../lib/gateway"
import { Hello } from "../lib/dtos"
const HelloApi = ({ name }) => {
const {data, error} = swrClient.get(() =>
new Hello({ name }))
if (error) return <div>{error.message}</div>
return <div>{data?data.result:'loading...'}</div>
}
This reactively sets up the UI to handle multiple states:
loading
- displays loading... message whilst API request is in transitdata
- when completed, populated with aHelloResponse
and displayederror
- when failed, populated withResponseStatus
and displayed
The primary UX benefits are realized when re-making an existing request in which a locally-cached stale version is immediately returned and displayed whilst a new API Request is made behind the scenes, updating the UI if the fresh response was modified.
Vite​
Despite Vercel's full-time resources, Next.js is still reliant on the Webpack ecosystem, who although have done a formidable job managing complex tooling requirements for npm projects over a number of years, has since lost the Developer Experience (DX) crown to vitejs.dev
Vite is being built for speed in the modern era and takes advantage of modern browser features like native ES modules support to remove bundling entirely during development and adopts performance leading technologies like esbuild to pre-bundle dependencies and transpile TypeScript which is able to do 20-30x faster than TypeScript's own tsc
compiler.
Ultimately its architectural choices allows Vite to deliver Lightning Fast Hot Module Reload (HMR) to remain at the developer-experience forefront of modern web development serving a growing ecosystem of frameworks with a rich typed suite of Universal Plugins.
Vue SSG or SPA​
Both Vue & Vite being led by Evan You, which ensures both have stellar integration and delivers a well-supported & productive development experience making it the clear choice for any new Vue project.
Both vue-ssg.jamstacks.net and vue-vite.jamstacks.net utilizing the same high-end Vue3, TypeScript and Tailwind components means their included pages like TODOs MVC, Bookings and Sign In contain identical source code, the choice on which to use effectively becomes if you need advanced features like Static Site Generation (SSG) and Dark Mode or would otherwise prefer to start with a simpler template.
Features list comparison​
- vue-ssg.jamstacks.net/features
- vue-vite.jamstacks.net/features
Stale-while-revalidate in Vue3​
Just like Next.js's Stale While Revalidate, both Vue templates includes a swrClient
providing a typed wrapper around SWVR Vue3 composition library around making typed SWR API Requests using ServiceStack’s typed JsonServiceClient
, e.g:
<template>
<div v-if="error">{{ error.message }}</div>
<div v-else>{{data ? data.result :'loading...'}}</div>
</template>
<script setup lang="ts">
import { Hello } from "@/dtos"
import { swrClient } from "@/api"
const props = defineProps<{ name: string }>()
const { data, error } = swrClient.get(() =>
new Hello({ name: props.name }))
</script>
Where it yields the same optimal UX with cached API responses rendered instantly before later updating itself if modified.
Vue SSG​
React & Next.js are primarily corporate-led efforts whilst the Vue ecosystem is largely community led, with one of Vue's lieutenants Anthony Fu being the primary developer behind many of the developer-experience focused features adopted in his vite-ssg project. Most of these features are designed to reduce developer effort by auto registering routes and components by convention which effectively gives it Nuxt like productivity by utilizing hand-picked quality dependencies without needing to be reliant on the slow development pace of a heavy framework like Nuxt.
Anthony's own opinionated Vite Starter Template - Vitesse serves as a great resource for an experienced insight into a curated list of Vue & Vite packages offering the nicest developer experience, although Vue SSG will be more conservative and adopt more well-known technologies like tailwindcss in favor of Windi CSS.
Otherwise, it's still jam-packed full of features for modern Web Apps, including built-in Dark Mode support:
Vue Vite​
Don't need SSG or Dark mode? Try the simpler SPA template instead:
/api route​
Each Jamstack templates are configured to the /api
predefined route for JSON APIs:
/api/{Request}
This simple and popular convention makes it easy to remember the route new APIs are immediately available on & also pairs nicely with:
/ui/{Request}
i.e. An easy to remember route for API Explorer's Auto Form UI, together we expect both to yield greater utility out-of-the-box in ServiceStack Apps.
Benefits in Jamstack Apps​
The /api
route is particularly useful in Jamstack Apps as the 2 ways to call back-end APIs from decoupled UIs hosted on CDNs is to make CORS requests which doesn't send pre-flight CORS requests for Simple Browser requests. As such, we can improve the latency of GET and POST API Requests by configuring our JsonServiceClient
to use /api
and to not send the Content-Type: application/json
HTTP Header which isn't necessary for /api
who always expects and returns JSON:
Configuring in TypeScript​
import { JsonServiceClient } from "@servicestack/client"
const client = new JsonServiceClient(baseUrl)
It also benefits the alternative method to CORS in only needing to define a single reverse proxy rule on the CDN host to proxy all API requests to downstream back-end servers.