Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/andresilva-cc/grafex/llms.txt

Use this file to discover all available pages before exploring further.

Grafex loads external CSS files at render time, which makes it a natural fit for Tailwind CSS. You generate a stylesheet with the Tailwind CLI, point config.css at it, and Grafex injects it as a <style> tag before the headless browser takes the screenshot. No plugins, no special configuration — just a stylesheet on disk.

Setup

1

Install dependencies

Add the Tailwind CLI and concurrently as dev dependencies. concurrently is optional but makes the dev workflow much smoother.
npm install --save-dev @tailwindcss/cli concurrently
2

Create input.css

Create an input.css file in your project root. This is the Tailwind entry point that the CLI reads.
@import 'tailwindcss';
3

Generate styles.css

Run the Tailwind CLI once to produce the compiled stylesheet. Tailwind scans your .tsx files for utility classes and writes only the ones you use.
npx @tailwindcss/cli -i ./input.css -o ./styles.css
styles.css is a generated file — do not commit it. Add it to .gitignore. When using grafex dev, you don’t even need to generate it up front; Grafex renders without styles initially and re-renders automatically as soon as Tailwind creates the file.
4

Reference styles.css in your composition config

Tell Grafex to load the compiled stylesheet by adding it to config.css. Paths are resolved relative to the composition file.
export const config: CompositionConfig = {
  width: 1200,
  height: 630,
  css: ['./styles.css'],
};
5

Write your composition with Tailwind classes

Use Tailwind utility classes on any element via className. Here is the full source of the Tailwind example that ships with Grafex:
// card.tsx
import type { CompositionConfig } from 'grafex';

export const config: CompositionConfig = {
  width: 1200,
  height: 630,
  css: ['./styles.css'],
};

interface Props {
  title?: string;
  description?: string;
  tag?: string;
  author?: string;
  site?: string;
}

export default function Card({
  title = 'Building Modern APIs',
  description = 'Best practices for REST and GraphQL in 2026',
  tag = 'Tutorial',
  author = 'Jane Smith',
  site = 'dev.blog',
}: Props) {
  return (
    <div className="w-full h-full bg-slate-900 flex flex-col justify-between p-16 relative overflow-hidden">
      {/* Background glow */}
      <div className="absolute -top-20 -right-20 w-96 h-96 rounded-full bg-pink-500/10 blur-3xl" />
      <div className="absolute -bottom-20 -left-20 w-96 h-96 rounded-full bg-indigo-500/10 blur-3xl" />

      {/* Top: tag */}
      <div className="flex items-center gap-3 z-10">
        <span className="bg-lime-400/15 border border-lime-400/30 rounded-md px-3 py-1 text-lime-400 text-sm font-semibold uppercase tracking-widest">
          {tag}
        </span>
      </div>

      {/* Middle: title + description */}
      <div className="flex flex-col gap-5 z-10">
        <h1 className="text-slate-50 text-6xl font-bold leading-tight tracking-tight">{title}</h1>
        <p className="text-slate-400 text-2xl leading-relaxed">{description}</p>
      </div>

      {/* Bottom: author + site */}
      <div className="flex items-center justify-between z-10">
        <div className="flex items-center gap-4">
          <div className="w-12 h-12 rounded-full bg-gradient-to-br from-pink-400 to-sky-400 flex items-center justify-center text-white text-base font-bold flex-shrink-0">
            {author.slice(0, 2).toUpperCase()}
          </div>
          <div className="flex flex-col gap-0.5">
            <span className="text-slate-200 text-lg font-semibold">{author}</span>
            <span className="text-slate-500 text-sm">5 min read</span>
          </div>
        </div>
        <span className="text-slate-500 text-base font-semibold tracking-wide">{site}</span>
      </div>

      {/* Bottom accent stripe */}
      <div className="absolute bottom-0 left-0 right-0 h-1 bg-gradient-to-r from-pink-400 via-sky-400 to-lime-400" />
    </div>
  );
}
6

Export the image

Run grafex export to render the composition to a PNG. Grafex compiles your TSX, loads the stylesheet, and takes the screenshot — all in one command.
npx grafex export -f card.tsx -o card.png

Dev workflow

The live preview server watches styles.css as a CSS dependency (via config.css). When Tailwind rewrites that file, Grafex detects the change and re-renders within ~100ms — no manual reloads needed.

Two-terminal approach

Open two terminals side by side: one for Tailwind’s watcher, one for the Grafex dev server.
# Terminal 1 — Tailwind watcher
npx @tailwindcss/cli -i ./input.css -o ./styles.css --watch

# Terminal 2 — Grafex dev server
npx grafex dev -f card.tsx
Open http://localhost:3000 in your browser. Edit any class in card.tsx and both tools react automatically.

Single-terminal approach with concurrently

Wire both processes into a single npm run dev command so you only need one terminal.
{
  "scripts": {
    "dev": "concurrently \"npx @tailwindcss/cli -i ./input.css -o ./styles.css --watch\" \"npx grafex dev -f card.tsx\"",
    "build": "npx @tailwindcss/cli -i ./input.css -o ./styles.css && npx grafex export -f card.tsx -o card.png"
  },
  "devDependencies": {
    "@tailwindcss/cli": "^4.0.0",
    "concurrently": "^9.0.0",
    "grafex": "^1.0.0"
  }
}
Run the whole stack with a single command:
npm run dev
If styles.css doesn’t exist when grafex dev starts, Grafex renders without styles and automatically re-renders as soon as Tailwind creates the file. You never need a pre-build step in dev mode.

Build docs developers (and LLMs) love