Any CSS to pixel art. Wrap your element with <Pixel> — Tailwind, inline styles, CSS modules all work. No Canvas, SSR compatible.
npm install @react-pixel-ui/react
# or
pnpm add @react-pixel-ui/react
# or
yarn add @react-pixel-ui/reactRequires React 18+. @react-pixel-ui/core is installed automatically.
import { Pixel } from '@react-pixel-ui/react';
function App() {
return (
<Pixel size={6}>
<div style={{
background: 'linear-gradient(135deg, #ff6b6b, #4ecdc4)',
borderRadius: 16,
border: '3px solid #333',
padding: 20,
}}>
Pixel Art!
</div>
</Pixel>
);
}That's it. <Pixel> reads your CSS and converts background, border-radius, border, and box-shadow into pixel art.
import { Pixel } from '@react-pixel-ui/react';
// Tailwind
<Pixel size={6}>
<div className="bg-gradient-to-r from-red-500 to-blue-500 rounded-xl border-2 border-black">
Works with Tailwind
</div>
</Pixel>
// Inline styles
<Pixel size={6}>
<div style={{ background: '#ff6b6b', borderRadius: 12, border: '2px solid #333' }}>
Works with inline styles
</div>
</Pixel>| Prop | Type | Default | Description |
|---|---|---|---|
size |
number |
4 |
Pixel block size in CSS px. Larger = blockier. |
enabled |
boolean |
true |
Toggle pixelation on/off |
children |
ReactElement |
required | Single child element to pixelate |
Supported CSS properties:
background/background-color— solid colors and gradients (linear-gradient,radial-gradient,repeating-*)border-radius— converted to staircase corners (supports per-corner[tl, tr, br, bl])border— pixel art border with staircase cornersbox-shadow— converted to hard drop-shadow (no blur)
Attach to any element without wrapping. Best for third-party components or when you can't use a wrapper.
import { usePixelRef } from '@react-pixel-ui/react';
function MyComponent() {
const pixelRef = usePixelRef({ pixelSize: 6 });
return (
<div
ref={pixelRef}
style={{
background: 'linear-gradient(135deg, #fd79a8, #e84393)',
borderRadius: 20,
border: '3px solid #b8256e',
padding: 16,
}}
>
Pixelated via ref
</div>
);
}| Option | Type | Default | Description |
|---|---|---|---|
pixelSize |
number |
4 |
Pixel block size |
enabled |
boolean |
true |
Toggle pixelation |
observeHover |
boolean |
true |
Re-compute on :hover |
observeFocus |
boolean |
true |
Re-compute on :focus |
observeActive |
boolean |
true |
Re-compute on :active |
Set default pixelSize for all <Pixel> and usePixelRef instances in the tree.
import { PixelConfigProvider } from '@react-pixel-ui/react';
function App() {
return (
<PixelConfigProvider config={{ pixelSize: 6 }}>
{/* All <Pixel> components default to size 6 */}
<MyPage />
</PixelConfigProvider>
);
}| Config Key | Type | Default | Description |
|---|---|---|---|
pixelSize |
number |
4 |
Default pixel block size |
borderColor |
string |
— | Default border color |
Use when you want direct control instead of auto-reading CSS.
import { PixelBox } from '@react-pixel-ui/react';
<PixelBox
width={280}
height={120}
pixelSize={6}
borderRadius={16}
borderWidth={3}
borderColor="#333"
background="linear-gradient(45deg, #ff6b6b, #4ecdc4)"
shadow={{ x: 4, y: 4, color: 'rgba(0,0,0,0.3)' }}
>
Content
</PixelBox>| Prop | Type | Default | Description |
|---|---|---|---|
width |
number |
200 |
Element width in px |
height |
number |
100 |
Element height in px |
pixelSize |
number |
4 |
Pixel block size |
borderRadius |
number | [number, number, number, number] |
— | Corner radius. Array = [topLeft, topRight, bottomRight, bottomLeft] |
borderWidth |
number |
— | Border thickness (auto-snapped to pixelSize grid) |
borderColor |
string |
— | Any CSS color |
background |
string |
— | CSS color or gradient string |
shadow |
{ x: number, y: number, color: string } |
— | Hard pixel shadow |
responsive |
boolean |
false |
Auto-detect size via ResizeObserver |
import { PixelButton } from '@react-pixel-ui/react';
<PixelButton variant="primary" width={160} height={48}>Click me</PixelButton>| Prop | Type | Default | Description |
|---|---|---|---|
variant |
'primary' | 'secondary' | 'danger' |
'primary' |
Color theme |
width |
number |
160 |
Button width |
height |
number |
48 |
Button height |
borderRadius |
number |
8 |
Corner radius |
pixelSize |
number |
from context | Pixel block size |
shadow |
{ x, y, color } |
auto | Pixel shadow |
| Use case | API | Why |
|---|---|---|
| Existing styled elements | <Pixel> |
Reads CSS automatically, zero config |
| Third-party components | usePixelRef |
Attach via ref, no wrapper div |
| Full manual control | PixelBox |
Explicit props, no CSS reading |
| Pre-built buttons | PixelButton |
Ready-to-use with variants |
| Feature | CSS Technique |
|---|---|
| Staircase corners | clip-path: polygon() — Bresenham circle algorithm generates stepped polygon |
| Pixel gradients | Composite BMP data URL + image-rendering: pixelated — 2D grid sampling per block |
| Pixel borders | Border color + gradient baked into single BMP with staircase shapes |
| Hard shadows | filter: drop-shadow(blur=0) — follows clip-path contour |
| Auto-detection | getComputedStyle() reads any CSS → converted to pixel art config |
function PixelSlider() {
const [size, setSize] = useState(6);
return (
<>
<input type="range" min={2} max={16} value={size} onChange={e => setSize(+e.target.value)} />
<Pixel size={size}>
<div style={{ background: '#ff6b6b', borderRadius: 12, border: '2px solid #333' }}>
Size: {size}px
</div>
</Pixel>
</>
);
}<Pixel size={6}>
<div style={{
background: '#ffeaa7',
borderRadius: '24px 4px 24px 4px', // TL TR BR BL
border: '3px solid #e17055',
width: 200, height: 80,
}}>
Asymmetric corners
</div>
</Pixel>// app/page.tsx — works directly, no 'use client' needed for <Pixel>
import { Pixel } from '@react-pixel-ui/react';
export default function Page() {
return (
<Pixel size={6}>
<div style={{ background: '#6c5ce7', borderRadius: 12, padding: 20, color: '#fff' }}>
SSR compatible
</div>
</Pixel>
);
}Note:
<Pixel>renders normally on the server. Pixel art is applied after hydration with no layout shift.
Q: Why does my gradient look smooth instead of pixelated?
A: Check that pixelSize is large enough to see distinct blocks. At size={2}, blocks are 2x2 CSS pixels — very small on high-DPI screens. Try size={6} or higher.
Q: Why is the border missing at diagonal corners?
A: Make sure you're using <Pixel> or usePixelRef (v2.0.1+). These use composite BMP rendering where border + gradient are baked together with correct staircase shapes.
Q: Does it work with Tailwind CSS?
A: Yes. <Pixel> reads getComputedStyle which resolves Tailwind classes into final CSS values.
Q: What CSS properties are supported?
A: background-color, background-image (linear/radial/repeating gradients), border-radius, border, box-shadow. Other properties (color, font, padding, etc.) are preserved as-is.
Q: Is it SSR compatible? A: Yes. The core package uses pure math (no Canvas, no DOM APIs). Elements render normally on the server and get pixelated on hydration.
| Feature | Chrome | Firefox | Safari | Edge |
|---|---|---|---|---|
clip-path: polygon() |
55+ | 54+ | 10+ | 79+ |
image-rendering: pixelated |
41+ | 56+ (crisp-edges) |
10+ | 79+ |
filter: drop-shadow() |
18+ | 35+ | 6+ | 79+ |
Overall: 97%+ global browser coverage.
Fully typed. All components, hooks, and config objects have TypeScript definitions.
import type {
PixelArtConfig,
PixelArtStyles,
PixelShadowConfig,
BorderRadii,
} from '@react-pixel-ui/react';packages/
core/ # Pure CSS generators (zero browser dependency, SSR safe)
react/ # React hooks & components
apps/
demo/ # Interactive demo + documentation site
pnpm setup # Install + build
pnpm dev --filter=@react-pixel-ui/demo # Run demo at localhost:3000
pnpm build && pnpm type-check # Build & verifyPRs welcome. Please open an issue first to discuss larger changes.
MIT
CSS 스타일을 자동으로 픽셀아트로 변환하는 React 라이브러리.
npm install @react-pixel-ui/reactimport { Pixel } from '@react-pixel-ui/react';
// 어떤 스타일이든 <Pixel>로 감싸면 픽셀 아트로 변환
<Pixel size={6}>
<div style={{
background: 'linear-gradient(135deg, #ff6b6b, #4ecdc4)',
borderRadius: 16,
border: '3px solid #333',
}}>
자동으로 픽셀화!
</div>
</Pixel>Tailwind, 인라인 스타일, CSS 모듈 모두 지원. Canvas 없음, SSR 호환.
자세한 API 문서는 영어 섹션을 참고하세요.