KRISH MAURYA — FOLIO ©2026
0
[CS /05] Case study — ©2026SELECTED WORK (03)

POES

A fullstack enterprise operations platform with a modern TypeScript + React frontend and a robust C# backend — bridging web and enterprise systems.

ROLEFull-stack · solo build
TIMELINE2026 · 6 weeks
CORE STACKTypeScript · C# · TanStack Start · Nitro
STATUSIn Progress
[01] OverviewTHE SHORT VERSION

What it is.

POES is a bridge between modern web architecture and enterprise backend systems. The frontend is built on TanStack Start — a minimal, server-driven framework that lets React components live on the server and stream to the client, eliminating the SPA bundle penalty.

The backend lives in C#, handling domain logic, integrations and database operations with the type safety and ecosystem maturity that enterprises expect. Together, they form a hybrid fullstack application: frontend type-safety from TypeScript, backend robustness from C#, and seamless communication between them.

TypeScriptC#TanStack StartReactReact QueryZodRadix UITailwind CSSVite
krishmaurya.me/poes05 / 03
poes — dashboard
POES — app preview

POES

TanStack Start frontend · C# backend · Enterprise-grade
[02] The challengeWHY IT WAS HARD

Problems worth solving.

  • Bridging TypeScript and C# type systems without manual sync — schema changes ripple across the full stack.
  • Building a frontend that works with server-driven rendering, not a traditional REST API.
  • Managing async operations across language boundaries without callback hell.
  • Keeping the C# backend loosely coupled so frontend changes don't require backend rewrites.
[03] ApproachHOW IT GOT BUILT

Built in four moves.

STEP 01

TanStack Start for the frontend

Server components render on Node.js and stream HTML, JavaScript only ships for interactivity. No SPA, no hydration overhead.

STEP 02

Typed contracts

Zod validation on the TypeScript side ensures frontend and backend agree on data shapes; C# receives validated input every time.

STEP 03

Radix UI + Tailwind

Accessible component library with no style surprises — focus, keyboard nav and ARIA attributes baked in.

STEP 04

React Query for state

Server state queries are separated from UI state. Cache invalidation and background refetches handle stale data without manual toggles.

[04] Key featuresSHIPPED & WORKING

What it does.

Server-driven UI

React components render on the server; JavaScript ships only for interactivity.

Typed validation

Zod schemas validate all incoming data on both frontend and backend.

Accessible components

Radix UI primitives with full keyboard and screen reader support.

Data fetching

React Query manages async operations, caching and background sync.

C# backend

Enterprise-grade logic, database operations and integrations.

Type-safe full-stack

Changes propagate end-to-end; no runtime surprises.

[05] Under the hood$ tree ./poes

How it fits together.

krish@dev — zsh — 80×24
krish@dev ~ % tree ./poes --depth 1
./poes
├── client/ TanStack Start · Server & client components
│ ├── routes/ File-based routing — no manual route definitions
│ └── ui/ Radix UI + Tailwind components
├── server/ Nitro server functions & middleware
├── api/ RPC & validation contracts
└── backend/ C# · Domain logic · Database access
KEY DECISIONSDECISIONS.md
  • TanStack Start over Next.js — less bundle, more server-side rendering, closer to traditional web architecture.
  • C# backend over Node.js — enterprise ecosystem, static typing, mature libraries for business logic.
  • Zod for validation — single source of truth for data shapes across the stack.
  • Radix UI over headless-only — unstyled enough to be flexible, but structured enough to be accessible by default.
[06] Results & learningsBY THE NUMBERS

What it proved.

TypeScript frontend · 27.4% C# backend71%
hydration mismatches (server-driven UI)0
language pair (TypeScript + C#) — type-safe end to end1
  • Server-driven UI feels weird at first, but it cuts your JavaScript bundle and eliminates SPA complexity.
  • Bridging type systems (TypeScript + C#) is worth the tooling overhead — schema drift becomes impossible.
  • Separating server state (React Query) from UI state (local component state) makes the data flow obvious.
  • Radix UI's accessible primitives are worth the extra kb — they save you from building accessible components from scratch.