Cross-Platform Development
Patterns for writing platform-specific code in OneKey.
Platform Extensions
Use platform extensions for platform-specific implementations:
| Extension |
Platform |
.native.ts |
React Native (iOS/Android) |
.web.ts |
Web platform |
.desktop.ts |
Desktop (Electron) |
.ext.ts |
Browser extension |
Platform Detection
ALWAYS use platformEnv for platform detection:
// ✅ CORRECT
import platformEnv from '@onekeyhq/shared/src/platformEnv';
if (platformEnv.isNative) {
// React Native specific code
}
if (platformEnv.isWeb) {
// Web specific code
}
if (platformEnv.isDesktop) {
// Desktop (Electron) specific code
}
if (platformEnv.isExtension) {
// Browser extension specific code
}
// ❌ FORBIDDEN - Direct platform checks
if (typeof window !== 'undefined') { }
if (process.env.REACT_APP_PLATFORM === 'web') { }
Available Platform Flags
platformEnv.isNative // React Native (iOS or Android)
platformEnv.isWeb // Web browser
platformEnv.isDesktop // Electron desktop app
platformEnv.isExtension // Browser extension
platformEnv.isIOS // iOS specifically
platformEnv.isAndroid // Android specifically
platformEnv.isWebEmbed // Embedded web components
Platform-Specific File Structure
MyComponent/
├── index.ts # Main entry, common logic
├── MyComponent.tsx # Shared component
├── MyComponent.native.tsx # React Native specific
├── MyComponent.web.tsx # Web specific
├── MyComponent.desktop.tsx # Desktop specific
└── MyComponent.ext.tsx # Extension specific
The bundler automatically resolves the correct file based on platform.
Example: Platform-Specific Storage
// storage.ts - shared interface
export interface IStorage {
get(key: string): Promise<string | null>;
set(key: string, value: string): Promise<void>;
}
// storage.native.ts
import AsyncStorage from '@react-native-async-storage/async-storage';
export const storage: IStorage = {
get: (key) => AsyncStorage.getItem(key),
set: (key, value) => AsyncStorage.setItem(key, value),
};
// storage.web.ts
export const storage: IStorage = {
get: async (key) => localStorage.getItem(key),
set: async (key, value) => localStorage.setItem(key, value),
};
// storage.desktop.ts
import { ipcRenderer } from 'electron';
export const storage: IStorage = {
get: (key) => ipcRenderer.invoke('storage:get', key),
set: (key, value) => ipcRenderer.invoke('storage:set', key, value),
};
Detailed Guide
For comprehensive cross-platform patterns and platform considerations, see cross-platform.md.
Topics covered:
- Platform extensions and file structure
- Platform detection with
platformEnv
- Platform-specific imports
- Platform considerations (Extension, Mobile, Desktop, Web)
- Real-world examples
- Cross-platform checklist
Platform Considerations
Extension (Chrome, Firefox, Edge, Brave)
- MV3/service worker lifetimes, permissions, CSP, background script limitations
Mobile (iOS/Android)
- WebView limitations, native modules, background/foreground states, deep linking
Desktop (Electron)
- Security boundaries, IPC communication, file system access
Web
- CORS restrictions, storage limitations, XSS prevention, bundle size
Checklist
Related Skills
/1k-coding-patterns - General coding patterns
/1k-architecture - Project structure and imports
1---2name: 1k-cross-platform3description: Cross-platform development patterns for OneKey. Use when writing platform-specific code, handling platform differences, or working with native/web/desktop/extension platforms. Triggers on platform, native, web, desktop, extension, iOS, Android, Electron, platformEnv, .native.ts, .web.ts, .desktop.ts, .ext.ts, cross-platform, multi-platform.4---56# Cross-Platform Development78Patterns for writing platform-specific code in OneKey.910## Platform Extensions1112Use platform extensions for platform-specific implementations:1314| Extension | Platform |15|-----------|----------|16| `.native.ts` | React Native (iOS/Android) |17| `.web.ts` | Web platform |18| `.desktop.ts` | Desktop (Electron) |19| `.ext.ts` | Browser extension |2021## Platform Detection2223**ALWAYS use `platformEnv` for platform detection:**2425```typescript26// ✅ CORRECT27import platformEnv from '@onekeyhq/shared/src/platformEnv';2829if (platformEnv.isNative) {30 // React Native specific code31}3233if (platformEnv.isWeb) {34 // Web specific code35}3637if (platformEnv.isDesktop) {38 // Desktop (Electron) specific code39}4041if (platformEnv.isExtension) {42 // Browser extension specific code43}4445// ❌ FORBIDDEN - Direct platform checks46if (typeof window !== 'undefined') { }47if (process.env.REACT_APP_PLATFORM === 'web') { }48```4950## Available Platform Flags5152```typescript53platformEnv.isNative // React Native (iOS or Android)54platformEnv.isWeb // Web browser55platformEnv.isDesktop // Electron desktop app56platformEnv.isExtension // Browser extension57platformEnv.isIOS // iOS specifically58platformEnv.isAndroid // Android specifically59platformEnv.isWebEmbed // Embedded web components60```6162## Platform-Specific File Structure6364```65MyComponent/66├── index.ts # Main entry, common logic67├── MyComponent.tsx # Shared component68├── MyComponent.native.tsx # React Native specific69├── MyComponent.web.tsx # Web specific70├── MyComponent.desktop.tsx # Desktop specific71└── MyComponent.ext.tsx # Extension specific72```7374The bundler automatically resolves the correct file based on platform.7576## Example: Platform-Specific Storage7778```typescript79// storage.ts - shared interface80export interface IStorage {81 get(key: string): Promise<string | null>;82 set(key: string, value: string): Promise<void>;83}8485// storage.native.ts86import AsyncStorage from '@react-native-async-storage/async-storage';8788export const storage: IStorage = {89 get: (key) => AsyncStorage.getItem(key),90 set: (key, value) => AsyncStorage.setItem(key, value),91};9293// storage.web.ts94export const storage: IStorage = {95 get: async (key) => localStorage.getItem(key),96 set: async (key, value) => localStorage.setItem(key, value),97};9899// storage.desktop.ts100import { ipcRenderer } from 'electron';101102export const storage: IStorage = {103 get: (key) => ipcRenderer.invoke('storage:get', key),104 set: (key, value) => ipcRenderer.invoke('storage:set', key, value),105};106```107108## Detailed Guide109110For comprehensive cross-platform patterns and platform considerations, see [cross-platform.md](references/rules/cross-platform.md).111112Topics covered:113- Platform extensions and file structure114- Platform detection with `platformEnv`115- Platform-specific imports116- Platform considerations (Extension, Mobile, Desktop, Web)117- Real-world examples118- Cross-platform checklist119120## Platform Considerations121122### Extension (Chrome, Firefox, Edge, Brave)123- MV3/service worker lifetimes, permissions, CSP, background script limitations124125### Mobile (iOS/Android)126- WebView limitations, native modules, background/foreground states, deep linking127128### Desktop (Electron)129- Security boundaries, IPC communication, file system access130131### Web132- CORS restrictions, storage limitations, XSS prevention, bundle size133134## Checklist135136- [ ] Platform-specific code uses correct file extension137- [ ] Uses `platformEnv` instead of direct checks138- [ ] Common logic extracted to shared files139- [ ] Tested on all target platforms140141## Related Skills142143- `/1k-coding-patterns` - General coding patterns144- `/1k-architecture` - Project structure and imports