|
| 1 | +# GitHub Copilot Instructions for React Native Windows |
| 2 | + |
| 3 | +This file provides guidance to GitHub Copilot for contributing to the React Native Windows repository. React Native Windows brings React Native to the Windows platform, supporting both UWP and Win32 applications. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +React Native Windows is a Microsoft-maintained implementation of React Native that targets Windows platforms. The repository is a monorepo containing: |
| 8 | + |
| 9 | +- **Native Windows implementation** (C++/C#) for React Native runtime |
| 10 | +- **JavaScript/TypeScript tooling** for development experience |
| 11 | +- **Sample applications** and test suites |
| 12 | +- **Documentation** and build tools |
| 13 | + |
| 14 | +### Key Architecture Components |
| 15 | + |
| 16 | +- **Paper Architecture** (legacy): UWP XAML-based renderer |
| 17 | +- **Fabric Architecture** (new): Win32 Composition-based renderer with WinAppSDK |
| 18 | +- **Native Modules**: Platform-specific functionality exposed to JavaScript |
| 19 | +- **View Managers**: Custom UI components |
| 20 | +- **Turbo Modules**: New native module system with better performance |
| 21 | + |
| 22 | +## Repository Structure |
| 23 | + |
| 24 | +``` |
| 25 | +├── .github/ # GitHub configuration and templates |
| 26 | +├── docs/ # Documentation |
| 27 | +├── packages/ # Monorepo packages |
| 28 | +│ ├── @react-native-windows/ # Core RNW packages |
| 29 | +│ ├── @rnw-scripts/ # Build and development tools |
| 30 | +│ └── sample-apps/ # Example applications |
| 31 | +├── vnext/ # Main C++/C# implementation |
| 32 | +└── tools/ # Development utilities |
| 33 | +``` |
| 34 | + |
| 35 | +## Coding Standards and Conventions |
| 36 | + |
| 37 | +### C++ Code (.cpp, .h files) |
| 38 | + |
| 39 | +**Style Guide**: Follow the project's `.clang-format` configuration |
| 40 | +- **Line length**: 120 characters maximum |
| 41 | +- **Indentation**: 2 spaces, no tabs |
| 42 | +- **Pointer alignment**: Right-aligned (`int *ptr`, not `int* ptr`) |
| 43 | +- **Braces**: Attach style (same line as control statements) |
| 44 | +- **Naming**: |
| 45 | + - PascalCase for classes, methods, and properties |
| 46 | + - camelCase for local variables and parameters |
| 47 | + - UPPER_CASE for constants and macros |
| 48 | + |
| 49 | +```cpp |
| 50 | +// Good C++ style |
| 51 | +class WindowsTextInput : public ViewManagerBase { |
| 52 | + public: |
| 53 | + WindowsTextInput(IReactContext const &reactContext); |
| 54 | + |
| 55 | + void SetText(std::wstring const &text) { |
| 56 | + m_text = text; |
| 57 | + } |
| 58 | + |
| 59 | + private: |
| 60 | + std::wstring m_text; |
| 61 | +}; |
| 62 | +``` |
| 63 | +
|
| 64 | +**Key Patterns**: |
| 65 | +- Use `IReactContext` for accessing React Native context |
| 66 | +- Prefer `winrt::` types for Windows Runtime interop |
| 67 | +- Use `std::shared_ptr` for shared ownership |
| 68 | +- Follow RAII principles for resource management |
| 69 | +
|
| 70 | +### C# Code (.cs files) |
| 71 | +
|
| 72 | +**Style Guide**: Follow Microsoft C# conventions |
| 73 | +- **Indentation**: 4 spaces |
| 74 | +- **Line endings**: CRLF (Windows style) |
| 75 | +- **Naming**: PascalCase for public members, camelCase for private fields with underscore prefix |
| 76 | +
|
| 77 | +```csharp |
| 78 | +// Good C# style |
| 79 | +public sealed class ReactNativeModule |
| 80 | +{ |
| 81 | + private readonly IReactContext _reactContext; |
| 82 | + |
| 83 | + public ReactNativeModule(IReactContext reactContext) |
| 84 | + { |
| 85 | + _reactContext = reactContext ?? throw new ArgumentNullException("reactContext"); |
| 86 | + } |
| 87 | + |
| 88 | + [ReactMethod] |
| 89 | + public void ShowAlert(string message) |
| 90 | + { |
| 91 | + // Implementation |
| 92 | + } |
| 93 | +} |
| 94 | +``` |
| 95 | + |
| 96 | +**Key Patterns**: |
| 97 | +- Use `[ReactMethod]` attribute for methods exposed to JavaScript |
| 98 | +- Use `[ReactProperty]` for bindable properties in view managers |
| 99 | +- Prefer `sealed` classes for performance |
| 100 | +- Use nullable reference types where appropriate |
| 101 | + |
| 102 | +### TypeScript/JavaScript Code (.ts, .tsx, .js, .jsx files) |
| 103 | + |
| 104 | +**Style Guide**: Follow Prettier configuration (`.prettierrc`) |
| 105 | +- **Quotes**: Single quotes preferred |
| 106 | +- **Semicolons**: Required |
| 107 | +- **Trailing commas**: Always include |
| 108 | +- **Indentation**: 2 spaces |
| 109 | +- **Bracket spacing**: No spaces (`{foo}` not `{ foo }`) |
| 110 | + |
| 111 | +```typescript |
| 112 | +// Good TypeScript style |
| 113 | +export interface WindowsSpecificProps { |
| 114 | + acceptsKeyboardFocus?: boolean; |
| 115 | + accessibilityRole?: string; |
| 116 | +} |
| 117 | + |
| 118 | +export const WindowsButton: React.FC<WindowsSpecificProps> = ({ |
| 119 | + acceptsKeyboardFocus = true, |
| 120 | + accessibilityRole, |
| 121 | + children, |
| 122 | +}) => { |
| 123 | + return ( |
| 124 | + <Pressable |
| 125 | + acceptsKeyboardFocus={acceptsKeyboardFocus} |
| 126 | + accessibilityRole={accessibilityRole}> |
| 127 | + {children} |
| 128 | + </Pressable> |
| 129 | + ); |
| 130 | +}; |
| 131 | +``` |
| 132 | + |
| 133 | +**Key Patterns**: |
| 134 | +- Use TypeScript for type safety |
| 135 | +- Export interfaces for public APIs |
| 136 | +- Prefer functional components with hooks |
| 137 | +- Use React Native core components as base |
| 138 | + |
| 139 | +## Development Workflow |
| 140 | + |
| 141 | +### Building and Testing |
| 142 | + |
| 143 | +```bash |
| 144 | +# Install dependencies |
| 145 | +yarn install |
| 146 | + |
| 147 | +# Build all packages |
| 148 | +yarn build |
| 149 | + |
| 150 | +# Run linting |
| 151 | +yarn lint |
| 152 | + |
| 153 | +# Fix linting issues |
| 154 | +yarn lint:fix |
| 155 | + |
| 156 | +# Format C++ code |
| 157 | +yarn format |
| 158 | + |
| 159 | +# Run tests |
| 160 | +yarn test |
| 161 | +``` |
| 162 | + |
| 163 | +### Making Changes |
| 164 | + |
| 165 | +1. **Create feature branch** from main |
| 166 | +2. **Make minimal changes** following existing patterns |
| 167 | +3. **Run linting and formatting** before committing |
| 168 | +4. **Add change files** using `yarn change` for versioning |
| 169 | +5. **Test thoroughly** including relevant test suites |
| 170 | + |
| 171 | +### Required Commands for Every PR |
| 172 | + |
| 173 | +**Always run these commands after making changes in PRs:** |
| 174 | + |
| 175 | +```bash |
| 176 | +# Fix linting issues automatically |
| 177 | +yarn lint:fix |
| 178 | + |
| 179 | +# Format C++ code according to project standards |
| 180 | +yarn format |
| 181 | + |
| 182 | +# Generate change files for versioning (prerelease for development) |
| 183 | +yarn change --type prerelease |
| 184 | +``` |
| 185 | + |
| 186 | +These commands ensure code quality, consistent formatting, and proper change tracking for the monorepo versioning system. |
| 187 | + |
| 188 | +### Native Module Development |
| 189 | + |
| 190 | +**C++ Native Module Pattern**: |
| 191 | +```cpp |
| 192 | +REACT_MODULE(SampleModule) |
| 193 | +struct SampleModule { |
| 194 | + REACT_INIT(Initialize) |
| 195 | + void Initialize(React::ReactContext const &reactContext) noexcept; |
| 196 | + |
| 197 | + REACT_METHOD(GetDeviceName) |
| 198 | + void GetDeviceName(React::ReactPromise<std::string> promise) noexcept; |
| 199 | + |
| 200 | + REACT_EVENT(OnDataReceived) |
| 201 | + std::function<void(std::string)> OnDataReceived; |
| 202 | +}; |
| 203 | +``` |
| 204 | +
|
| 205 | +**C# Native Module Pattern**: |
| 206 | +```csharp |
| 207 | +[ReactModule] |
| 208 | +public sealed class SampleModule |
| 209 | +{ |
| 210 | + [ReactMethod] |
| 211 | + public void GetDeviceName(IReactPromise<string> promise) |
| 212 | + { |
| 213 | + promise.Resolve(Environment.MachineName); |
| 214 | + } |
| 215 | + |
| 216 | + [ReactEvent] |
| 217 | + public Action<string> OnDataReceived { get; set; } |
| 218 | +} |
| 219 | +``` |
| 220 | + |
| 221 | +### View Manager Development |
| 222 | + |
| 223 | +**C++ View Manager Pattern**: |
| 224 | +```cpp |
| 225 | +class SampleViewManager : public ViewManagerBase { |
| 226 | + public: |
| 227 | + SampleViewManager(IReactContext const &reactContext); |
| 228 | + |
| 229 | + const char *GetName() const override; |
| 230 | + winrt::FrameworkElement CreateView() noexcept override; |
| 231 | + |
| 232 | + void GetNativeProps(NativePropsBuilder const &builder) const override; |
| 233 | + void UpdateProperties(ShadowNodeBase const &shadowNode, winrt::FrameworkElement const &view) override; |
| 234 | +}; |
| 235 | +``` |
| 236 | +
|
| 237 | +## Common Patterns and Best Practices |
| 238 | +
|
| 239 | +### Error Handling |
| 240 | +- Use `React::ReactPromise` for async operations that can fail |
| 241 | +- Throw `React::ReactError` for immediate failures |
| 242 | +- Log errors using `IReactContext::LogError()` |
| 243 | +
|
| 244 | +### Memory Management |
| 245 | +- Use RAII and smart pointers in C++ |
| 246 | +- Avoid circular references between C++ and JavaScript |
| 247 | +- Dispose of resources in component unmount/cleanup |
| 248 | +
|
| 249 | +### Performance Considerations |
| 250 | +- Minimize cross-thread marshaling |
| 251 | +- Use batch updates for multiple property changes |
| 252 | +- Prefer native UI thread for UI operations |
| 253 | +- Cache expensive computations |
| 254 | +
|
| 255 | +### Testing |
| 256 | +- Write unit tests for business logic |
| 257 | +- Use integration tests for React Native bridge interactions |
| 258 | +- Include accessibility testing |
| 259 | +- Test on both UWP and Win32 targets when applicable |
| 260 | +
|
| 261 | +## Technology-Specific Guidelines |
| 262 | +
|
| 263 | +### Windows Runtime (WinRT) Interop |
| 264 | +- Use `winrt::` namespace for Windows Runtime types |
| 265 | +- Handle exceptions from WinRT APIs appropriately |
| 266 | +- Use `co_await` for async WinRT operations |
| 267 | +
|
| 268 | +### XAML Integration |
| 269 | +- Follow XAML naming conventions for dependency properties |
| 270 | +- Use data binding where appropriate |
| 271 | +- Handle XAML events on UI thread |
| 272 | +
|
| 273 | +### Win32 Integration |
| 274 | +- Use Windows App SDK APIs for modern Win32 features |
| 275 | +- Handle Win32 messages appropriately |
| 276 | +- Consider DPI awareness for UI elements |
| 277 | +
|
| 278 | +## File Organization |
| 279 | +
|
| 280 | +- **Source files**: Place in appropriate package under `packages/` or `vnext/` |
| 281 | +- **Tests**: Co-locate with source or in dedicated test directories |
| 282 | +- **Documentation**: Add to `docs/` for public APIs |
| 283 | +- **Examples**: Include in sample applications when relevant |
| 284 | +
|
| 285 | +## Comments and Documentation |
| 286 | +
|
| 287 | +- Use JSDoc for TypeScript/JavaScript APIs |
| 288 | +- Document public C++ APIs with doxygen-style comments |
| 289 | +- Include usage examples for complex APIs |
| 290 | +- Explain Windows-specific behavior differences |
| 291 | +
|
| 292 | +This guidance helps ensure consistent, high-quality contributions to React Native Windows while leveraging platform-specific capabilities effectively. |
0 commit comments