[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6CC1F7HJAT7VM6GSWPMJGPF":3,"skill-same:01M6CC1F7HJAT7VM6GSWPMJGPF":54},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":27,"linkOnly":28,"markdownContent":29,"markdownBody":30,"frontMatter":31,"refName":33,"commitSha":34,"skillDirectory":35,"forksCount":14,"repositoryHtmlUrl":36,"repositoryHomepageUrl":6,"ownerHtmlUrl":37,"ownerBlogUrl":38,"ownerDescription":6,"updatedAt":39,"install":40,"resources":53},"01M6CC1F7HJAT7VM6GSWPMJGPF","use-dom",null,"Use Expo DOM components to run web code in a webview on native and as-is on web. Migrate web code to native incrementally.","epiphanyapps\u002Fmapyourhealth","epiphanyapps","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F7298208?v=4","01M6CBX8TV8415WB6ZC8SGRVKZ","Epiphany Apps LLC","01M6CBX8ZBWZX3B8YENG80VSHK",0,"MIT","https:\u002F\u002Fgithub.com\u002Fepiphanyapps\u002Fmapyourhealth\u002Fblob\u002Fmain\u002Fapps\u002Fmobile\u002F.agents\u002Fskills\u002Fuse-dom\u002FSKILL.md",[],[19,20,21,22,23,24,25,26],"use dom","use","web","components","run","code","migrate","expo","2026-11-10 10:12:30",false,"---\nname: use-dom\ndescription: Use Expo DOM components to run web code in a webview on native and as-is on web. Migrate web code to native incrementally.\nversion: 1.0.0\nlicense: MIT\n---\n\n## What are DOM Components?\n\nDOM components allow web code to run verbatim in a webview on native platforms while rendering as-is on web. This enables using web-only libraries like `recharts`, `react-syntax-highlighter`, or any React web library in your Expo app without modification.\n\n## When to Use DOM Components\n\nUse DOM components when you need:\n\n- **Web-only libraries** — Charts (recharts, chart.js), syntax highlighters, rich text editors, or any library that depends on DOM APIs\n- **Migrating web code** — Bring existing React web components to native without rewriting\n- **Complex HTML\u002FCSS layouts** — When CSS features aren't available in React Native\n- **iframes or embeds** — Embedding external content that requires a browser context\n- **Canvas or WebGL** — Web graphics APIs not available natively\n\n## When NOT to Use DOM Components\n\nAvoid DOM components when:\n\n- **Native performance is critical** — Webviews add overhead\n- **Simple UI** — React Native components are more efficient for basic layouts\n- **Deep native integration** — Use local modules instead for native APIs\n- **Layout routes** — `_layout` files cannot be DOM components\n\n## Basic DOM Component\n\nCreate a new file with the `'use dom';` directive at the top:\n\n```tsx\n\u002F\u002F components\u002FWebChart.tsx\n\"use dom\";\n\nexport default function WebChart({\n  data,\n}: {\n  data: number[];\n  dom: import(\"expo\u002Fdom\").DOMProps;\n}) {\n  return (\n    \u003Cdiv style={{ padding: 20 }}>\n      \u003Ch2>Chart Data\u003C\u002Fh2>\n      \u003Cul>\n        {data.map((value, i) => (\n          \u003Cli key={i}>{value}\u003C\u002Fli>\n        ))}\n      \u003C\u002Ful>\n    \u003C\u002Fdiv>\n  );\n}\n```\n\n## Rules for DOM Components\n\n1. **Must have `'use dom';` directive** at the top of the file\n2. **Single default export** — One React component per file\n3. **Own file** — Cannot be defined inline or combined with native components\n4. **Serializable props only** — Strings, numbers, booleans, arrays, plain objects\n5. **Include CSS in the component file** — DOM components run in isolated context\n\n## The `dom` Prop\n\nEvery DOM component receives a special `dom` prop for webview configuration. Always type it in your props:\n\n```tsx\n\"use dom\";\n\ninterface Props {\n  content: string;\n  dom: import(\"expo\u002Fdom\").DOMProps;\n}\n\nexport default function MyComponent({ content }: Props) {\n  return \u003Cdiv>{content}\u003C\u002Fdiv>;\n}\n```\n\n### Common `dom` Prop Options\n\n```tsx\n\u002F\u002F Disable body scrolling\n\u003CDOMComponent dom={{ scrollEnabled: false }} \u002F>\n\n\u002F\u002F Flow under the notch (disable safe area insets)\n\u003CDOMComponent dom={{ contentInsetAdjustmentBehavior: \"never\" }} \u002F>\n\n\u002F\u002F Control size manually\n\u003CDOMComponent dom={{ style: { width: 300, height: 400 } }} \u002F>\n\n\u002F\u002F Combine options\n\u003CDOMComponent\n  dom={{\n    scrollEnabled: false,\n    contentInsetAdjustmentBehavior: \"never\",\n    style: { width: '100%', height: 500 }\n  }}\n\u002F>\n```\n\n## Exposing Native Actions to the Webview\n\nPass async functions as props to expose native functionality to the DOM component:\n\n```tsx\n\u002F\u002F app\u002Findex.tsx (native)\nimport { Alert } from \"react-native\";\nimport DOMComponent from \"@\u002Fcomponents\u002Fdom-component\";\n\nexport default function Screen() {\n  return (\n    \u003CDOMComponent\n      showAlert={async (message: string) => {\n        Alert.alert(\"From Web\", message);\n      }}\n      saveData={async (data: { name: string; value: number }) => {\n        \u002F\u002F Save to native storage, database, etc.\n        console.log(\"Saving:\", data);\n        return { success: true };\n      }}\n    \u002F>\n  );\n}\n```\n\n```tsx\n\u002F\u002F components\u002Fdom-component.tsx\n\"use dom\";\n\ninterface Props {\n  showAlert: (message: string) => Promise\u003Cvoid>;\n  saveData: (data: {\n    name: string;\n    value: number;\n  }) => Promise\u003C{ success: boolean }>;\n  dom?: import(\"expo\u002Fdom\").DOMProps;\n}\n\nexport default function DOMComponent({ showAlert, saveData }: Props) {\n  const handleClick = async () => {\n    await showAlert(\"Hello from the webview!\");\n    const result = await saveData({ name: \"test\", value: 42 });\n    console.log(\"Save result:\", result);\n  };\n\n  return \u003Cbutton onClick={handleClick}>Trigger Native Action\u003C\u002Fbutton>;\n}\n```\n\n## Using Web Libraries\n\nDOM components can use any web library:\n\n```tsx\n\u002F\u002F components\u002Fsyntax-highlight.tsx\n\"use dom\";\n\nimport SyntaxHighlighter from \"react-syntax-highlighter\";\nimport { docco } from \"react-syntax-highlighter\u002Fdist\u002Fesm\u002Fstyles\u002Fhljs\";\n\ninterface Props {\n  code: string;\n  language: string;\n  dom?: import(\"expo\u002Fdom\").DOMProps;\n}\n\nexport default function SyntaxHighlight({ code, language }: Props) {\n  return (\n    \u003CSyntaxHighlighter language={language} style={docco}>\n      {code}\n    \u003C\u002FSyntaxHighlighter>\n  );\n}\n```\n\n```tsx\n\u002F\u002F components\u002Fchart.tsx\n\"use dom\";\n\nimport {\n  LineChart,\n  Line,\n  XAxis,\n  YAxis,\n  CartesianGrid,\n  Tooltip,\n} from \"recharts\";\n\ninterface Props {\n  data: Array\u003C{ name: string; value: number }>;\n  dom: import(\"expo\u002Fdom\").DOMProps;\n}\n\nexport default function Chart({ data }: Props) {\n  return (\n    \u003CLineChart width={400} height={300} data={data}>\n      \u003CCartesianGrid strokeDasharray=\"3 3\" \u002F>\n      \u003CXAxis dataKey=\"name\" \u002F>\n      \u003CYAxis \u002F>\n      \u003CTooltip \u002F>\n      \u003CLine type=\"monotone\" dataKey=\"value\" stroke=\"#8884d8\" \u002F>\n    \u003C\u002FLineChart>\n  );\n}\n```\n\n## CSS in DOM Components\n\nCSS imports must be in the DOM component file since they run in isolated context:\n\n```tsx\n\u002F\u002F components\u002Fstyled-component.tsx\n\"use dom\";\n\nimport \"@\u002Fstyles.css\"; \u002F\u002F CSS file in same directory\n\nexport default function StyledComponent({\n  dom,\n}: {\n  dom: import(\"expo\u002Fdom\").DOMProps;\n}) {\n  return (\n    \u003Cdiv className=\"container\">\n      \u003Ch1 className=\"title\">Styled Content\u003C\u002Fh1>\n    \u003C\u002Fdiv>\n  );\n}\n```\n\nOr use inline styles \u002F CSS-in-JS:\n\n```tsx\n\"use dom\";\n\nconst styles = {\n  container: {\n    padding: 20,\n    backgroundColor: \"#f0f0f0\",\n  },\n  title: {\n    fontSize: 24,\n    color: \"#333\",\n  },\n};\n\nexport default function StyledComponent({\n  dom,\n}: {\n  dom: import(\"expo\u002Fdom\").DOMProps;\n}) {\n  return (\n    \u003Cdiv style={styles.container}>\n      \u003Ch1 style={styles.title}>Styled Content\u003C\u002Fh1>\n    \u003C\u002Fdiv>\n  );\n}\n```\n\n## Expo Router in DOM Components\n\nThe expo-router `\u003CLink \u002F>` component and router API work inside DOM components:\n\n```tsx\n\"use dom\";\n\nimport { Link, useRouter } from \"expo-router\";\n\nexport default function Navigation({\n  dom,\n}: {\n  dom: import(\"expo\u002Fdom\").DOMProps;\n}) {\n  const router = useRouter();\n\n  return (\n    \u003Cnav>\n      \u003CLink href=\"\u002Fabout\">About\u003C\u002FLink>\n      \u003Cbutton onClick={() => router.push(\"\u002Fsettings\")}>Settings\u003C\u002Fbutton>\n    \u003C\u002Fnav>\n  );\n}\n```\n\n### Router APIs That Require Props\n\nThese hooks don't work directly in DOM components because they need synchronous access to native routing state:\n\n- `useLocalSearchParams()`\n- `useGlobalSearchParams()`\n- `usePathname()`\n- `useSegments()`\n- `useRootNavigation()`\n- `useRootNavigationState()`\n\n**Solution:** Read these values in the native parent and pass as props:\n\n```tsx\n\u002F\u002F app\u002F[id].tsx (native)\nimport { useLocalSearchParams, usePathname } from \"expo-router\";\nimport DOMComponent from \"@\u002Fcomponents\u002Fdom-component\";\n\nexport default function Screen() {\n  const { id } = useLocalSearchParams();\n  const pathname = usePathname();\n\n  return \u003CDOMComponent id={id as string} pathname={pathname} \u002F>;\n}\n```\n\n```tsx\n\u002F\u002F components\u002Fdom-component.tsx\n\"use dom\";\n\ninterface Props {\n  id: string;\n  pathname: string;\n  dom?: import(\"expo\u002Fdom\").DOMProps;\n}\n\nexport default function DOMComponent({ id, pathname }: Props) {\n  return (\n    \u003Cdiv>\n      \u003Cp>Current ID: {id}\u003C\u002Fp>\n      \u003Cp>Current Path: {pathname}\u003C\u002Fp>\n    \u003C\u002Fdiv>\n  );\n}\n```\n\n## Detecting DOM Environment\n\nCheck if code is running in a DOM component:\n\n```tsx\n\"use dom\";\n\nimport { IS_DOM } from \"expo\u002Fdom\";\n\nexport default function Component({\n  dom,\n}: {\n  dom?: import(\"expo\u002Fdom\").DOMProps;\n}) {\n  return \u003Cdiv>{IS_DOM ? \"Running in DOM component\" : \"Running natively\"}\u003C\u002Fdiv>;\n}\n```\n\n## Assets\n\nPrefer requiring assets instead of using the public directory:\n\n```tsx\n\"use dom\";\n\n\u002F\u002F Good - bundled with the component\nconst logo = require(\"..\u002Fassets\u002Flogo.png\");\n\nexport default function Component({\n  dom,\n}: {\n  dom: import(\"expo\u002Fdom\").DOMProps;\n}) {\n  return \u003Cimg src={logo} alt=\"Logo\" \u002F>;\n}\n```\n\n## Usage from Native Components\n\nImport and use DOM components like regular components:\n\n```tsx\n\u002F\u002F app\u002Findex.tsx\nimport { View, Text } from \"react-native\";\nimport WebChart from \"@\u002Fcomponents\u002Fweb-chart\";\nimport CodeBlock from \"@\u002Fcomponents\u002Fcode-block\";\n\nexport default function HomeScreen() {\n  return (\n    \u003CView style={{ flex: 1 }}>\n      \u003CText>Native content above\u003C\u002FText>\n\n      \u003CWebChart data={[10, 20, 30, 40, 50]} dom={{ style: { height: 300 } }} \u002F>\n\n      \u003CCodeBlock\n        code=\"const x = 1;\"\n        language=\"javascript\"\n        dom={{ scrollEnabled: true }}\n      \u002F>\n\n      \u003CText>Native content below\u003C\u002FText>\n    \u003C\u002FView>\n  );\n}\n```\n\n## Platform Behavior\n\n| Platform | Behavior                            |\n| -------- | ----------------------------------- |\n| iOS      | Rendered in WKWebView               |\n| Android  | Rendered in WebView                 |\n| Web      | Rendered as-is (no webview wrapper) |\n\nOn web, the `dom` prop is ignored since no webview is needed.\n\n## Tips\n\n- DOM components hot reload during development\n- Keep DOM components focused — don't put entire screens in webviews\n- Use native components for navigation chrome, DOM components for specialized content\n- Test on all platforms — web rendering may differ slightly from native webviews\n- Large DOM components may impact performance — profile if needed\n- The webview has its own JavaScript context — cannot directly share state with native\n","## What are DOM Components?\n\nDOM components allow web code to run verbatim in a webview on native platforms while rendering as-is on web. This enables using web-only libraries like `recharts`, `react-syntax-highlighter`, or any React web library in your Expo app without modification.\n\n## When to Use DOM Components\n\nUse DOM components when you need:\n\n- **Web-only libraries** — Charts (recharts, chart.js), syntax highlighters, rich text editors, or any library that depends on DOM APIs\n- **Migrating web code** — Bring existing React web components to native without rewriting\n- **Complex HTML\u002FCSS layouts** — When CSS features aren't available in React Native\n- **iframes or embeds** — Embedding external content that requires a browser context\n- **Canvas or WebGL** — Web graphics APIs not available natively\n\n## When NOT to Use DOM Components\n\nAvoid DOM components when:\n\n- **Native performance is critical** — Webviews add overhead\n- **Simple UI** — React Native components are more efficient for basic layouts\n- **Deep native integration** — Use local modules instead for native APIs\n- **Layout routes** — `_layout` files cannot be DOM components\n\n## Basic DOM Component\n\nCreate a new file with the `'use dom';` directive at the top:\n\n```tsx\n\u002F\u002F components\u002FWebChart.tsx\n\"use dom\";\n\nexport default function WebChart({\n  data,\n}: {\n  data: number[];\n  dom: import(\"expo\u002Fdom\").DOMProps;\n}) {\n  return (\n    \u003Cdiv style={{ padding: 20 }}>\n      \u003Ch2>Chart Data\u003C\u002Fh2>\n      \u003Cul>\n        {data.map((value, i) => (\n          \u003Cli key={i}>{value}\u003C\u002Fli>\n        ))}\n      \u003C\u002Ful>\n    \u003C\u002Fdiv>\n  );\n}\n```\n\n## Rules for DOM Components\n\n1. **Must have `'use dom';` directive** at the top of the file\n2. **Single default export** — One React component per file\n3. **Own file** — Cannot be defined inline or combined with native components\n4. **Serializable props only** — Strings, numbers, booleans, arrays, plain objects\n5. **Include CSS in the component file** — DOM components run in isolated context\n\n## The `dom` Prop\n\nEvery DOM component receives a special `dom` prop for webview configuration. Always type it in your props:\n\n```tsx\n\"use dom\";\n\ninterface Props {\n  content: string;\n  dom: import(\"expo\u002Fdom\").DOMProps;\n}\n\nexport default function MyComponent({ content }: Props) {\n  return \u003Cdiv>{content}\u003C\u002Fdiv>;\n}\n```\n\n### Common `dom` Prop Options\n\n```tsx\n\u002F\u002F Disable body scrolling\n\u003CDOMComponent dom={{ scrollEnabled: false }} \u002F>\n\n\u002F\u002F Flow under the notch (disable safe area insets)\n\u003CDOMComponent dom={{ contentInsetAdjustmentBehavior: \"never\" }} \u002F>\n\n\u002F\u002F Control size manually\n\u003CDOMComponent dom={{ style: { width: 300, height: 400 } }} \u002F>\n\n\u002F\u002F Combine options\n\u003CDOMComponent\n  dom={{\n    scrollEnabled: false,\n    contentInsetAdjustmentBehavior: \"never\",\n    style: { width: '100%', height: 500 }\n  }}\n\u002F>\n```\n\n## Exposing Native Actions to the Webview\n\nPass async functions as props to expose native functionality to the DOM component:\n\n```tsx\n\u002F\u002F app\u002Findex.tsx (native)\nimport { Alert } from \"react-native\";\nimport DOMComponent from \"@\u002Fcomponents\u002Fdom-component\";\n\nexport default function Screen() {\n  return (\n    \u003CDOMComponent\n      showAlert={async (message: string) => {\n        Alert.alert(\"From Web\", message);\n      }}\n      saveData={async (data: { name: string; value: number }) => {\n        \u002F\u002F Save to native storage, database, etc.\n        console.log(\"Saving:\", data);\n        return { success: true };\n      }}\n    \u002F>\n  );\n}\n```\n\n```tsx\n\u002F\u002F components\u002Fdom-component.tsx\n\"use dom\";\n\ninterface Props {\n  showAlert: (message: string) => Promise\u003Cvoid>;\n  saveData: (data: {\n    name: string;\n    value: number;\n  }) => Promise\u003C{ success: boolean }>;\n  dom?: import(\"expo\u002Fdom\").DOMProps;\n}\n\nexport default function DOMComponent({ showAlert, saveData }: Props) {\n  const handleClick = async () => {\n    await showAlert(\"Hello from the webview!\");\n    const result = await saveData({ name: \"test\", value: 42 });\n    console.log(\"Save result:\", result);\n  };\n\n  return \u003Cbutton onClick={handleClick}>Trigger Native Action\u003C\u002Fbutton>;\n}\n```\n\n## Using Web Libraries\n\nDOM components can use any web library:\n\n```tsx\n\u002F\u002F components\u002Fsyntax-highlight.tsx\n\"use dom\";\n\nimport SyntaxHighlighter from \"react-syntax-highlighter\";\nimport { docco } from \"react-syntax-highlighter\u002Fdist\u002Fesm\u002Fstyles\u002Fhljs\";\n\ninterface Props {\n  code: string;\n  language: string;\n  dom?: import(\"expo\u002Fdom\").DOMProps;\n}\n\nexport default function SyntaxHighlight({ code, language }: Props) {\n  return (\n    \u003CSyntaxHighlighter language={language} style={docco}>\n      {code}\n    \u003C\u002FSyntaxHighlighter>\n  );\n}\n```\n\n```tsx\n\u002F\u002F components\u002Fchart.tsx\n\"use dom\";\n\nimport {\n  LineChart,\n  Line,\n  XAxis,\n  YAxis,\n  CartesianGrid,\n  Tooltip,\n} from \"recharts\";\n\ninterface Props {\n  data: Array\u003C{ name: string; value: number }>;\n  dom: import(\"expo\u002Fdom\").DOMProps;\n}\n\nexport default function Chart({ data }: Props) {\n  return (\n    \u003CLineChart width={400} height={300} data={data}>\n      \u003CCartesianGrid strokeDasharray=\"3 3\" \u002F>\n      \u003CXAxis dataKey=\"name\" \u002F>\n      \u003CYAxis \u002F>\n      \u003CTooltip \u002F>\n      \u003CLine type=\"monotone\" dataKey=\"value\" stroke=\"#8884d8\" \u002F>\n    \u003C\u002FLineChart>\n  );\n}\n```\n\n## CSS in DOM Components\n\nCSS imports must be in the DOM component file since they run in isolated context:\n\n```tsx\n\u002F\u002F components\u002Fstyled-component.tsx\n\"use dom\";\n\nimport \"@\u002Fstyles.css\"; \u002F\u002F CSS file in same directory\n\nexport default function StyledComponent({\n  dom,\n}: {\n  dom: import(\"expo\u002Fdom\").DOMProps;\n}) {\n  return (\n    \u003Cdiv className=\"container\">\n      \u003Ch1 className=\"title\">Styled Content\u003C\u002Fh1>\n    \u003C\u002Fdiv>\n  );\n}\n```\n\nOr use inline styles \u002F CSS-in-JS:\n\n```tsx\n\"use dom\";\n\nconst styles = {\n  container: {\n    padding: 20,\n    backgroundColor: \"#f0f0f0\",\n  },\n  title: {\n    fontSize: 24,\n    color: \"#333\",\n  },\n};\n\nexport default function StyledComponent({\n  dom,\n}: {\n  dom: import(\"expo\u002Fdom\").DOMProps;\n}) {\n  return (\n    \u003Cdiv style={styles.container}>\n      \u003Ch1 style={styles.title}>Styled Content\u003C\u002Fh1>\n    \u003C\u002Fdiv>\n  );\n}\n```\n\n## Expo Router in DOM Components\n\nThe expo-router `\u003CLink \u002F>` component and router API work inside DOM components:\n\n```tsx\n\"use dom\";\n\nimport { Link, useRouter } from \"expo-router\";\n\nexport default function Navigation({\n  dom,\n}: {\n  dom: import(\"expo\u002Fdom\").DOMProps;\n}) {\n  const router = useRouter();\n\n  return (\n    \u003Cnav>\n      \u003CLink href=\"\u002Fabout\">About\u003C\u002FLink>\n      \u003Cbutton onClick={() => router.push(\"\u002Fsettings\")}>Settings\u003C\u002Fbutton>\n    \u003C\u002Fnav>\n  );\n}\n```\n\n### Router APIs That Require Props\n\nThese hooks don't work directly in DOM components because they need synchronous access to native routing state:\n\n- `useLocalSearchParams()`\n- `useGlobalSearchParams()`\n- `usePathname()`\n- `useSegments()`\n- `useRootNavigation()`\n- `useRootNavigationState()`\n\n**Solution:** Read these values in the native parent and pass as props:\n\n```tsx\n\u002F\u002F app\u002F[id].tsx (native)\nimport { useLocalSearchParams, usePathname } from \"expo-router\";\nimport DOMComponent from \"@\u002Fcomponents\u002Fdom-component\";\n\nexport default function Screen() {\n  const { id } = useLocalSearchParams();\n  const pathname = usePathname();\n\n  return \u003CDOMComponent id={id as string} pathname={pathname} \u002F>;\n}\n```\n\n```tsx\n\u002F\u002F components\u002Fdom-component.tsx\n\"use dom\";\n\ninterface Props {\n  id: string;\n  pathname: string;\n  dom?: import(\"expo\u002Fdom\").DOMProps;\n}\n\nexport default function DOMComponent({ id, pathname }: Props) {\n  return (\n    \u003Cdiv>\n      \u003Cp>Current ID: {id}\u003C\u002Fp>\n      \u003Cp>Current Path: {pathname}\u003C\u002Fp>\n    \u003C\u002Fdiv>\n  );\n}\n```\n\n## Detecting DOM Environment\n\nCheck if code is running in a DOM component:\n\n```tsx\n\"use dom\";\n\nimport { IS_DOM } from \"expo\u002Fdom\";\n\nexport default function Component({\n  dom,\n}: {\n  dom?: import(\"expo\u002Fdom\").DOMProps;\n}) {\n  return \u003Cdiv>{IS_DOM ? \"Running in DOM component\" : \"Running natively\"}\u003C\u002Fdiv>;\n}\n```\n\n## Assets\n\nPrefer requiring assets instead of using the public directory:\n\n```tsx\n\"use dom\";\n\n\u002F\u002F Good - bundled with the component\nconst logo = require(\"..\u002Fassets\u002Flogo.png\");\n\nexport default function Component({\n  dom,\n}: {\n  dom: import(\"expo\u002Fdom\").DOMProps;\n}) {\n  return \u003Cimg src={logo} alt=\"Logo\" \u002F>;\n}\n```\n\n## Usage from Native Components\n\nImport and use DOM components like regular components:\n\n```tsx\n\u002F\u002F app\u002Findex.tsx\nimport { View, Text } from \"react-native\";\nimport WebChart from \"@\u002Fcomponents\u002Fweb-chart\";\nimport CodeBlock from \"@\u002Fcomponents\u002Fcode-block\";\n\nexport default function HomeScreen() {\n  return (\n    \u003CView style={{ flex: 1 }}>\n      \u003CText>Native content above\u003C\u002FText>\n\n      \u003CWebChart data={[10, 20, 30, 40, 50]} dom={{ style: { height: 300 } }} \u002F>\n\n      \u003CCodeBlock\n        code=\"const x = 1;\"\n        language=\"javascript\"\n        dom={{ scrollEnabled: true }}\n      \u002F>\n\n      \u003CText>Native content below\u003C\u002FText>\n    \u003C\u002FView>\n  );\n}\n```\n\n## Platform Behavior\n\n| Platform | Behavior                            |\n| -------- | ----------------------------------- |\n| iOS      | Rendered in WKWebView               |\n| Android  | Rendered in WebView                 |\n| Web      | Rendered as-is (no webview wrapper) |\n\nOn web, the `dom` prop is ignored since no webview is needed.\n\n## Tips\n\n- DOM components hot reload during development\n- Keep DOM components focused — don't put entire screens in webviews\n- Use native components for navigation chrome, DOM components for specialized content\n- Test on all platforms — web rendering may differ slightly from native webviews\n- Large DOM components may impact performance — profile if needed\n- The webview has its own JavaScript context — cannot directly share state with native\n",{"name":5,"license":15,"version":32,"description":7},"1.0.0","main","415349a94ba1a83dfbd3fc8f28f1d4ce34df49ab","apps\u002Fmobile\u002F.agents\u002Fskills\u002Fuse-dom","https:\u002F\u002Fgithub.com\u002Fepiphanyapps\u002Fmapyourhealth","https:\u002F\u002Fgithub.com\u002Fepiphanyapps","www.epiphanyapps.com","2026-09-02 13:41:20",{"source":8,"skillName":5,"commands":41,"prompt":51,"zipAvailable":52},[42,45,48],{"tool":43,"command":44},"npx","npx skills add epiphanyapps\u002Fmapyourhealth --skill use-dom",{"tool":46,"command":47},"bunx","bunx skills add epiphanyapps\u002Fmapyourhealth --skill use-dom",{"tool":49,"command":50},"pnpm","pnpm dlx skills add epiphanyapps\u002Fmapyourhealth --skill use-dom","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fepiphanyapps\u002Fmapyourhealth\u002Fblob\u002Fmain\u002Fapps\u002Fmobile\u002F.agents\u002Fskills\u002Fuse-dom\u002FSKILL.md",true,[],[55,69,93,105,126,148],{"skillNo":56,"name":57,"nameZh":6,"description":58,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":59,"categories":60,"keywords":61,"publishedAt":27},"01M6CC1HHT3GY5AT1EKNVEPNB6","validate-skills","Validates skills in this repo against agentskills.io spec and Claude Code best practices. Use via \u002Fvalidate-skills command.","https:\u002F\u002Fgithub.com\u002Fepiphanyapps\u002Fmapyourhealth\u002Fblob\u002Fmain\u002Fapps\u002Fmobile\u002F.agents\u002Fskills\u002Fvalidate-skills\u002FSKILL.md",[],[62,63,20,64,65,66,67,24,68],"validate","validate skills","command","repo","validation","best practices","spec",{"skillNo":70,"name":71,"nameZh":6,"description":72,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":73,"categories":74,"keywords":80,"publishedAt":27},"01M6CC1CDBNAEG4XPPAEDHK0K4","upgrading-react-native","React Native upgrade workflow covering updated templates, dependencies, and common pitfalls. Use when migrating a React Native app to a newer release.","https:\u002F\u002Fgithub.com\u002Fepiphanyapps\u002Fmapyourhealth\u002Fblob\u002Fmain\u002Fapps\u002Fmobile\u002F.agents\u002Fskills\u002Fupgrading-react-native\u002FSKILL.md",[75],{"categoryNo":76,"categoryName":77,"taxonomyType":78,"taxonomyTypeDesc":79},"01JBSEEDCAT000000000000009","前端开发","SCENARIO","使用场景",[81,82,83,20,84,85,86,87,88,89,90,91,92],"react","react native","upgrading react native","react-native","android","common","templates","ios","npm","changelog","release","workflow",{"skillNo":94,"name":95,"nameZh":6,"description":96,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":97,"categories":98,"keywords":99,"publishedAt":27},"01M6CC19S41G82VN6WRTTMZ233","upgrading-expo","Guidelines for upgrading Expo SDK versions and fixing dependency issues","https:\u002F\u002Fgithub.com\u002Fepiphanyapps\u002Fmapyourhealth\u002Fblob\u002Fmain\u002Fapps\u002Fmobile\u002F.agents\u002Fskills\u002Fupgrading-expo\u002FSKILL.md",[],[26,100,101,102,103,104],"upgrading expo","sdk","guidelines","issues","dependency",{"skillNo":106,"name":107,"nameZh":6,"description":108,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":109,"categories":110,"keywords":112,"publishedAt":27},"01M6CC0NPK5PVP2BG3QDW4KNV3","react-native-best-practices","Provides React Native performance optimization guidelines for FPS, TTI, bundle size, memory leaks, re-renders, and animations. Applies to tasks involving Hermes optimization, JS thread blocking, bridge overhead, FlashList, native modules, or debugging jank and frame drops.","https:\u002F\u002Fgithub.com\u002Fepiphanyapps\u002Fmapyourhealth\u002Fblob\u002Fmain\u002Fapps\u002Fmobile\u002F.agents\u002Fskills\u002Freact-native-best-practices\u002FSKILL.md",[111],{"categoryNo":76,"categoryName":77,"taxonomyType":78,"taxonomyTypeDesc":79},[113,81,67,82,26,84,114,115,116,117,118,119,120,121,122,123,102,124,125],"react native best practices","hermes","modules","bridge","js","memory","bundle size","performance optimization","Optimization","tasks","debugging","performance","profiling",{"skillNo":127,"name":128,"nameZh":6,"description":129,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":130,"categories":131,"keywords":138,"publishedAt":27},"01M6CC090RAFTKGJ7K9SF71HMA","native-data-fetching","Use when implementing or debugging ANY network request, API call, or data fetching. Covers fetch API, axios, React Query, SWR, error handling, caching strategies, offline support.","https:\u002F\u002Fgithub.com\u002Fepiphanyapps\u002Fmapyourhealth\u002Fblob\u002Fmain\u002Fapps\u002Fmobile\u002F.agents\u002Fskills\u002Fnative-data-fetching\u002FSKILL.md",[132,133],{"categoryNo":76,"categoryName":77,"taxonomyType":78,"taxonomyTypeDesc":79},{"categoryNo":134,"categoryName":135,"taxonomyType":136,"taxonomyTypeDesc":137},"01JBSEEDCAT000000000000033","数据分析师","PROFESSION","适用职业",[139,140,141,81,20,142,143,144,145,146,147,123],"native data fetching","data","support","fetch","api","network","swr","offline","error handling",{"skillNo":149,"name":150,"nameZh":6,"description":151,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":152,"categories":153,"keywords":157,"publishedAt":27},"01M6CC00KWX6XENSWJ0P5GXXZW","github","GitHub patterns using gh CLI for pull requests, stacked PRs, code review, branching strategies, and repository automation. Use when working with GitHub PRs, merging strategies, or repository management tasks.","https:\u002F\u002Fgithub.com\u002Fepiphanyapps\u002Fmapyourhealth\u002Fblob\u002Fmain\u002Fapps\u002Fmobile\u002F.agents\u002Fskills\u002Fgithub\u002FSKILL.md",[154],{"categoryNo":155,"categoryName":156,"taxonomyType":78,"taxonomyTypeDesc":79},"01JBSEEDCAT000000000000007","代码审查",[150,158,20,159,160,161,162,163,164,165,24,122,166,167,168,169,170,171],"repository","management","gh cli","gh","squash","rebase","stacked prs","pull","pr","pull requests","automation","cli","review","code review"]