Architecture
How VitNode combines TanStack Start for UI and isomorphic routing with Hono for API authorization and database access.
VitNode separates concerns between two core layers:
- TanStack Start: Frontend UI, SSR, isomorphic routing, and client caching.
- Hono API: Backend routing, session management, staff permissions, and database operations.
System Boundaries
| Responsibility | TanStack Start (Web App) | Hono (API) |
|---|---|---|
| Routing | Page URLs, dynamic parameters, nested layouts | REST/RPC endpoints under /api/* |
| Data Fetching | Route loaders and the universal fetcher | Query execution via Drizzle ORM |
| State & Cache | TanStack Query client cache | Redis domain cache & database storage |
| Security Boundary | UI guards (redirecting unauthenticated users) | Enforces authentication, permissions, CSRF, and rate limits |
Security Boundary
Route guards (beforeLoad) enhance UX by redirecting visitors early, but the
Hono API is the true security boundary. All private endpoints strictly verify
cookies and permissions on every request.
End-to-End Request Flow
When a user visits a page (e.g. /blog):
| Phase | Runtime | Action |
|---|---|---|
| 1. Request | Browser | Visitor navigates to /blog |
| 2. Routing | Server (SSR) / Browser | TanStack Router matches route and executes loader |
| 3. Query Warming | Server / Browser | context.queryClient.query executes isomorphic fetcher |
| 4. RPC Call | Server / Browser | The universal fetcher calls the Hono endpoint by plugin id |
| 5. API Middleware | Server (Hono) | Verifies session cookie, applies rate limits, injects c.get(db) |
| 6. Handler & Database | Server (Hono) | Handler validates input and queries PostgreSQL via Drizzle |
| 7. Response | Server / Browser | JSON data hydrates TanStack Query cache and paints component |
The Request Pipeline
Before route matching, every request passes through the middleware
createVitNodeStart installs - in this order, and an app cannot get in front of
any of it:
| Order | Middleware | Applies to |
|---|---|---|
| 1 | CSRF | Server function calls (handlerType === 'serverFn') |
| 2 | Locale | Page requests: canonical 308 redirects and the locale cookie |
| 3 | Document cache | HTML responses: forced Cache-Control: private, no-store |
| 4 | Your own | Whatever requestMiddleware lists |
/api/* reaches the same middleware and passes through untouched - no redirect,
no rewrite, no cache directive - so the Hono bridge sees the request exactly as
the client sent it and keeps its own caching policy. See
Configuration.
Plugin System Architecture
VitNode is built around modular plugins located in plugins/*:
- Independent Packages: Plugins compile to their own
dist/with isolated dependencies. - Unified Manifest: Routes, AdminCP navigation, and database models are registered declaratively.
- Zero Overhead: Inactive plugins contribute no code or overhead to production bundles.
Learn More
Vercel
Deploy a VitNode app to Vercel: the settings that work, the features that need a server which stays up, and where migrations have to run instead.
Configuration
The two config files a VitNode app owns - the browser-safe shared one, and the server-only companion - plus the request pipeline Core installs for you.