# How to Override Astryx Component Styles Using className

> Easily override Astryx component styles with className. Merge custom CSS with StyleX classes using stylex.props() for safe visual customization without altering component behavior.

- Repository: [Meta/astryx](https://github.com/facebook/astryx)
- Tags: how-to-guide
- Published: 2026-07-15

---

**Pass a `className` prop to any Astryx component to merge custom CSS with internal StyleX-generated classes via `stylex.props()`, allowing safe visual customization without modifying component behavior.**

Astryx is a React component library built on **StyleX**, Meta's compile-time CSS-in-JS system. Every component in the `facebook/astryx` repository accepts a `className` prop that integrates seamlessly with the internal styling architecture, enabling developers to apply custom styles while preserving accessibility and interaction logic.

## Understanding the `className` Architecture in Astryx

### StyleX Foundation and Class Name Generation

Astryx components rely on StyleX to generate deterministic class names at build time. In [`packages/core/src/Button/Button.tsx`](https://github.com/facebook/astryx/blob/main/packages/core/src/Button/Button.tsx), the component uses `stylex.props()` to combine internal styles with external class names:

```tsx
export const Button = (props) => {
  const {className, ...rest} = props;
  const styles = useButtonStyles(); // StyleX-generated object
  return <button {...rest} className={stylex.props(styles.root, className)} />;
};

```

The `styles.root` class provides the baseline appearance, while the `className` prop is appended to allow CSS cascade overrides.

### Prop Signature and Type Safety

According to `packages/core/src/Button/Button.doc.mjs`, the `className` prop is explicitly typed as `string` and documented as the standard entry point for style overrides. This pattern remains consistent across all public components in the library.

## Methods to Override Component Styles

### CSS Module Integration

For scoped styles, pass a CSS Module class to the `className` prop:

```tsx
// src/MyButton.module.css
.myButton {
  margin: 8px 0;
  font-weight: 600;
}

// MyComponent.tsx
import styles from './MyButton.module.css';
import {Button} from '@astryxdesign/core';

export const MyComponent = () => (
  <Button className={styles.myButton}>Click me</Button>
);

```

### Global Stylesheet Overrides

Apply global CSS classes for cross-component styling:

```css
/* index.css */
.customBtn {
  background-color: teal;
  border-radius: 4px;
}

```

```tsx
import {Button} from '@astryxdesign/core';
import './index.css';

export const MyComponent = () => (
  <Button className="customBtn">Styled Button</Button>
);

```

### StyleX Marker Overrides

For complex interactions involving child elements, use `stylex.defineMarker()`:

```tsx
import {Button} from '@astryxdesign/core';
import stylex from '@stylexjs/stylex';

const marker = stylex.defineMarker('myHover');

export const MyComponent = () => (
  <Button className={marker}>
    <span className={stylex.when.ancestor(':hover', marker)}>
      Hover text
    </span>
  </Button>
);

```

## `className` vs. Theming: When to Use Each Approach

**Use `className`** for one-off visual adjustments, component-specific positioning, or integrating with existing CSS architectures.

**Use Theming** for global design system changes. Create a theme using `createTheme` and wrap your application in `ThemeProvider`:

```tsx
import {ThemeProvider, createTheme} from '@astryxdesign/core';

const myTheme = createTheme({
  button: {
    primaryColor: 'magenta',
  },
});

export const App = () => (
  <ThemeProvider theme={myTheme}>
    <Button>Themed Button</Button>
  </ThemeProvider>
);

```

**Use `astryx swizzle`** for structural modifications. This CLI command ejects the component source when you need to add or remove DOM elements.

## Key Source Files

Understanding the implementation requires examining these specific files in the `facebook/astryx` repository:

- **[`packages/core/src/Button/Button.tsx`](https://github.com/facebook/astryx/blob/main/packages/core/src/Button/Button.tsx)** – Core implementation showing `className` forwarding via `stylex.props()`
- **`packages/core/src/Button/Button.doc.mjs`** – API documentation defining the `className` prop signature
- **[`packages/core/src/stylex-utils.ts`](https://github.com/facebook/astryx/blob/main/packages/core/src/stylex-utils.ts)** – Utility functions for StyleX class merging and `defineMarker()`
- **[`packages/core/src/Theme/ThemeProvider.tsx`](https://github.com/facebook/astryx/blob/main/packages/core/src/Theme/ThemeProvider.tsx)** – Theming infrastructure for global style overrides

## Summary

- Astryx components accept a `className` prop that merges with internal StyleX classes using `stylex.props()`
- The merging preserves internal behavior while allowing external CSS to cascade
- CSS Modules, global stylesheets, and StyleX markers are all valid override mechanisms
- Use theming for global changes and `astryx swizzle` for structural modifications
- All styling approaches maintain the library's accessibility and interaction guarantees

## Frequently Asked Questions

### How does Astryx merge `className` with internal styles?

Astryx uses `stylex.props()` to concatenate the internal StyleX-generated class (e.g., `styles.root`) with the user-provided `className` string. The internal classes appear first in the DOM, followed by the custom class, ensuring your CSS rules apply via the cascade without `!important` declarations.

### Can I use CSS Modules with Astryx components?

Yes. Import your module styles and pass the imported class directly to the `className` prop. Astryx accepts any valid string, including hashed CSS Module class names, making it compatible with most React styling workflows.

### What is the difference between using `className` and theming in Astryx?

`className` overrides are instance-specific and ideal for positioning or one-off visual tweaks. Theming via `ThemeProvider` modifies design tokens (colors, spacing) across all component instances globally. Choose `className` for exceptions; choose theming for systematic design changes.

### How do I override styles for a specific component instance without affecting others?

Pass a unique `className` to that specific component instance. For complex overrides requiring internal structure changes, use the `astryx swizzle <Component>` command to eject and customize the component source code directly.