tanstack-start-shadcn-tailwind — GitHub Copilot rule: what it does
A Copilot instruction file that pins the stack to TanStack Start, Shadcn/ui and Tailwind CSS, with Zod validating every external payload.
.github/instructions/tanstack-start-shadcn-tailwind.instructions.mdWhat tanstack-start-shadcn-tailwind does
The rule tells Copilot how to write code in a TanStack Start app: TypeScript in strict mode, function components, Shadcn/ui instead of hand-rolled buttons and cards, Tailwind for layout. External data goes through Zod schemas kept in src/lib/schemas.ts. The any type is off the table.
Data fetching is split by purpose. Initial render data, SSR and SEO-critical data come from route loaders; frequently updating and secondary data come from TanStack Query. Every route in src/routes/ needs error and pending boundaries. Internal imports use the @/ alias.
This ships as an instruction file, not a package. For GitHub Copilot the path is .github/instructions/tanstack-start-shadcn-tailwind.instructions.md. If your project is not on TanStack Start with Shadcn/ui and Tailwind, there is nothing for it to govern — Copilot will keep pushing the src/routes/ layout and the @/ alias into code that does not use them.
What it helps with
- keep Copilot writing one consistent style across a TanStack Start app
- move external data validation into Zod schemas
- decide when to use route loaders and when to use TanStack Query
- add error and pending boundaries to every route
- swap custom UI components for Shadcn/ui
Example prompts for the agent
- Create a /users/$id route with a loader, errorBoundary and pendingBoundary following the project rules
- Define a Zod schema for the user in src/lib/schemas.ts and validate the API response
- Rewrite this component with Shadcn/ui and Tailwind, imports through @/
How to install tanstack-start-shadcn-tailwind
Manually: put the files in place
.github/instructions/tanstack-start-shadcn-tailwind.instructions.mdThe applyTo field sets which files it applies to
Manually: put the files in place
.claude/rules/tanstack-start-shadcn-tailwind.mdThe paths frontmatter field limits the files: move applyTo from the source into paths
AGENTS.md
Codex reads AGENTS.md: paste the rule text there
Manually: put the files in place
.cursor/rules/tanstack-start-shadcn-tailwind.mdcFrontmatter: description, globs, alwaysApply. Move applyTo from the source into globs, or the rule will not attach on its own
Manually: put the files in place
.devin/rules/tanstack-start-shadcn-tailwind.mdManually: put the files in place
.clinerules/tanstack-start-shadcn-tailwind.mdStep by step, with commands for each platform: AGENTS.md vs CLAUDE.md: what they are and which one to use
Questions about tanstack-start-shadcn-tailwind
How do I install tanstack-start-shadcn-tailwind in GitHub Copilot?
Add the file .github/instructions/tanstack-start-shadcn-tailwind.instructions.md to your repository. The rule is picked up through the applyTo mask in its frontmatter.
What does tanstack-start-shadcn-tailwind do?
It sets Copilot's conventions for TanStack Start work: strict TypeScript, Shadcn/ui, Tailwind, Zod for external data and route loaders for initial data.
Which files does the rule apply to?
The applyTo mask covers **/*.ts, **/*.tsx, **/*.js, **/*.jsx, **/*.css, **/*.scss and **/*.json.
Source text
tanstack-start-shadcn-tailwind.instructions.md · MIT
---
description: 'Guidelines for building TanStack Start applications'
applyTo: '**/*.ts, **/*.tsx, **/*.js, **/*.jsx, **/*.css, **/*.scss, **/*.json'
---
# TanStack Start with Shadcn/ui Development Guide
You are an expert TypeScript developer specializing in TanStack Start applications with modern React patterns.
## Tech Stack
- TypeScript (strict mode)
- TanStack Start (routing & SSR)
- Shadcn/ui (UI components)
- Tailwind CSS (styling)
- Zod (validation)
- TanStack Query (client state)
## Code Style Rules
- NEVER use `any` type - always use proper TypeScript types
- Prefer function components over class components
- Always validate external data with Zod schemas
- Include error and pending boundaries for all routes
- Follow accessibility best practices with ARIA attributes
## Component Patterns
Use function components with proper TypeScript interfaces:
```typescript
interface ButtonProps {
children: React.ReactNode;
onClick: () => void;
variant?: 'primary' | 'secondary';
}
export default function Button({ children, onClick, variant = 'primary' }: ButtonProps) {
return (
<button onClick={onClick} className={cn(buttonVariants({ variant }))}>
{children}
</button>
);
}
```
## Data Fetching
Use Route Loaders for:
- Initial page data required for rendering
- SSR requirements
- SEO-critical data
Use React Query for:
- Frequently updating data
- Optional/secondary data
- Client mutations with optimistic updates
```typescript
// Route Loader
export const Route = createFileRoute('/users')({
loader: async () => {
const users = await fetchUsers()
return { users: userListSchema.parse(users) }
},
component: UserList,
})
// React Query
const { data: stats } = useQuery({
queryKey: ['user-stats', userId],
queryFn: () => fetchUserStats(userId),
refetchInterval: 30000,
});
```
## Zod Validation
Always validate external data. Define schemas in `src/lib/schemas.ts`:
```typescript
export const userSchema = z.object({
id: z.string(),
name: z.string().min(1).max(100),
email: z.string().email().optional(),
role: z.enum(['admin', 'user']).default('user'),
})
export type User = z.infer<typeof userSchema>
// Safe parsing
const result = userSchema.safeParse(data)
if (!result.success) {
console.error('Validation failed:', result.error.format())
return null
}
```
## Routes
Structure routes in `src/routes/` with file-based routing. Always include error and pending boundaries:
```typescript
export const Route = createFileRoute('/users/$id')({
loader: async ({ params }) => {
const user = await fetchUser(params.id);
return { user: userSchema.parse(user) };
},
component: UserDetail,
errorBoundary: ({ error }) => (
<div className="text-red-600 p-4">Error: {error.message}</div>
),
pendingBoundary: () => (
<div className="flex items-center justify-center p-4">
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary" />
</div>
),
});
```
## UI Components
Always prefer Shadcn/ui components over custom ones:
```typescript
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
<Card>
<CardHeader>
<CardTitle>User Details</CardTitle>
</CardHeader>
<CardContent>
<Button onClick={handleSave}>Save</Button>
</CardContent>
</Card>
```
Use Tailwind for styling with responsive design:
```typescript
<div className="flex flex-col gap-4 p-6 md:flex-row md:gap-6">
<Button className="w-full md:w-auto">Action</Button>
</div>
```
## Accessibility
Use semantic HTML first. Only add ARIA when no semantic equivalent exists:
```typescript
// ✅ Good: Semantic HTML with minimal ARIA
<button onClick={toggleMenu}>
<MenuIcon aria-hidden="true" />
<span className="sr-only">Toggle Menu</span>
</button>
// ✅ Good: ARIA only when needed (for dynamic states)
<button
aria-expanded={isOpen}
aria-controls="menu"
onClick={toggleMenu}
>
Menu
</button>
// ✅ Good: Semantic form elements
<label htmlFor="email">Email Address</label>
<input id="email" type="email" />
{errors.email && (
<p role="alert">{errors.email}</p>
)}
```
## File Organization
```
src/
├── components/ui/ # Shadcn/ui components
├── lib/schemas.ts # Zod schemas
├── routes/ # File-based routes
└── routes/api/ # Server routes (.ts)
```
## Import Standards
Use `@/` alias for all internal imports:
```typescript
// ✅ Good
import { Button } from '@/components/ui/button'
import { userSchema } from '@/lib/schemas'
// ❌ Bad
import { Button } from '../components/ui/button'
```
## Adding Components
Install Shadcn components when needed:
```bash
npx shadcn@latest add button card input dialog
```
## Common Patterns
- Always validate external data with Zod
- Use route loaders for initial data, React Query for updates
- Include error/pending boundaries on all routes
- Prefer Shadcn components over custom UI
- Use `@/` imports consistently
- Follow accessibility best practices
© github · MIT · github/awesome-copilot