Back to list
dcyfr

dcyfr-component-patterns

by dcyfr

DCYFR Labs

2🍴 0📅 Jan 25, 2026

SKILL.md


name: dcyfr-component-patterns description: Guide DCYFR component structure with PageLayout, barrel exports, and metadata license: MIT compatibility: opencode metadata: audience: developers workflow: implementation category: architecture

What I do

I ensure DCYFR components follow established architectural patterns:

  • 90% PageLayout usage - Default layout for standard pages
  • Barrel exports only - No direct file imports
  • Metadata generation - Proper SEO metadata on all pages
  • Import strategy - Consistent import patterns across codebase

When to use me

Use this skill when:

  • Creating new pages or components
  • Refactoring existing components to follow DCYFR patterns
  • Deciding which layout to use (PageLayout vs ArticleLayout vs ArchiveLayout)
  • Setting up barrel exports for new component directories

Don't use this skill for:

  • Testing patterns (use dcyfr-testing skill)
  • API route patterns (use dcyfr-api-patterns skill)

Core Rules (NON-NEGOTIABLE)

1. PageLayout (90% Rule)

Use PageLayout for 90% of pages

// ✅ CORRECT: PageLayout for standard pages
import { PageLayout } from "@/components/layouts";

export default function AboutPage() {
  return (
    <PageLayout>
      <div className={`mx-auto ${CONTAINER_WIDTHS.standard}`}>
        Content
      </div>
    </PageLayout>
  );
}

Exceptions (10%):

  • ArticleLayout - For blog posts and articles
  • ArchiveLayout - For filterable lists (blog archive, work items)

2. Barrel Exports Only

// ✅ CORRECT: Import from barrel export
import { PostCard, CategoryBadge } from "@/components/blog";

// ❌ WRONG: Direct file imports
import { PostCard } from "@/components/blog/post-card";
import { CategoryBadge } from "@/components/blog/category-badge";

Barrel export structure:

// src/components/blog/index.ts
export { PostCard } from "./post-card";
export { CategoryBadge } from "./category-badge";
export { BlogFilter } from "./blog-filter";

3. Metadata Generation

Every page must export metadata:

import { createPageMetadata } from "@/lib/metadata";

export const metadata = createPageMetadata({
  title: "Page Title",
  description: "Page description for SEO",
  path: "/path",
});

Available helpers:

  • createPageMetadata() - Standard pages
  • createArticleMetadata() - Blog posts
  • createRichMetadata() - Complex metadata with images

Decision Trees

Which Layout?

START: Creating a new page

Is it a blog post?
├─ YES → Use ArticleLayout
│
Is it a filterable list (blog archive, work items)?
├─ YES → Use ArchiveLayout
│
Otherwise → Use PageLayout (default)

Which Container Width?

START: Choosing container width

Is it a blog post?
├─ YES → CONTAINER_WIDTHS.prose (optimal reading width)
│
Is it a wide layout (dashboard, gallery)?
├─ YES → CONTAINER_WIDTHS.wide
│
Otherwise → CONTAINER_WIDTHS.standard (default)

Common Patterns

New Page Template

import { PageLayout } from "@/components/layouts";
import { createPageMetadata } from "@/lib/metadata";
import { CONTAINER_WIDTHS, SPACING, TYPOGRAPHY } from "@/lib/design-tokens";

export const metadata = createPageMetadata({
  title: "Page Title",
  description: "Page description",
  path: "/page-path",
});

export default function NewPage() {
  return (
    <PageLayout>
      <div className={`mx-auto ${CONTAINER_WIDTHS.standard}`}>
        <h1 className={TYPOGRAPHY.h1.standard}>
          Page Heading
        </h1>
        <div className={`mt-${SPACING.content}`}>
          Content
        </div>
      </div>
    </PageLayout>
  );
}

New Component with Barrel Export

# 1. Create component file
# src/components/blog/new-component.tsx

# 2. Add to barrel export
# src/components/blog/index.ts
export { NewComponent } from "./new-component";

# 3. Import from barrel
import { NewComponent } from "@/components/blog";

Validation

# Check component patterns
npm run lint

# Full quality check
npm run check

# OpenCode-specific validation
npm run check:opencode

ESLint Rules

  • import/no-restricted-paths - Enforces barrel exports
  • @dcyfr/component-patterns/require-page-layout - Validates layout usage
  • Full component patterns: .github/agents/patterns/COMPONENT_PATTERNS.md
  • Layout decision tree: docs/ai/decision-trees.md
  • Templates: docs/templates/NEW_PAGE.tsx.md

Approval Gates

Component pattern violations are STRICT (hard block):

  • ❌ Direct imports fail ESLint
  • ❌ Missing metadata fails build
  • ✅ Must follow patterns before merging

PageLayout preference is FLEXIBLE (warning only):

  • ⚠️ Reviewed during PR
  • ⚠️ Must justify exceptions (ArticleLayout, ArchiveLayout)

Score

Total Score

65/100

Based on repository quality metrics

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

+10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

1ヶ月以内に更新

+10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

+5

Reviews

💬

Reviews coming soon