> ## Documentation Index
> Fetch the complete documentation index at: https://docs.metabind.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Modifiers

> How chainable modifiers compose with components, why order matters, and where to find each modifier in the reference

Modifiers are chainable methods on a component builder. Each modifier returns a new builder with one additional modifier wrapping the inner subtree, and the renderer applies the chain in order. Calling `.padding(16)` on a `Text` does not mutate the text — it produces a new builder that the next call can chain from. The result is that styling, layout, and behavior all read top-to-bottom on a single component, and the component itself stays a function call with its bare arguments.

This page covers the chainable pattern, why ordering matters, and how the modifier surface is organized in the reference.

## The chainable pattern

Every component supports the same universal modifier set. Calls return the builder, so you can chain as many as you need:

```typescript theme={null}
Text("Hello")
    .font("headline")
    .foregroundStyle(Color("blue"))
    .padding(16)
```

Each call returns a new builder. The chain reads as a sequence of wrappers around the inner component — `font` is applied first, then `foregroundStyle`, then `padding`. The renderer walks that wrapper chain when it produces native output, so what you write is the order the renderer applies.

A few practical consequences:

* Modifiers compose across components. The same `.padding(16)` works on a `Text`, a `VStack`, an `Image`, a `Button`.
* Modifiers can carry components themselves. `.background(Color("red"))` and `.overlay(Text("Badge"))` accept other components as their content, which lets the chain stay flat instead of nesting wrappers in the tree.
* Some modifiers only take effect on specific component types. The chain still type-checks, but the rendered effect is scoped to where it makes sense — see [Component-specific modifiers](#component-specific-modifiers) below.

## Order matters

Modifiers apply left to right. Reordering changes what you see, because each modifier wraps the result of the chain so far.

The classic case is `.padding` and `.background`:

```typescript theme={null}
// Background extends to the padded area
Text("Hello")
    .padding(8)
    .background(Color("red"))

// Background hugs the text; padding is applied outside
Text("Hello")
    .background(Color("red"))
    .padding(8)
```

In the first chain, `.padding(8)` runs first and produces a padded text node; `.background` then paints the entire padded area red. In the second, `.background` paints the bare text node; `.padding(8)` then adds whitespace around the colored block.

The same logic applies anywhere a modifier wraps geometry — `.frame`, `.cornerRadius`, `.clipped`, `.overlay`, `.shadow`, transform modifiers. When a chain is not producing what you expect, the order is usually the answer.

Every conforming BindJS runtime preserves the author's order through to the renderer. You can rely on `A.then(B)` rendering the same way on every platform.

## Categories

The modifier surface is organized by what each modifier affects. The reference splits the catalog into consolidated pages — use the table to jump to the right section.

| Category                     | What it does                                                         | Reference                                                                    |
| ---------------------------- | -------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| Identity and lifecycle       | `.id`, `.tag`, `.onAppear`, `.onDisappear`                           | [Identity and lifecycle](/bindjs/modifiers/identity-and-lifecycle)           |
| Layout — frame and padding   | `.frame`, `.padding`, `.offset`, `.zIndex`, sizing                   | [Layout — frame and padding](/bindjs/modifiers/layout-frame-and-padding)     |
| Transforms                   | `.scaleEffect`, `.rotationEffect`, `.transformEffect`                | [Transforms](/bindjs/modifiers/transforms)                                   |
| Appearance — color and style | `.foregroundStyle`, `.background`, `.cornerRadius`, `.shadow`        | [Appearance — color and style](/bindjs/modifiers/appearance-color-and-style) |
| Appearance — effects         | `.blur`, `.saturation`, `.brightness`, `.blendMode`                  | [Appearance — effects](/bindjs/modifiers/appearance-effects)                 |
| Typography                   | `.font`, `.fontWeight`, `.bold`, `.italic`, `.lineLimit`             | [Typography](/bindjs/modifiers/typography)                                   |
| Layering — overlay           | `.overlay`                                                           | [overlay](/bindjs/modifiers/overlay)                                         |
| Clipping and masking         | `.clipped`, `.clipShape`, `.mask`                                    | [Clipping and masking](/bindjs/modifiers/clipping-and-masking)               |
| Visibility and interaction   | `.hidden`, `.disabled`, `.allowsHitTesting`, `.textSelection`        | [Visibility and interaction](/bindjs/modifiers/visibility-and-interaction)   |
| Gestures                     | `.onTapGesture`, `.onDragGesture`, `.onLongPressGesture`, `.onHover` | [Gestures](/bindjs/modifiers/gestures)                                       |
| Visual effects               | `.visualEffect`, `.coordinateSpace`                                  | [Visual effects](/bindjs/modifiers/visual-effects)                           |
| Controls                     | `.controlSize`, `.pickerStyle`, `.buttonStyle`                       | [Controls](/bindjs/modifiers/controls)                                       |
| Text input                   | `.keyboardType`, `.textFieldStyle`, `.submitLabel`, `.focused`       | [Text input](/bindjs/modifiers/text-input)                                   |
| Value observation            | `.onChange`                                                          | [onChange](/bindjs/modifiers/onChange)                                       |
| Accessibility                | `.accessibilityLabel`, `.accessibilityValue`, `.accessibilityHidden` | [Accessibility](/bindjs/modifiers/accessibility)                             |
| Transitions                  | `.transition`                                                        | [transition](/bindjs/modifiers/transition)                                   |
| Environment                  | `.environment(key, value)`                                           | [environment](/bindjs/modifiers/environment)                                 |

These are core — every conforming runtime should implement them, and code that uses them is portable across iOS, Android, and the web.

A separate set of iOS-only modifiers covers presentation, navigation chrome, and platform-specific affordances: [Presentation](/bindjs/modifiers/presentation) (`.sheet`, `.fullScreenCover`, `.presentationDetents`), [Navigation chrome](/bindjs/modifiers/navigation-chrome), [Toolbar](/bindjs/modifiers/toolbar), [List chrome](/bindjs/modifiers/list-chrome), [Scroll chrome](/bindjs/modifiers/scroll-chrome), [Grid cells](/bindjs/modifiers/grid-cells), [Accessibility refinements](/bindjs/modifiers/accessibility-refinements), and [Text refinements](/bindjs/modifiers/text-refinements). Reading these from a cross-platform component requires a fallback.

## Component-specific modifiers

A handful of modifiers are only valid on specific component types. The chain still type-checks because the modifier is declared on the corresponding component interface, but the rendered effect is scoped:

* `.font(...)`, `.bold()`, `.italic()`, and the rest of typography apply to `Text`.
* `.resizable()`, `.renderingMode(...)`, `.interpolation(...)` apply to `Image`.
* `.fill(...)` and `.stroke(...)` apply to shapes (`Circle`, `Rectangle`, `RoundedRectangle`, `Ellipse`, `Capsule`, `Path`).

The reference pages call these out where they apply. When in doubt, look at the component's own page — the typography modifiers, for example, are documented under [Typography](/bindjs/modifiers/typography) and surface as methods on `Text`.

## Animation

Animation is a thin layer on top of the modifier chain. `withAnimation(animation?, body)` wraps a state mutation in an animation context, and any modifier whose value changes as a result of that mutation animates between the old and new values.

```typescript theme={null}
withAnimation(() => setExpanded(!expanded))
withAnimation(Spring({ response: 0.5 }), () => setOffset({ x: 100, y: 0 }))
```

The first argument is an optional animation builder — `Spring`, `EaseIn`, `EaseOut`, `Linear`, `Bouncy`, and the rest. Omit it for the default spring. See [`withAnimation`](/bindjs/functions/withAnimation) for the wrapping function and [Animation builders](/bindjs/functions/animations) for the catalog of timing curves.

## What to read next

<CardGroup cols={2}>
  <Card title="Layout — frame and padding" icon="ruler-combined" href="/bindjs/modifiers/layout-frame-and-padding">
    The geometric modifiers most chains start with.
  </Card>

  <Card title="Typography" icon="font" href="/bindjs/modifiers/typography">
    The text-shaping modifiers `Text` accepts.
  </Card>

  <Card title="Gestures" icon="hand-pointer" href="/bindjs/modifiers/gestures">
    Tap, drag, long press, and hover handlers.
  </Card>

  <Card title="State and environment" icon="circle-nodes" href="/bindjs/authoring/state">
    How `useState`, `useStore`, and environment values move through a render.
  </Card>
</CardGroup>
