# Tamagui Complete Documentation > Tamagui is a complete UI solution for React Native and Web, with a fully-featured UI kit, styling engine, and optimizing compiler. ## core/settings --- title: Settings description: Strictness, SSR, theme class placement, and other createTamagui settings. --- Pass a `settings` object to `createTamagui` to control type strictness, SSR behavior, flex behavior, units, and how themes reach the DOM. ```tsx fileName="tamagui.config.ts" export const config = createTamagui({ // ... settings: { disableSSR: true, allowedStyleValues: 'somewhat-strict-web', defaultFont: 'body', }, }) ``` [`@tamagui/config/v6`](/docs/core/config-v6) sets sensible values for all of these. Spread `defaultConfig.settings` and override the keys you need. ## Options ', description: `Which media queries count as active on the first render. Used for SSR.`, }, { name: 'addThemeClassName', required: false, type: "false | 'html' | 'body'", default: false, description: `Where to put the root theme className on web. Styling with theme CSS variables needs the class on body or above. When false, the class goes on the element TamaguiProvider renders.`, }, { name: 'selectionStyles', required: false, type: '(theme) => ({ backgroundColor: Variable | string; color: Variable | string })', default: false, description: `Generates ::selection styles for text selection on the web.`, }, { name: 'shouldAddPrefersColorThemes', required: false, type: 'boolean', default: `true`, description: `Generates prefers-color-scheme media queries for your light and dark themes. Increases total CSS size.`, }, { name: 'onlyAllowShorthands', required: false, type: 'boolean', default: false, description: `Removes the types for the long-form version of every shorthand you define. See Shorthands.`, }, { name: 'styleValueSyntax', required: false, type: `'string' | 'object'`, default: `undefined`, description: `Restrict conditional style values to one syntax. Flat values accept both the string form (bg="red hover:blue") and the object form (bg={{ default: 'red', hover: 'blue' }}). Setting this narrows the types to one form, makes the runtime warn on the other in development, and tells tamagui generate-prompt and the skills to only show that form.`, }, { name: `allowedStyleValues`, required: false, type: 'AllowedStyleValuesSetting', description: `Controls type validation of single-token style values. See below. Run tamagui check --strict to validate conditional payloads against the project config too.`, }, { name: 'styleCompat', required: false, type: `'legacy' | 'react-native' | 'web'`, default: `'web'`, description: `Which flex expansion semantics to follow where Yoga and CSS differ. Numeric lineHeight values are ratios in every mode.`, }, { name: 'remBaseFontSize', required: false, type: 'number', default: `16`, description: `Base font size for rem calculations on native. On web, browsers use the root font size.`, }, { name: 'defaultPosition', required: false, type: `'static' | 'relative'`, default: `'static'`, description: `Default position value for all Tamagui components.`, }, { name: 'onlyShorthandStyleProps', required: false, type: 'boolean', default: false, description: `Removes the longhand border, outline, and shadow props (borderWidth, outlineWidth, shadowColor, and the rest) from the types, encouraging the combined border, outline, and boxShadow props instead. Type-level only.`, }, { name: 'fastSchemeChange', required: false, type: 'boolean', default: false, description: `On iOS, returns color values as DynamicColorIOS so light and dark switches skip a re-render. The defaultTheme you pass to TamaguiProvider must match the current system color scheme.`, }, { name: 'optimizeFor', required: false, type: `'updates' | 'first-render'`, default: `'updates' on web, 'first-render' on native`, description: `Chooses the render performance tradeoff. "updates" tracks which theme and media keys each component reads so changes re-render only their consumers, at a small per-component first-render cost. "first-render" skips per-key tracking for the fastest initial render. Theme and media changes still apply, but re-render coarsely. This is a startup-level setting. Do not change it at runtime.`, }, ]} /> ## allowedStyleValues Controls which values the types accept for token-backed style props: - `false` (default): any string, or number for styles that accept numbers - `strict`: only tokens for any token-enabled property - `strict-web`: same as strict, plus web-only values like `auto` and `inherit` - `somewhat-strict`: tokens, or: - for `space` and `size`: percentage strings or numbers - for `radius`: numbers - for `zIndex`: numbers - for `color`: named colors or rgba and hsla strings - `somewhat-strict-web`: same as somewhat-strict, plus web-only values Pass one value for every category, or an object to set each category on its own: ```tsx type AllowedValueSetting = | boolean | 'strict' | 'somewhat-strict' | 'strict-web' | 'somewhat-strict-web' type AllowedStyleValuesSetting = | AllowedValueSetting | { space?: AllowedValueSetting size?: AllowedValueSetting radius?: AllowedValueSetting zIndex?: AllowedValueSetting color?: AllowedValueSetting } ``` ## Environment variables A few behaviors are set with environment variables rather than `settings`. Your bundler can then drop the code paths you do not use. On web, use the Tamagui Vite or Next.js plugin, or define them in your own bundler config. On native the extra size is small enough not to matter. ## core/html-primitives --- title: HTML elements description: Semantic HTML elements that render on web and native, in early development --- The `html` export renders semantic HTML on web and the matching React Native primitives on native. It follows web and React Strict DOM semantics, and suits screens that are mostly web content. Each member is an ordinary Tamagui component, so it takes Tamagui style props alongside the DOM props for that element. ```tsx import { html } from 'tamagui' export function Article() { return ( A semantic, styled heading The same source renders semantic tags on web and native primitives in a native app. ) } ``` You can also import `html` from `@tamagui/core`. ## Before you use it `html.*` is in early development. Its elements keep the browser's default `display`, so on web `html.div` and `html.p` are `display: block` and `html.span` is inline. React Native only has flex layout, so the same tree can lay out differently on native. [`View` and `Text`](/docs/core/view-and-text) are flex columns everywhere, which is why they stay the default for cross-platform screens. Every `html.*` member is built on `View` or `Text`, so both take the same style props, tokens, themes, and variants, and you can mix them in one tree. ## What renders On web, `html.article`, `html.h1`, and `html.p` render literal `article`, `h1`, and `p` elements. Tamagui applies explicit element defaults so the result does not depend on whether the page loaded a CSS reset. On native, the same members render through one of four backing primitives: | Source element | Native backing | | --- | --- | | layout elements such as `div`, `article`, `main`, `section`, and `ul` | `View` | | text elements such as `span`, `p`, `strong`, and `h1` | `Text` | | `img` | `Image` | | `input` and `textarea` | `TextInput` | The native runtime maps supported DOM prop names to their React Native names. It also wraps literal text inside a View-backed element, because a React Native `View` cannot render a raw string. The compiler performs the same mapping and text wrapping ahead of time when it can lower the element. ## Available elements The root export includes: ```txt a article aside b bdi bdo blockquote br button code del div em fieldset footer form h1 h2 h3 h4 h5 h6 header hr i img input ins kbd label li main mark nav ol optgroup option p pre s section select span strong sub sup textarea u ul ``` Props are specific to the element. For example, `html.a` accepts `href`, `html.img` accepts `src` and `alt`, and `html.input` accepts input props. Void elements such as `br`, `hr`, `img`, and `input` reject children in TypeScript. Because these are Tamagui components, style props use the same tokens, themes, shorthands, and [flat conditional values](/docs/guides/flat-values) as `View` and `Text`: ```tsx Save ``` ## Native support is explicit A browser feature without a faithful native equivalent does not silently turn into a different control. Native builds reject `html.select`, `html.option`, and `html.optgroup`, because React Native has no menu-based select control. Unsupported props and events also produce a diagnostic naming the unsupported behavior. Some elements preserve their useful native subset. `html.form` and `html.fieldset`, for example, render containers on native, while browser form submission, validation, and reset behavior remain web-only. The compiler and runtime read the same generated compatibility tables. Running with or without compiler lowering therefore uses the same supported tag and prop contract. ## Compiler behavior The compiler treats `html.*` as regular lowering candidates. On web it can replace a component with its literal tag, extracted classes, and any remaining host props. On native it can replace the same component with its backing primitive and mapped props. If the compiler cannot lower an ordinary use, the root export still has a runtime implementation on both platforms. For new code, use the root `html` export shown here. The standalone `tamagui/dom` and `@tamagui/core/dom` entries are deprecated implementation surfaces. Their `style()` handles are compile-only and throw if they reach the runtime. ## core/tamagui-provider --- title: TamaguiProvider description: Mount your config, generate its CSS, and trim theme JS from the client bundle. --- `TamaguiProvider` makes the object returned by `createTamagui` available to every component below it. Render it once at the root of your app: ```tsx line=3-5 fileName="App.tsx" import { TamaguiProvider } from 'tamagui' import { config } from './tamagui.config' export default function App() { return ( ) } ``` Import `tamagui.config.ts` in one place near the root. Importing it from many files invites circular imports and breaks hot reloading. Other files reach the config through style props, `useMedia`, `useTheme`, or getters like `getTokenValue`. The full object is available from `getConfig` when you need it. Set your root theme with `defaultTheme` instead of wrapping the app in ``. That keeps the [`fastSchemeChange` setting](/docs/core/settings) working on native, and lets light and dark switches on web use media query updates during SSR. ## Props ## Generating CSS On the client, Tamagui injects the CSS for your configuration into `document.head`. For production you want that CSS served with the page. Set `disableInjectCSS` on `TamaguiProvider`, then pick one of three ways to emit it. If your framework has server-side layouts, render it inline: ```tsx fileName=app/_layout.tsx import { config } from './tamagui.config' export default () => (