This file provides essential information for agentic coding assistants working in this repository.
8bitcn/ui is a retro 8-bit styled component library built with Next.js 16 (App Router), React 19, TypeScript (strict mode), Tailwind CSS v4, and shadcn/ui + Radix UI components. It's a shadcn/ui registry that provides pixelated, gaming-themed components.
Package Manager: pnpm
Registry: https://ui.shadcn.com/registry
Installation: pnpm dlx shadcn@latest add @8bitcn/[component-name]
pnpm dev- Start development server (http://localhost:3000)pnpm build- Build for productionpnpm start- Start production server
pnpm check- Run Ultracite linting checks (Biome-based)pnpm fix- Auto-fix linting issues (Ultracite)npx ultracite fix- Format and fix all issuesnpx ultracite check- Check for issues onlynpx ultracite doctor- Diagnose Ultracite setup
No test framework is currently configured. When adding tests, use Vitest as the preferred testing framework.
This project uses Ultracite (Biome-based preset) for automatic formatting and linting. Always run pnpm fix before committing. Biome handles most formatting automatically - focus on code quality and logic.
Wrapper Pattern: 8-bit components wrap regular shadcn/ui components rather than replacing them:
import { Button as ShadcnButton } from "@/components/ui/button"
import "./styles/retro.css"
export const Button = ({ className, ...props }: ButtonProps) => {
return (
<div className="relative">
<ShadcnButton className={cn("rounded-none", className)} {...props} />
{/* Pixelated border elements */}
</div>
)
}Pixelated Border Construction: Use absolute-positioned divs for 8-bit borders:
<div className="absolute -top-1.5 w-1/2 left-1.5 h-1.5 bg-foreground dark:bg-ring" />
<div className="absolute -top-1.5 w-1/2 right-1.5 h-1.5 bg-foreground dark:bg-ring" />Required Retro CSS: All 8-bit components must import the retro stylesheet:
import "./styles/retro.css"- Use
@/*path alias for internal imports (configured in tsconfig.json)import { Button } from "@/components/ui/button" import { cn } from "@/lib/utils"
- Import order: External libraries (alphabetical) → Internal
@/*imports - Prefer named exports over default exports
- 8-bit components must import retro.css:
import "./styles/retro.css"
- Strict mode enabled - All types must be properly defined
- Use explicit types for function parameters and return values when they enhance clarity
- Prefer
unknownoveranywhen the type is genuinely unknown - Use
constassertions (as const) for immutable literal values - Leverage TypeScript's type narrowing instead of type assertions
- Use meaningful variable names instead of magic numbers
- Use function components only - no class components
- Call hooks at top level only, never conditionally
- Specify all dependencies in hook dependency arrays correctly
- Use
keyprop for iterables (prefer unique IDs over array indices) - Nest children between opening/closing tags, not as props
- Don't define components inside other components
- For React 19+: Use
refas prop instead ofReact.forwardRef
- Use Next.js
<Image>component for all images (never<img>tags) - Use App Router metadata API for head elements
- Use Server Components for async data fetching
"use cache"directive for cached async data (see StarsCount component)
- Keep functions focused with reasonable cognitive complexity
- Extract complex conditions into well-named boolean variables
- Use early returns to reduce nesting
- Avoid barrel files (index files that re-export everything)
- Group related code and separate concerns
- Throw
Errorobjects with descriptive messages, not strings - Use
try-catchblocks meaningfully in async code - Prefer early returns over nested conditionals for error cases
- Remove
console.log,debugger, andalertfrom production code
- Avoid spread syntax in accumulators within loops
- Use top-level regex literals instead of creating them in loops
- Prefer specific imports over namespace imports
- Avoid creating objects/arrays inside loops when possible
- Components: PascalCase (e.g.,
UserProfile,Button) - Functions/hooks: camelCase (e.g.,
useIsMobile,calculateTotal) - Constants/Types: PascalCase (e.g.,
MOBILE_BREAKPOINT,ButtonProps) - CSS classes: kebab-case (handled by Tailwind)
- Files: kebab-case for utilities, PascalCase for components
- Use Tailwind CSS v4 for all styling
- Use
cn()utility from@/lib/utilsfor conditional classes - Avoid inline styles - use Tailwind classes
- Use semantic HTML elements with proper ARIA attributes
- Provide meaningful alt text for images
- Use proper heading hierarchy (h1 → h2 → h3)
- Add labels for form inputs
- Include keyboard handlers alongside mouse events
- Use semantic elements (
<button>,<nav>,<main>) instead of divs with roles
- Add
rel="noopener"when usingtarget="_blank"on links - Avoid
dangerouslySetInnerHTMLunless absolutely necessary - Never use
eval()or directdocument.cookieassignment - Validate and sanitize user input
Follow conventional commits: category(scope): message
Categories:
feat- New featuresfix- Bug fixes (reference issue if applicable)refactor- Code changes that aren't fixes or featuresdocs- Documentation changesbuild- Build/dependency changestest- Test changesci- CI/CD configurationchore- Other changes
Example: feat(components): add new prop to avatar component
Components are registered in registry.json with specific patterns:
- Component entries: Include retro.css dependency and proper file mappings
- Block entries: Pre-built layouts like login forms, player profiles
- Gaming categories: Components marked with "gaming" category for game UI elements
- Dependencies: Explicitly declare shadcn/ui dependencies via
registryDependencies
/app - Next.js App Router pages
/components - React components
/ui - shadcn/ui components
/ui/8bit - Retro 8-bit styled components
/lib - Utility functions
/config - Configuration files
/hooks - Custom React hooks
/types - TypeScript type definitions
/public - Static assets
This project uses Fumadocs for documentation generation and management:
- Docs location:
content/docs/directory - Configuration:
source.config.tsdefines docs collection - Search: Built-in search functionality via
/app/api/search/route.ts - MDX support: Components documented in MDX format with custom components
- URL structure: Documentation served at
/docs/*routes
These rules are strict for all v2 block work.
- Use ONLY 8bitcn components for all new blocks (
components/ui/8bit/*and approved 8bitcn wrappers). - Never import Lucide, Phosphor, Heroicons, or emoji-based icons in 8bitcn blocks.
- Use only 8bit icon sources/components (approved local 8bit icons / raster-style icon set).
- No emojis in UI copy, block copy, docs copy, or placeholder text for 8bitcn blocks.
- All blocks should feel gamified/playful retro (copy + structure), while staying production-usable.
- Descriptions and helper text must default to
text-xsbecause the project font renders larger. - Build blocks one-by-one in iterations for review, not huge all-at-once drops.
- Hardcoded demo content is allowed for showcase blocks.
- Husky is configured for pre-commit hooks with lint-staged
- Lint-staged runs
pnpm checkon all staged files before commit - Components are registered in
registry.json- update when adding/modifying components - For 8-bit components, make changes for every style variant
- Ultracite excludes:
public/,components/ui/,hooks/use-mobile.ts,lib/utils.ts,.source/