| name | component-organization |
| description | Component organization patterns for React applications. Use when creating components, organizing files, or structuring routes. ALWAYS keep 1 component per file and routes simple. |
Component Organization
Core Principles
1 Component Per File
Each component should be in its own file with a clear, descriptive name.
export function SiteInfoSection({ siteName, siteUrl, onUpdate }) {
return (
<div className="space-y-4">
{/* Site info form fields */}
</div>
);
}
export function SiteInfoSection() { ... }
export function ThemeSection() { ... }
export function SEOSection() { ... }
Folder Structure
Organize components by feature and purpose, using categorized folders:
app/
โโโ components/
โ โโโ ui/ # Primitives (button, input, card, dialog)
โ โ โโโ button.tsx
โ โ โโโ input.tsx
โ โ โโโ card.tsx
โ โ โโโ dialog.tsx
โ โ
โ โโโ shared/ # Cross-feature shared components
โ โ โโโ ColorPicker.tsx
โ โ โโโ NodeControls.tsx
โ โ โโโ VideoEmbed.tsx
โ โ
โ โโโ [feature]/ # Feature-specific components
โ โโโ [page]/ # Page-specific components
โ โโโ Header.tsx
โ โโโ Sidebar.tsx
โ โโโ ContentSection.tsx
โ โโโ ActionsPanel.tsx
โ
โโโ features/ # Complex features with multiple concerns
โ โโโ [feature]/
โ โโโ components/ # Feature's internal components
โ โโโ hooks/ # Feature-specific hooks
โ โโโ stores/ # Feature-specific state
โ
โโโ routes/
โโโ admin/
โโโ settings.tsx # Simple wrapper
Example: Admin Settings Structure
app/
โโโ components/
โ โโโ admin/
โ โโโ settings/
โ โโโ SettingsPage.tsx # Main page component
โ โโโ SiteInfoSection.tsx # Site name, URL
โ โโโ ThemeSection.tsx # Theme settings
โ โโโ SEOSection.tsx # SEO fields
โ โโโ DangerZoneSection.tsx # Logout, destructive actions
โ
โโโ routes/
โโโ admin/
โโโ settings.tsx # Simple wrapper (see below)
Example: Blog Feature Structure
app/
โโโ components/
โ โโโ blog/
โ โโโ index/
โ โโโ PostCard.tsx
โ โโโ Pagination.tsx
โ โโโ BioSidebar.tsx
โ
โโโ features/
โโโ blog/
โโโ components/
โ โโโ shared/
โ โโโ PostHeader.tsx
โโโ hooks/
โ โโโ usePosts.ts
โโโ stores/
โโโ isAdmin.ts
Simple Route Pattern
Routes should be thin wrappers that delegate to page components. Keep loaders and actions in the route, but move JSX to a component.
import { SettingsPage } from "~/components/admin/settings/SettingsPage";
export const loader = async ({ request }: Route.LoaderArgs) => {
const settings = await getAllSettings();
return { settings };
};
export const action = formAction({
schema: settingsSchema,
handler: async ({ request }, formData) => {
await updateSettings(formData);
return success();
},
});
export default function SettingsRoute() {
const { settings } = useLoaderData<typeof loader>();
return <SettingsPage settings={settings} />;
}
export default function SettingsRoute() {
const { settings } = useLoaderData<typeof loader>();
return (
<div className="container">
<h1>Settings</h1>
<div className="grid">
<section>
<h2>Site Info</h2>
<Input ... />
<Input ... />
{/* 800 more lines of JSX */}
</section>
</div>
</div>
);
}
Page Component Pattern
The page component imported by the route can compose smaller section components:
import { SiteInfoSection } from "./SiteInfoSection";
import { ThemeSection } from "./ThemeSection";
import { SEOSection } from "./SEOSection";
export function SettingsPage({ settings }) {
const submitter = useDynamicSubmitter();
const [siteInfo, setSiteInfo] = useState(settings.siteInfo);
const [theme, setTheme] = useState(settings.theme);
return (
<div className="container">
<h1>Settings</h1>
<div className="space-y-8">
<SiteInfoSection
data={siteInfo}
onChange={setSiteInfo}
/>
<ThemeSection
data={theme}
onChange={setTheme}
/>
<SEOSection
data={settings.seo}
/>
</div>
</div>
);
}
Benefits
This organization provides:
- Easy to find components (predictable structure)
- Clear separation of concerns
- Reusable components (1 per file)
- Simple routes that are easy to understand
- Easier testing (components are isolated)
- Better code review (small, focused files)
When Creating New Components
- Ask: "Is this a UI primitive?" โ
components/ui/
- Ask: "Will multiple features use this?" โ
components/shared/
- Ask: "Is this specific to a feature?" โ
components/[feature]/ or features/[feature]/components/
- Ask: "Is this specific to a page?" โ
components/[feature]/[page]/
Always create a new file for each component, even if it's small. Small, focused files are better than large, multi-purpose files.
Generated images, mockups, and โasset packโ rasters
AI-generated or imported layout mockups and reference sheets are for visual reference โ not automatic UI chrome. Prefer real DOM, CSS, and accessible text/controls for buttons, forms, labels, and panels. Use raster assets sparingly: backgrounds, subtle accents, posters/cards, decorative textures. Avoid stretching a generated PNG of fake UI (buttons, panels) as the primary control surface without visual testing in a real browser. Realtime and canvas-specific patterns: cf-socka-realtime/SKILL.md.