Imported from crossplatformkorea/expo-template-cpk (
AGENTS.md). Install upstream withnpx skills add crossplatformkorea/expo-template-cpk. Copyright stays with the author.
AI Agent Instructions for expo-template-cpk
Overview
This document provides guidelines for AI agents (Claude, Gemini, etc.) working on expo-template-cpk. For detailed coding conventions, refer to CONVENTION.md.
Quick Start
Core Technologies
- Frontend: React Native with Expo Router
- UI Library: cpk-ui
- Styling: kstyled (compile-time CSS-in-JS)
- State Management: Zustand with immer
- Internationalization: i18n-js
- Package Manager: Bun
Essential Rules
- Use cpk-ui components - Typography, Button, useCPK, Icons
- Use
useCPK()for theme - NEVER useuseColorScheme() - Import assets from
src/icons.ts- Centralized asset management - Use
cssfor dynamic styles - No props in styled-components - Use Stack header - NEVER create custom headers
Project Configuration
Package Manager
This project uses Bun as the package manager.
Commands
- Install dependencies:
bun install - Run development server:
bun start - Run tests:
bun test - Run linting:
bun lint - Run type checking:
npx tsc --noEmit
Important Notes
- Always use
buninstead ofnpmoryarnfor package management - The lock file is
bun.lock(notpackage-lock.jsonoryarn.lock)
1. General Coding Guidelines
- Always use TypeScript (TSX) and ES6+ syntax
- Use explicit type definitions for function parameters and return values
- Always use named exports for utility functions
- Prefer functional components over class components
- Use
styled.Viewinstead ofViewfor wrapping components - Use
cssfromkstyledfor inline styles instead of passing props tostyled-components - Follow consistent indentation, double quotes for strings, and no semicolons
- After writing code, ALWAYS run
bun lint && npx tsc --noEmitto ensure no errors
2. File & Directory Structure
expo-template-cpk uses expo-router, which determines the structure of the project:
app/ # Page components managed by Expo Router
├── _layout.tsx # Root layout
├── index.tsx # Main entry point
└── details.tsx # Example detail page
src/ # Core logic and reusable code
├── components/ # All React reusable code
│ ├── hooks/ # Custom React hooks
│ ├── modals/ # Modal components
│ ├── providers/ # Context providers
│ └── uis/ # UI components
├── stores/ # Zustand state management
├── utils/ # Utility functions
├── icons.ts # Asset exports
├── theme.ts # Theme configuration
├── styled.d.ts # kstyled TypeScript types
└── STRINGS.ts # i18n configuration
assets/ # Static files
├── fonts/ # Custom font files
├── icons/ # Icon images
└── langs/ # i18n language files
📂 src/components/ Folder
All React reusable code is organized under src/components/:
hooks/- Custom React hooks (useDebounce, useAppState, etc.)modals/- Modal componentsproviders/- Context providers (RootProvider)uis/- UI components (ListEmptyItem, etc.)
3. CPK-UI Library
Core Rules
-
ALWAYS use cpk-ui components instead of React Native primitives
// ✅ Correct import {Typography, Button} from 'cpk-ui'; <Typography.Body1>Text</Typography.Body1> // ❌ Incorrect import {Text} from 'react-native'; <Text>Text</Text> -
ALWAYS use
useCPK()for theme, NEVERuseColorScheme()// ✅ Correct import {useCPK} from 'cpk-ui'; const {theme, themeType} = useCPK(); // ❌ Incorrect import {useColorScheme} from 'react-native'; const colorScheme = useColorScheme();
4. Theme and Styling
Theme Detection
import {useCPK} from 'cpk-ui';
const {theme, themeType, changeThemeType} = useCPK();
const isDark = themeType === 'dark';
// Access theme colors
const backgroundColor = theme.bg.basic;
const textColor = theme.text.basic;
const primaryColor = theme.role.primary;
Styling with kstyled
import {styled, css} from 'kstyled';
// Static styles - use styled
const Container = styled.View`
flex: 1;
padding: 16px;
`;
// Dynamic styles - use css
<View
style={css`
background-color: ${theme.bg.basic};
opacity: ${isActive ? 1 : 0.5};
`}
/>
Important:
- Use
cssfor dynamic styles - NO quotes in font-family inside css template literals
- For dynamic values with units, use
${variable}pxsyntax - kstyled compiles styles at build-time for zero runtime overhead
5. Navigation and Headers
Router Hook Destructuring
ALWAYS destructure methods from useRouter()
// ✅ Correct
import {useRouter} from 'expo-router';
const {push, replace, back} = useRouter();
push('/some-route');
// ❌ Incorrect
const router = useRouter();
router.push('/some-route');
Stack Navigation Headers
Use native Stack header instead of custom header implementations:
import {Stack} from 'expo-router';
export default function MyScreen(): JSX.Element {
return (
<Container>
<Stack.Screen
options={{
title: t('screen.title'),
}}
/>
{/* Content */}
</Container>
);
}
const Container = styled.View`
flex: 1;
`;
6. State Management (Zustand)
- Use Zustand for global state management
- Store files should follow the pattern:
useSomethingStore.ts - Always use the
immermiddleware for state immutability
import {create} from 'zustand';
import {immer} from 'zustand/middleware/immer';
type SomethingState = {
value: string;
setValue: (value: string) => void;
};
export const useSomethingStore = create<SomethingState>()(
immer((set) => ({
value: '',
setValue: (value) =>
set((state) => {
state.value = value;
}),
})),
);
7. Internationalization
import {t} from '../src/STRINGS';
<Typography.Body1>
{t('common.welcome')}
</Typography.Body1>
Language Files:
assets/langs/en.jsonassets/langs/ko.json
8. Asset Management
All assets (images, fonts) should be defined in src/icons.ts:
// ✅ Correct
import {IC_APP_ICON, IMG_TUTORIAL1} from '../src/icons';
// ❌ Incorrect
const icon = require('../assets/icon.png');
Naming Convention:
IC_prefix for iconsIMG_prefix for imagesFONT_prefix for fontsBG_prefix for backgrounds- Use UPPER_SNAKE_CASE
9. Component Structure
Every component should follow this structure:
/**
* @name MyComponent
*/
import {styled, css} from 'kstyled';
import {Typography, Button, useCPK} from 'cpk-ui';
type Props = {};
export default function MyComponent({}: Props): JSX.Element {
const {theme} = useCPK();
return (
<Container>
<Typography.Body1
style={css`
color: ${theme.text.basic};
`}
>
Example Text
</Typography.Body1>
</Container>
);
}
const Container = styled.View`
flex: 1;
`;
Component File Naming
- Use PascalCase for component files:
MyComponent.tsx - Use camelCase for utility files:
myUtil.ts - Use kebab-case for hook files:
use-my-hook.ts
10. Git Commit Message Guidelines
- Use the following format for commit messages:
feat: Add new featurefix: Fix a bugchore: Update dependenciesrefactor: Improve code structuredocs: Update documentationtest: Add or update tests
- Always write commit messages in present tense
Quick Reference Checklist
Before Writing Code
- Check CONVENTION.md for detailed conventions
- Use cpk-ui components (Typography, Button, useCPK)
- Use
useCPK()for theme, NOTuseColorScheme() - Import assets from
src/icons.ts
Component Checklist
- File name in PascalCase
- @name annotation at top
- Import cpk-ui components
- Use
useCPK()for theme - Use
cssfor dynamic styles - Styled components at bottom
Styling Checklist
- Use
styledfor static styles - Use
cssfor dynamic styles - No props in styled-components
- Use
${variable}pxsyntax for dynamic values with units
Documentation
- Detailed Conventions: CONVENTION.md
- Project Structure: Section 2 of this document
By following these guidelines, we ensure high-quality, maintainable code.