Getting Started
Go from zero to a rendered image in under 5 minutes.
Install
npm install grafex
Grafex uses WebKit for rendering. The browser binary is downloaded automatically during npm install via a postinstall script — no extra steps needed.
Tip: If the postinstall download fails (corporate firewalls, restricted CI environments), see Browser Setup for manual installation.
Requirements: Node.js >= 20.0.0
Write a composition
Create a file called card.tsx:
import type { CompositionConfig } from 'grafex';
export const config: CompositionConfig = {
width: 1200,
height: 630,
};
export default function Card() {
return (
<div
style={{
width: '100%',
height: '100%',
background: 'linear-gradient(135deg, #667eea, #764ba2)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
color: 'white',
fontSize: '64px',
fontWeight: 'bold',
fontFamily: 'system-ui, sans-serif',
}}
>
Hello, Grafex!
</div>
);
}A composition has two parts:
- Default export — a function that returns JSX. This is your image layout.
- Named
configexport — aCompositionConfigobject that sets the output dimensions, format, and optional features like custom fonts and CSS files.
TypeScript Setup
Run grafex init to generate the correct tsconfig.json automatically:
npx grafex init
This creates a tsconfig.json and a starter composition.tsx in your current directory. Existing files are never overwritten.
Or add these compiler options to your tsconfig.json manually:
{
"compilerOptions": {
"jsx": "react",
"jsxFactory": "h",
"jsxFragmentFactory": "Fragment"
}
}
Grafex ships its own JSX type definitions. They are picked up automatically once the package is installed — no extra imports needed. The h and Fragment functions are injected at transpile time, so you never import them in composition files.
Export
npx grafex export -f card.tsx -o card.pngGrafex bundles your composition with esbuild, renders it in a headless WebKit instance, and saves the screenshot as an image. The output is a 1200×630 image with your gradient background and centered text.
See it in action
This is the kind of image Grafex can generate. Write the code, run one command, see the result — no browser window, no server.
export const config = {
width: 600,
height: 400,
};
export default function OgCard() {
return (
<div style={{
width: '100%',
height: '100%',
background: 'linear-gradient(145deg, #0f172a 0%, #1e293b 100%)',
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-between',
padding: '52px',
fontFamily: 'system-ui, -apple-system, sans-serif',
position: 'relative',
overflow: 'hidden',
}}>
{/* Top accent glow */}
<div style={{
position: 'absolute',
top: '-60px',
right: '-60px',
width: '300px',
height: '300px',
background: 'radial-gradient(circle, rgba(244,114,182,0.2) 0%, transparent 70%)',
}} />
{/* Top: tag */}
<div style={{ display: 'flex', alignItems: 'center', gap: '12px', zIndex: 1 }}>
<div style={{
background: 'rgba(163,230,53,0.15)',
border: '1px solid rgba(163,230,53,0.3)',
borderRadius: '6px',
padding: '4px 12px',
color: '#A3E635',
fontSize: '12px',
fontWeight: '600',
letterSpacing: '0.08em',
textTransform: 'uppercase',
}}>
Tutorial
</div>
<span style={{ color: '#475569', fontSize: '13px' }}>5 min read</span>
</div>
{/* Middle: title */}
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px', zIndex: 1 }}>
<div style={{
color: '#F1F5F9',
fontSize: '36px',
fontWeight: '700',
lineHeight: '1.2',
letterSpacing: '-0.5px',
}}>
Building Modern APIs
</div>
<div style={{ color: '#94A3B8', fontSize: '16px', lineHeight: '1.5' }}>
Best practices for REST and GraphQL in 2026
</div>
</div>
{/* Bottom: author + meta */}
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', zIndex: 1 }}>
<div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
<div style={{
width: '36px',
height: '36px',
borderRadius: '50%',
background: 'linear-gradient(135deg, #F472B6, #38BDF8)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
color: 'white',
fontSize: '14px',
fontWeight: '700',
flexShrink: 0,
}}>
JS
</div>
<div style={{ display: 'flex', flexDirection: 'column', gap: '2px' }}>
<span style={{ color: '#E2E8F0', fontSize: '14px', fontWeight: '600' }}>Jane Smith</span>
<span style={{ color: '#64748B', fontSize: '12px' }}>March 15, 2026</span>
</div>
</div>
<div style={{
color: '#475569',
fontSize: '13px',
fontWeight: '600',
letterSpacing: '0.05em',
}}>
dev.blog
</div>
</div>
{/* Bottom-left accent stripe */}
<div style={{
position: 'absolute',
bottom: '0',
left: '0',
right: '0',
height: '3px',
background: 'linear-gradient(90deg, #F472B6, #38BDF8, #A3E635)',
}} />
</div>
);
}
og-card.png npx grafex export -f og-card.tsx -o og-card.png