A modern, production-ready full-stack React application template combining TanStack Router with Hono for server-side rendering. This setup delivers fast, SEO-friendly applications with excellent developer experience.
AI Ready: this repo includes checked-in framework-specific docs in
docs/ai/and repo-local skills in.agents/skills/so an LLM can follow the project's actual patterns when helping build the app.
# Clone the template
npx degit bskimball/tanstack-hono my-app
# Navigate to your project
cd my-app
# Run the interactive setup script
bash scripts/setup.shThe setup script will:
- Update project name in package.json
- Create .env file from .env.example
- Install dependencies (optional)
- Initialize git repository (optional)
# Clone the template
npx degit bskimball/tanstack-hono my-app
# Navigate to your project
cd my-app
# Copy environment file
cp .env.example .env
# Install dependencies
npm install
# Start development server
npm run devOpen http://localhost:3000 to see your app running!
Health Check: http://localhost:3000/api/health
- πΊ TanStack Router: Type-safe, file-based routing with powerful data loading
- β‘ Hono SSR: Ultra-fast server-side rendering with minimal overhead
- π₯ Vite+: Lightning-fast development with Hot Module Replacement, powered by Rolldown
- π TypeScript: Full type safety across client and server, checked by tsgo/tsgolint
- π¨ Tailwind CSS v4: Modern utility-first CSS framework
- π§Ή Oxlint & Oxfmt: Fast linting and formatting via Vite+ (replaces ESLint & Prettier)
- π§ͺ Vitest: Fast unit testing with great DX
src/
βββ components/
β βββ Header.tsx # Site header component
β βββ HeroSection.tsx # Landing page hero
βββ hooks/
β βββ useDebounce.ts # Reusable debounce hook
βββ lib/
β βββ api.ts # Shared Hono RPC client
βββ routes/ # File-based routing (TanStack Router)
β βββ __root.tsx # Root layout component
β βββ index.tsx # Home page route
β βββ about.tsx # About page route
β βββ error.tsx # Error boundary route
β βββ -api.ts # Server-only API route helpers
β βββ -test.ts # Test route utilities (ignored by router)
βββ tests/
β βββ Header.test.tsx
β βββ HeroSection.test.tsx
β βββ root-route.test.tsx
βββ entry-client.tsx # Client-side hydration entry
βββ entry-server.tsx # Hono server with SSR setup
βββ router.tsx # Router configuration
βββ routeTree.gen.ts # Auto-generated route tree (do not edit)
βββ reportWebVitals.ts # Web Vitals reporting
βββ styles.css # Global styles
vp dev # Start development server
vp run build # Build for production (client + server)
vp test # Run tests
vp check # Lint, format, and type-check
vp check --fix # Auto-fix lint and formatting issues
npm start # Start production server (after build)- Request: Browser requests a URL
- Server: Hono matches route and runs TanStack Router SSR
- Render: React components render through TanStack Router's streaming SSR handler
- Response: The HTML stream is sent with embedded router data
- Hydration: Client-side React takes over for SPA navigation
This template uses renderRouterToStream in src/entry-server.tsx. Streaming is
compatible with the root route's lazy development tools and supports Suspense without
forcing affected boundaries to client rendering.
See docs/ai/streaming.md for:
- How the server entry is wired for streaming
- How to use the existing Hono RPC client in deferred loaders and queries
- A
defer(...)+Awaitexample - A
Suspenseexample - An SSR query streaming example using
@tanstack/react-router-ssr-query
Routes are automatically generated from files in src/routes/:
// src/routes/about.tsx
import { createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute("/about")({
component: AboutPage,
});
function AboutPage() {
return <div>About us!</div>;
}import { Link } from "@tanstack/react-router";
function Navigation() {
return <Link to="/about">About</Link>;
}import type { InferResponseType } from "hono/client";
import { createFileRoute } from "@tanstack/react-router";
import { api } from "../lib/api";
const getHealthRoute = api.health.$get;
type Health = InferResponseType<typeof getHealthRoute>;
async function getHealth(): Promise<Health> {
const response = await api.health.$get();
if (!response.ok) {
throw new Error("Failed to load health check");
}
return response.json();
}
export const Route = createFileRoute("/status")({
loader: async () => {
return {
health: await getHealth(),
};
},
component: StatusPage,
});
function StatusPage() {
const { health } = Route.useLoaderData();
return <pre>{JSON.stringify(health, null, 2)}</pre>;
}For client-side data, you can reuse the same Hono-backed helpers with TanStack Query instead of maintaining a separate fetch path:
import { queryOptions, useQuery } from "@tanstack/react-query";
export const healthQuery = queryOptions({
queryKey: ["health"],
queryFn: getHealth,
staleTime: 30_000,
});
function HealthBadge() {
const { data, isPending } = useQuery(healthQuery);
if (isPending) return <p>Checking API...</p>;
return <p>API status: {data.status}</p>;
}See docs/ai/routing-and-data.md and docs/ai/server-api.md for the full Hono
RPC patterns used in this template.
The root layout (src/routes/__root.tsx) wraps all pages:
import { Outlet, createRootRoute } from "@tanstack/react-router";
import { Header } from "../components/Header";
export const Route = createRootRoute({
component: RootLayout,
});
function RootLayout() {
return (
<>
<Header />
<main>
<Outlet />
</main>
</>
);
}SSR Advantages:
- SEO: Fully rendered HTML for search engines
- LCP: Faster Largest Contentful Paint
- Progressive Enhancement: Works without JavaScript
- Social Sharing: Rich preview cards with meta tags
Hono Benefits:
- Small Bundle: Minimal server overhead
- Edge Ready: Deploy to Cloudflare Workers, etc.
- Fast Startup: Quick cold start times
# Build and run production
docker-compose up app
# Development with hot reload
docker-compose --profile dev up devdocker build -t tanstack-hono .
docker run -p 3000:3000 tanstack-hononpm run build
npm start- Docker: Use included Dockerfile and docker-compose.yml
- Vercel/Netlify: Serverless functions
- Railway/Render: Container deployments
- Cloudflare Workers: Edge runtime
- VPS: With PM2 + Nginx
See ARCHITECTURE.md for detailed deployment strategies.
- AGENTS.md - Guide for AI agents working with this codebase
- CLAUDE.md - Claude-specific context and patterns
- docs/ai/README.md - Index of framework-specific working docs for this repo
- ARCHITECTURE.md - Deep dive into system design
- CONTRIBUTING.md - Contribution guidelines
- docs/ai/streaming.md - How to enable TanStack Router streaming SSR
This template includes checked-in guidance for LLMs and coding agents, so they have repo-specific context for building features instead of relying only on generic framework knowledge.
.cursorrulesfor Cursor IDEAGENTS.mdfor general AI agent guidelinesCLAUDE.mdfor Claude-specific contextdocs/ai/for task-focused docs covering commands, architecture, routing, Hono APIs, styling, testing, deployment, and streaming SSR.agents/skills/for repo-local skills covering Hono, TanStack Router, TanStack Query, Vite, Vite+, Vitest, and React research
An LLM that reads those files should have the project-specific instructions it needs to help implement and maintain the app effectively.
- TanStack Router - Type-safe routing
- Hono - Ultrafast web framework
- SSR Guide - TanStack Router SSR
- Vite SSR - Vite server-side rendering
MIT License - see LICENSE file for details
Contributions are welcome! Please read CONTRIBUTING.md for guidelines.