skill

Expo Dom

Framework (OSS). Use Expo DOM components to run web code in a webview on native and as-is on web. Migrate web code to native incrementally. For the end-to-end migration of a whole web app, use the expo-web-to-native skill.

Expo0+ installsVetted

About

## What are DOM Components?

DOM 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.

## When to Use DOM Components

Use DOM components when you need:

- **Web-only libraries** — Charts (recharts, chart.js), syntax highlighters, rich text editors, or any library that depends on DOM APIs - **Migrating web code** — Bring existing React web components to native without rewriting - **Complex HTML/CSS layouts** — When CSS features aren't available in React Native - **iframes or embeds** — Embedding external content that requires a browser context - **Canvas or WebGL** — Web graphics APIs not available natively

## When NOT to Use DOM Components

Avoid DOM components when:

- **Native performance is critical** — Webviews add overhead - **Simple UI** — React Native components are more efficient for basic layouts - **Deep native integration** — Use local modules instead for native APIs - **Layout routes** — `_layout` files cannot be DOM components

## Basic DOM Component

Create a new file with the `'use dom';` directive at the top:

```tsx // components/WebChart.tsx "use dom";

export default function WebChart({ data, }: { data: number[]; dom: import("expo/dom").DOMProps; }) { return ( <div style={{ padding: 20 }}> <h2>Chart Data</h2> <ul> {data.map((value, i) => ( <li key={i}>{value}</li> ))} </ul> </div> ); } ```

## Rules for DOM Components

1. **Must have `'use dom';` directive** at the top of the file 2. **Single default export** — One React component per file 3. **Own file** — Cannot be defined inline or combined with native components 4. **Serializable props only** — Strings, numbers, booleans, arrays, plain objects 5. **Include CSS in the component file** — DOM components run in isolated context

## The `dom` Prop

Every DOM component receives a special `dom` prop for webview configuration. Always type it in your props:

```tsx "use dom";

interface Props { content: string; dom: import("expo/dom").DOMProps; }

export default function MyComponent({ content }: Props) { return <div>{content}</div>; } ```

### Common `dom` Prop Options

```tsx // Disable body scrolling <DOMComponent dom={{ scrollEnabled: false }} />

// Flow under the notch (disable safe area insets) <DOMComponent dom={{ contentInsetAdjustmentBehavior: "never" }} />

// Control size manually <DOMComponent dom={{ style: { width: 300, height: 400 } }} />

// Combine options <DOMComponent dom={{ scrollEnabled: false, contentInsetAdjustmentBehavior: "never", style: { width: '100%', height: 500 } }} /> ```

## Exposing Native Actions to the Webview

Pass async functions as props to expose native functionality to the DOM component:

```tsx // app/index.tsx (native) import { Alert } from "react-native"; import DOMComponent from "@/components/dom-component";

export default function Screen() { return ( <DOMComponent showAlert={async (message: string) => { Alert.alert("From Web", message); }} saveData={async (data: { name: string; value: number }) => { // Save to native storage, database, etc. console.log("Saving:", data); return { success: true }; }} /> ); } ```

```tsx // components/dom-component.tsx "use dom";

interface Props { showAlert: (message: string) => Promise<void>; saveData: (data: { name: string; value: number; }) => Promise<{ success: boolean }>; dom?: import("expo/dom").DOMProps; }

export default function DOMComponent({ showAlert, saveData }: Props) { const handleClick = async () => { await showAlert("Hello from the webview!"); const result = await saveData({ name: "test", value: 42 }); console.log("Save result:", result); };

return <button onClick={handleClick}>Trigger Native Action</button>; } ```

## Using Web Libraries

DOM components can use any web library:

```tsx // components/syntax-highlight.tsx "use dom";

import SyntaxHighlighter from "react-syntax-highlighter"; import { docco } from "react-syntax-highlighter/dist/esm/styles/hljs";

interface Props { code: string; language: string; dom?: import("expo/dom").DOMProps; }

export default function SyntaxHighlight({ code, language }: Props) { return ( <SyntaxHighlighter language={language} style={docco}> {code} </SyntaxHighlighter> ); } ```

```tsx // components/chart.tsx "use dom";

import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, } from "recharts";

interface Props { data: Array<{ name: string; value: number }>; dom: import("expo/dom").DOMProps; }

export default function Chart({ data }: Props) { return ( <LineChart width={400} height={300} data={data}> <CartesianGrid strokeDasharray="3 3" /> <XAxis dataKey="name" /> <Y

Install

Run this command

git clone https://github.com/expo/skills && cp -r skills/plugins/expo/skills/expo-dom ~/.claude/skills/

Works with

claude appclaude codeclaude apicursorcodexwindsurfclinezed

Manual steps

Clone the repository and copy the `plugins/expo/skills/expo-dom` folder into your Claude skills directory. Compatible with Claude Code, Cursor, Codex, and any Agent Skills-compatible agent.

View source
License: MITBy Expo

Frequently asked questions

What is the Expo Dom skill?

Framework (OSS). Use Expo DOM components to run web code in a webview on native and as-is on web. Migrate web code to native incrementally. For the end-to-end migration of a whole web app, use the expo-web-to-native skill.

How do I install Expo Dom?

Run this in your terminal:

git clone https://github.com/expo/skills && cp -r skills/plugins/expo/skills/expo-dom ~/.claude/skills/
Which AI tools does Expo Dom work with?

It works with claude_app, claude_code, claude_api, cursor, codex, windsurf, cline, zed.

Who made Expo Dom?

Expo, released under the MIT license.

Is Expo Dom free?

Yes, it is free to use under the MIT license.

Related assets

More curated picks in Development & Code.

All Expo Dom alternatives →
skillclaude_appclaude_codeclaude_api
npx skills add google/agents-cli
Google Agents Cli Adk Code
This skill should be used when the user wants to "write agent code", "build an agent with ADK", "add a tool", "create a callback", "define an agent",…358,165+
skillclaude_appclaude_codeclaude_api
npx skills add google/agents-cli
Google Agents Cli Workflow
This skill should be used when the user wants to "develop an agent", "build an agent using ADK", "run the agent locally", "debug agent code", "test an…357,749+
skillclaude_appclaude_codeclaude_api
npx skills add google/agents-cli
Google Agents Cli Eval
This skill should be used when the user wants to "run an evaluation", "evaluate my agent", "evaluate my ADK agent", "write an eval dataset", "analyze…357,721+
skillclaude_appclaude_codeclaude_api
npx skills add google/agents-cli
Google Agents Cli Deploy
This skill should be used when the user wants to "deploy an agent", "deploy my ADK agent", "set up CI/CD", "configure secrets", "troubleshoot a deploy…357,661+
skillclaude_appclaude_codeclaude_api
npx skills add google/agents-cli
Google Agents Cli Publish
This skill should be used when the user wants to "publish an agent", "publish my ADK agent", "register an agent with Gemini Enterprise", "publish to G…357,490+
skillclaude_appclaude_codeclaude_api
npx skills add prisma/skills
Prisma Cli
Prisma ORM CLI commands reference covering init, generate, migrate, db, dev, complete, studio, validate, format, debug, and mcp. Use for ORM/database…309,452+

Audit before you install

Run any source through our checks - AI visibility, security, performance, and stack detection.

More in Development & Code