
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
@webeach/react-x
Advanced tools
Extended React JSX syntax for conditional classes, inline styles, and CSS variables
🇺🇸 English version | 🇷🇺 Русская версия
A React extension library that adds convenient syntax for working with CSS classes, styles, and CSS variables directly in JSX.
class:className with CSS Modules supportstyle:propertyvar:variableNamex.div, x.span, x.svg, etc.x(Component)npm install @webeach/react-x
or
pnpm install @webeach/react-x
or
yarn add @webeach/react-x
import { x } from '@webeach/react-x';
function App() {
const isActive = true;
const isDisabled = false;
return (
<x.div
class:container={true}
class:active={isActive}
class:disabled={isDisabled}
style:padding="20px"
style:backgroundColor="#f0f0f0"
var:primaryColor="#007bff"
>
Hello, World!
</x.div>
);
}
Result in DOM:
<div
class="container active"
style="padding: 20px; background-color: #f0f0f0; --primaryColor: #007bff;"
>
Hello, World!
</div>
x ObjectThe main export of the library. Works in two ways:
import { x } from '@webeach/react-x';
// HTML tags
<x.div>...</x.div>
<x.span>...</x.span>
<x.button>...</x.button>
<x.input />
<x.form>...</x.form>
// SVG tags
<x.svg>...</x.svg>
<x.path />
<x.circle />
<x.rect />
All standard HTML and SVG tags are supported.
import { x } from '@webeach/react-x';
// Your component
const ButtonInternal = ({ className, style, children, ...props }) => (
<button className={className} style={style} {...props}>
{children}
</button>
);
// Extended component
const Button = x(Button);
// Usage
<Button
class:primary
class:large={size === 'large'}
style:borderRadius="8px"
var:btnColor="blue"
>
Click me
</Button>
class:Add CSS classes conditionally via props with the class: prefix.
<x.div
class:visible={isVisible} // added if isVisible === true
class:hidden={!isVisible} // added if isVisible === false
class:active={isActive}
class:error={hasError}
class:my-custom-class // kebab-case is supported
>
Content
</x.div>
Supported value types:
boolean — true adds the class, false does notstring — used as an alias (class name from value, not from key)null | undefined — class is not addedPass a string to use with CSS Modules — the value becomes the class name:
import styles from './Button.module.css';
<x.button
class:base={styles.button} // adds class from styles.button
class:primary={styles.primary} // adds class from styles.primary
class:disabled={isDisabled && styles.disabled} // conditional
>
Click me
</x.button>
If styles.button = "Button_button__x7f2s", the result:
<button class="Button_button__x7f2s Button_primary__a3bc1">
Click me
</button>
Important: When passing a string, the value is used as the class name, not the key after class:.
classListAn alternative way to pass multiple classes via an array:
const classes = ['card', 'card-primary', isLarge && 'card-large'];
<x.div classList={classes}>
Content
</x.div>
Falsy array elements are automatically filtered out.
Can be combined with className and class::
<x.div
className="base-class"
classList={['additional', 'classes']}
class:conditional
>
All three methods work together
</x.div>
// Result: class="base-class additional classes conditional"
style:Set CSS properties directly via props with the style: prefix.
<x.div
style:display="flex"
style:justifyContent="center"
style:alignItems="center"
style:gap="10px"
style:padding="20px"
style:backgroundColor="#f5f5f5"
style:borderRadius="8px"
>
Flex container
</x.div>
Advantages:
Can be combined with regular style:
<x.div
style={{ margin: '10px' }}
style:padding="20px"
style:color="red"
>
Styles are merged
</x.div>
var:Pass CSS custom properties (variables) via props with the var: prefix.
<x.div
var:primaryColor="#007bff"
var:secondaryColor="#6c757d"
var:spacing="16px"
var:columns={3}
>
<x.span style:color="var(--primaryColor)">
Text in primary color
</x.span>
</x.div>
Result in DOM:
<div style="--primaryColor: #007bff; --secondaryColor: #6c757d; --spacing: 16px; --columns: 3;">
<span style="color: var(--primaryColor);">
Text in primary color
</span>
</div>
Supported value types:
string — var:color="red"number — var:columns={3}null — to reset a variableYou can type available CSS variables for a component:
import { ReactNode } from 'react';
import { x } from '@webeach/react-x';
// Define variable types
type ThemeVars = {
primaryColor: string;
secondaryColor: string;
spacing: number;
};
// Typed component
const ThemedBox = x<{ children: ReactNode }, ThemeVars>(
({ children, className, style }) => (
<div className={className} style={style}>
{children}
</div>
)
);
// Now IDE suggests available variables
<ThemedBox
var:primaryColor="blue" // ✓ autocompletion works
var:secondaryColor="gray" // ✓
var:spacing={16} // ✓
var:unknownVar="value" // ✗ TypeScript error
>
Content
</ThemedBox>
import { ReactNode } from 'react';
import { x } from '@webeach/react-x';
type ButtonProps = {
variant?: 'primary' | 'secondary' | 'danger';
size?: 'small' | 'medium' | 'large';
disabled?: boolean;
children: ReactNode;
};
function Button({ variant = 'primary', size = 'medium', disabled, children }: ButtonProps) {
return (
<x.button
class:btn
class:btn-primary={variant === 'primary'}
class:btn-secondary={variant === 'secondary'}
class:btn-danger={variant === 'danger'}
class:btn-sm={size === 'small'}
class:btn-lg={size === 'large'}
class:disabled={disabled}
disabled={disabled}
>
{children}
</x.button>
);
}
import { ReactNode } from 'react';
import { x } from '@webeach/react-x';
import styles from './Button.module.css';
type ButtonProps = {
variant?: 'primary' | 'secondary';
disabled?: boolean;
children: ReactNode;
};
function Button({ variant = 'primary', disabled, children }: ButtonProps) {
return (
<x.button
class:base={styles.button}
class:variant={variant === 'primary' ? styles.primary : styles.secondary}
class:disabled={disabled && styles.disabled}
disabled={disabled}
>
{children}
</x.button>
);
}
import { x } from '@webeach/react-x';
function Card({ title, children, accentColor = '#007bff' }) {
return (
<x.article
class:card
var:accentColor={accentColor}
style:borderLeft="4px solid var(--accentColor)"
style:padding="20px"
style:borderRadius="8px"
style:boxShadow="0 2px 8px rgb(0 0 0 / 0.1)"
>
<x.h2 style:color="var(--accentColor)" style:marginTop="0">
{title}
</x.h2>
{children}
</x.article>
);
}
import { x } from '@webeach/react-x';
function Grid({ columns = 3, gap = '16px', children }) {
return (
<x.div
style:display="grid"
style:gridTemplateColumns={`repeat(${columns}, 1fr)`}
style:gap={gap}
>
{children}
</x.div>
);
}
import { x } from '@webeach/react-x';
function Icon({ size = 24, color = 'currentColor' }) {
return (
<x.svg
var:iconSize={`${size}px`}
var:iconColor={color}
style:width="var(--iconSize)"
style:height="var(--iconSize)"
viewBox="0 0 24 24"
fill="none"
stroke="var(--iconColor)"
strokeWidth="2"
>
<x.path d="M12 2L2 7l10 5 10-5-10-5z" />
<x.path d="M2 17l10 5 10-5" />
<x.path d="M2 12l10 5 10-5" />
</x.svg>
);
}
import type { XClassProps, XStyleProps, XVarProps } from '@webeach/react-x';
XClassProps — types for class:* propsXStyleProps — types for style:* props (based on CSSProperties)XVarProps<T> — types for var:* props with optional variable typing| Feature | react-x | clsx/classnames | styled-components |
|---|---|---|---|
| Conditional classes | class:active={bool} | clsx({ active: bool }) | ${bool && 'active'} |
| CSS Modules | class:x={styles.class} | clsx(styles.class) | ❌ |
| Inline styles | style:padding="10px" | ❌ | Built-in |
| CSS variables | var:color="red" | ❌ | ${props => props.color} |
| TypeScript | ✅ Full | ✅ | ✅ |
| Runtime overhead | Minimal | Minimal | CSS-in-JS |
| Bundle size | ~2KB | ~1KB | ~15KB |
This library has no external dependencies (Zero dependencies).
Releases are handled automatically via semantic-release.
Before publishing a new version, ensure that:
main branch.feat: ... — for new featuresfix: ... — for bug fixeschore: ..., refactor: ... and other types — as neededpatch, minor, major).Development and maintenance: Ruslan Martynov
If you have suggestions or found a bug, open an issue or submit a pull request.
This package is distributed under the MIT License.
FAQs
Extended React JSX syntax for conditional classes, inline styles, and CSS variables
We found that @webeach/react-x demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.