UISampleSpark: Seven UI Paradigms, One Backend
Most tutorial projects demonstrate one way to build a web interface. SampleMvcCRUD asks a different question — what if we demonstrated all of them? Seven radically different frontend approaches, the same backend API, the same data model, compared side by side.
UISampleSpark: Seven UI Paradigms, One Backend
Part 4 of the UISampleSpark Series — The UI Showcase
The Question That Changed Everything
Most tutorial projects demonstrate one way to build a web interface. SampleMvcCRUD asks a different question: What if we demonstrated all of them?
The same backend API. The same Employee and Department data model. The same CRUD operations — create, read, update, delete. But seven radically different approaches to rendering the user interface, each with its own philosophy, its own tradeoffs, and its own community of advocates.
This wasn't an academic exercise. In the real world, development teams face this decision on every new project: do we go with server-rendered pages or a single-page application? React or Vue? Should we minimize JavaScript or embrace it? Is there a middle ground?
SampleMvcCRUD answers these questions by letting developers compare the approaches side by side, running against the same data, in the same application.
The Seven Implementations
1. Traditional MVC (/MvcEmployee
)
/MvcEmployeeThe oldest and most straightforward implementation. The
MvcEmployeeControllerIndexCreateEditDeleteA user clicks "Edit" on an employee row. The browser navigates to
/MvcEmployee/Edit/42The tradeoff: Maximum simplicity and SEO friendliness at the cost of user experience. Every interaction requires a server round-trip and full page refresh. For internal tools and content-heavy sites, this is often perfectly acceptable.
- Lines of code: ~200
- JavaScript required: Minimal (DataTables for enhanced table display)
2. Razor Pages (/EmployeeRazor
)
/EmployeeRazorRazor Pages offer a page-centric alternative to MVC. Instead of controllers with multiple actions, each page has its own
.cshtml.cshtml.csOnGetOnPostEach page is self-contained, with its model, handlers, and view in one logical unit. For CRUD operations where each page maps naturally to a database operation, this model feels intuitive.
The tradeoff: Razor Pages reduce the cognitive overhead of MVC's controller-action-view triangle. The limitation is the same as traditional MVC: full page reloads on every interaction.
- Lines of code: ~300
- JavaScript required: Moderate (form enhancement)
3. jQuery AJAX with Partial Views (/Employee
)
/EmployeeOne of the project's original approaches, dating back to April 2019. jQuery and AJAX load HTML fragments from the server without full page reloads. Bootstrap modals handle create, edit, and delete operations.
When a user clicks "Edit", jQuery fires an AJAX request to the server, which renders a partial view and returns the HTML fragment. jQuery injects this into a Bootstrap modal. On save, another AJAX request submits the form data and the employee list partial is re-fetched and swapped into the DOM.
The tradeoff: More responsive user experience than full-page MVC without requiring a modern JavaScript framework. The server still renders all HTML. The downside is jQuery's imperative programming model — managing DOM state manually becomes unwieldy as complexity grows.
- Lines of code: ~500
- JavaScript required: jQuery + inline scripts
4. React SPA (/EmployeeReact
)
/EmployeeReactThe React implementation brings a modern component-based architecture. React 18 is loaded via CDN with Babel for in-browser JSX compilation, avoiding build toolchain complexity while demonstrating React's core concepts.
A single
EmployeeTableuseStateuseEffectuseMemoconst EmployeeTable = () => {
const [employees, setEmployees] = React.useState([]);
const [search, setSearch] = React.useState('');
const filtered = React.useMemo(() => {
return employees.filter(emp =>
emp.name.toLowerCase().includes(search.toLowerCase())
);
}, [employees, search]);
return <Table data={filtered} />;
};The tradeoff: React's virtual DOM and declarative model make complex UIs manageable. State changes automatically trigger re-renders. But the CDN approach means Babel compiles JSX in the browser, adding latency on first load.
- Lines of code: 737
- JavaScript required: React 18 + Hooks
5. Vue SPA (/EmployeeVue
)
/EmployeeVueVue 3 provides a reactive SPA implementation using the Composition API loaded via CDN. Two-way data binding and fine-grained reactivity offer an alternative philosophy to React.
ref()computed()watch()v-modelv-forv-if@clickconst { createApp, ref, computed, watch } = Vue;
createApp({
setup() {
const employees = ref([]);
const searchTerm = ref('');
const filtered = computed(() => {
if (!searchTerm.value) return employees.value;
return employees.value.filter(e =>
e.name.toLowerCase().includes(searchTerm.value.toLowerCase())
);
});
watch(searchTerm, () => { currentPage.value = 1; });
return { employees, searchTerm, filtered };
}
}).mount('#vue-root');The tradeoff: Vue's two-way binding with
v-model- Lines of code: 616
- JavaScript required: Vue 3 Composition API
6. htmx — Hypermedia-Driven (/EmployeeHtmx
)
/EmployeeHtmxThe htmx implementation represents a fundamentally different philosophy: instead of shipping JavaScript frameworks to the browser and returning JSON from APIs, htmx extends HTML with attributes that enable AJAX, CSS transitions, and server-sent events directly in markup. The server returns HTML fragments, not data.
<input type="text" name="search"
hx-get="/EmployeeHtmx/Table"
hx-trigger="keyup changed delay:500ms"
hx-target="#employee-table"
hx-include="#pageSize"
hx-swap="innerHTML" />Search happens with a 500ms debounce. The server filters employees, renders a table partial with pagination controls, and returns the HTML. htmx swaps it into the target element. No JavaScript was written.
The controller uses
HX-TriggerrefreshTableThe tradeoff: Near-zero JavaScript (~20 lines in the entire implementation). Server-rendered HTML is SEO-friendly and cacheable. The server maintains all state. But every interaction requires a server round-trip, and complex client-side behaviors (drag-and-drop, real-time validation) are harder to implement.
- Lines of code: 685 (view + partials + controller)
- JavaScript required: ~20 lines (htmx handles the rest)
7. Blazor Server (/EmployeeBlazor
)
/EmployeeBlazorThe Blazor implementation eliminates JavaScript entirely by running C# on the server and pushing UI updates to the browser through a persistent SignalR WebSocket connection.
The component injects
IEmployeeService@inject IEmployeeService EmployeeService
@code {
private List<EmployeeDto> employees = new();
protected override async Task OnInitializedAsync()
{
employees = (await EmployeeService.GetEmployeesAsync(
new PagingParameterModel(), cts.Token)).ToList();
}
private async Task HandleSave()
{
await EmployeeService.SaveAsync(formEmployee, cts.Token);
await LoadData();
}
}The tradeoff: Zero JavaScript for CRUD logic. C# developers build interactive UIs without learning a JavaScript framework. Direct service injection bypasses the HTTP API, reducing latency. But every UI event travels over WebSocket to the server, creating latency for users on slow connections.
- Lines of code: 626
- JavaScript required: 0 (C# only, plus the Blazor framework script)
The Comparison Matrix
| Implementation | Paradigm | JS Needed | Server Trips | State Location | Best For |
|---|---|---|---|---|---|
| MVC | Multi-view | Minimal | Every action | Server | Content sites, simple CRUD |
| Razor Pages | Page-centric | Moderate | Every action | Page model | Page-focused workflows |
| jQuery AJAX | Modal CRUD | jQuery | API calls | Client variables | Legacy modernization |
| React | Component SPA | React Hooks | API only | | Complex interactive UIs |
| Vue | Reactive SPA | Composition API | API only | | Form-heavy applications |
| htmx | Hypermedia | ~20 lines | Every interaction | Server | SEO, progressive enhancement |
| Blazor Server | C# components | 0 | Every UI event | Component state | .NET-only teams |
What Developers Learn by Comparing
State Management Spectrum
The seven implementations span the entire spectrum of state management:
- Server state (MVC, Razor Pages, htmx): The server is the source of truth. Each request retrieves fresh data. Simplicity at the cost of latency.
- Client state (React, Vue, jQuery): Data is loaded once and managed in the browser. Fast interactions, but state can drift from the server.
- Hybrid state (Blazor): State lives on the server but UI updates push to the client over WebSocket. The speed of client-side rendering with the authority of server-side state.
JavaScript Complexity Spectrum
From zero JavaScript (Blazor) to framework-heavy (React, Vue), the implementations demonstrate that JavaScript isn't always the answer — and isn't always avoidable:
- Blazor proves you can build interactive UIs without touching JavaScript
- htmx proves you can add interactivity with HTML attributes instead of JavaScript code
- jQuery proves that imperative DOM manipulation works but doesn't scale
- React and Vue prove that declarative frameworks manage complexity better for rich UIs
The Performance Conversation
Each approach handles performance differently:
- SPA approaches (React, Vue) load all data upfront, making subsequent interactions instant but initial load heavier
- Server-rendered approaches (MVC, htmx) deliver fast initial loads but require round-trips for every interaction
- Blazor occupies a unique position: fast initial load (thin client) but every click requires a WebSocket round-trip
Cloud-Native Aspirations: The .NET Aspire Experiment
SampleMvcCRUD's UI diversity wasn't the only expansion. The project also explored cloud-native architecture through .NET Aspire, Microsoft's framework for building distributed, observable applications.
In early 2024, an AspireHost project explored decomposing the monolithic application into orchestrated services with service discovery, OpenTelemetry instrumentation, and multi-project orchestration. By May 2024, the Aspire artifacts were removed from the main solution — the experiment succeeded in demonstrating cloud-native concepts, but keeping the artifacts risked confusing developers who came for straightforward MVC examples.
This decision exemplified the project's philosophy: demonstrate advanced concepts, but don't let them overwhelm the fundamentals. The Aspire influence persisted in the application's health check infrastructure at
/health/statusThe Navigation Experience
All seven CRUD implementations are accessible from a unified dropdown menu:
Employees (dropdown)
├── Single Page (DataTables SPA)
├── Employee (jQuery AJAX)
├── MVC Employee (Traditional)
├── Employee Razor (Page-centric)
├── React
├── htmx
├── Vue
└── BlazorThe consistent navigation makes comparison effortless — click "React", try the CRUD operations, click "htmx", try the same operations, and observe the differences in behavior, responsiveness, and browser network activity.
The Educational Impact
The seven-paradigm showcase transforms SampleMvcCRUD from a code reference into a decision-making tool. A team evaluating frontend approaches for a new project can:
- Clone the repository and run it locally
- Try each implementation with the same employee data
- Open browser developer tools and compare network traffic
- Examine the source code to understand implementation complexity
- Make an informed architectural decision based on hands-on experience
The tradeoffs aren't theoretical — they're visible, tangible, and running on localhost.
Additional Resources
- SampleMvcCRUD on GitHub
- Live Demo — Try All Seven
- htmx Documentation
- Blazor Server Documentation
- React Documentation
- Vue 3 Documentation
UISampleSpark Series
This is part 4 of a five-part series tracing the evolution of SampleMvcCRUD from a simple CRUD tutorial to a comprehensive web UI exploration platform.
- A Developer's Swiss Army Knife — The founding philosophy and core architecture
- Seven Years of .NET Modernization — Navigating the annual .NET upgrade cycle
- Constitution-Driven Development — How governance and AI transformed project quality
- Seven UI Paradigms, One Backend (this article) — Comparing seven frontend approaches side by side
- Modern DevOps as a Living Reference — Containerization, CI/CD, and cloud deployment
Project Links: GitHub | Live Demo | Docker Hub


