Glyph vs react-pdf for PDF Generation
When building React applications that generate PDFs, react-pdf has been a popular choice for its React-native approach to document construction. Glyph takes a fundamentally different philosophy: template-based documents with AI-powered customization, requiring zero layout code.
This guide provides an objective comparison to help you choose the right tool for your use case.
Quick Comparison
Section titled “Quick Comparison”| Feature | Glyph | react-pdf |
|---|---|---|
| Approach | Templates + AI modifications | Programmatic layout components |
| Setup complexity | 2 lines of code | Component tree construction |
| Learning curve | Low (describe what you want) | Medium (learn Document, Page, View, Text APIs) |
| Styling method | CSS in templates | StyleSheet objects (CSS-like but limited) |
| End-user editing | Built-in web component | Not available |
| AI customization | Native | Not available |
| Runtime | API-based (any stack) | React/Node.js required |
| Template reuse | Yes (template library) | Copy/paste component code |
| Non-developer editing | Yes (natural language) | No (requires code changes) |
| Flexbox support | Full CSS flexbox | Partial (react-pdf subset) |
Code Complexity Comparison
Section titled “Code Complexity Comparison”Generating a Simple Invoice PDF
Section titled “Generating a Simple Invoice PDF”// Generate a polished invoice in secondsconst response = await fetch('https://api.glyph.you/v1/create', { method: 'POST', headers: { 'Authorization': 'Bearer gk_your_api_key', 'Content-Type': 'application/json' }, body: JSON.stringify({ template: 'invoice-clean', data: { invoice: { number: 'INV-001', date: '2024-01-15' }, client: { name: 'Acme Corp', email: 'billing@acme.com' }, lineItems: [ { description: 'Consulting', quantity: 10, unitPrice: 150, total: 1500 }, { description: 'Development', quantity: 20, unitPrice: 125, total: 2500 } ], totals: { subtotal: 4000, tax: 360, total: 4360 } } })});
const { url } = await response.json();// Done. Professional PDF hosted at `url`import React from 'react';import { Document, Page, Text, View, StyleSheet } from '@react-pdf/renderer';
// First, define all your stylesconst styles = StyleSheet.create({ page: { padding: 30 }, header: { flexDirection: 'row', justifyContent: 'space-between', marginBottom: 20 }, title: { fontSize: 24, fontWeight: 'bold' }, invoiceInfo: { textAlign: 'right' }, clientSection: { marginBottom: 20 }, table: { display: 'table', width: '100%' }, tableRow: { flexDirection: 'row', borderBottom: 1, borderColor: '#eee' }, tableHeader: { backgroundColor: '#f0f0f0', fontWeight: 'bold' }, tableCell: { padding: 8, flex: 1 }, tableCellDescription: { flex: 3 }, totals: { marginTop: 20, alignItems: 'flex-end' }, totalRow: { flexDirection: 'row', width: 200 }, totalLabel: { flex: 1 }, totalValue: { width: 80, textAlign: 'right' }});
// Then build the document structureconst Invoice = ({ data }) => ( <Document> <Page size="A4" style={styles.page}> <View style={styles.header}> <Text style={styles.title}>INVOICE</Text> <View style={styles.invoiceInfo}> <Text>{data.invoice.number}</Text> <Text>{data.invoice.date}</Text> </View> </View>
<View style={styles.clientSection}> <Text style={{ fontWeight: 'bold' }}>Bill To:</Text> <Text>{data.client.name}</Text> <Text>{data.client.email}</Text> </View>
<View style={styles.table}> <View style={[styles.tableRow, styles.tableHeader]}> <Text style={[styles.tableCell, styles.tableCellDescription]}>Description</Text> <Text style={styles.tableCell}>Qty</Text> <Text style={styles.tableCell}>Rate</Text> <Text style={styles.tableCell}>Amount</Text> </View>
{data.lineItems.map((item, i) => ( <View key={i} style={styles.tableRow}> <Text style={[styles.tableCell, styles.tableCellDescription]}>{item.description}</Text> <Text style={styles.tableCell}>{item.quantity}</Text> <Text style={styles.tableCell}>${item.unitPrice}</Text> <Text style={styles.tableCell}>${item.total}</Text> </View> ))} </View>
<View style={styles.totals}> <View style={styles.totalRow}> <Text style={styles.totalLabel}>Subtotal:</Text> <Text style={styles.totalValue}>${data.totals.subtotal}</Text> </View> <View style={styles.totalRow}> <Text style={styles.totalLabel}>Tax:</Text> <Text style={styles.totalValue}>${data.totals.tax}</Text> </View> <View style={styles.totalRow}> <Text style={[styles.totalLabel, { fontWeight: 'bold' }]}>Total:</Text> <Text style={[styles.totalValue, { fontWeight: 'bold' }]}>${data.totals.total}</Text> </View> </View> </Page> </Document>);
// Then render itimport { pdf } from '@react-pdf/renderer';const blob = await pdf(<Invoice data={invoiceData} />).toBlob();Lines of code: Glyph ~15 vs react-pdf ~80+ (and Glyph’s template is pre-designed)
Modifying Document Styles
Section titled “Modifying Document Styles”// User wants a more modern lookconst response = await fetch('https://api.glyph.you/v1/modify', { method: 'POST', headers: { 'Authorization': 'Bearer gk_your_api_key', 'Content-Type': 'application/json' }, body: JSON.stringify({ sessionId: 'session-id', prompt: 'Make the design more modern with a navy header, clean sans-serif fonts, and subtle gray line separators' })});
// AI applies comprehensive style changes automaticallyconst { html } = await response.json();// You need to manually update every style property
const styles = StyleSheet.create({ page: { padding: 30, fontFamily: 'Helvetica' // Limited font options }, header: { flexDirection: 'row', justifyContent: 'space-between', marginBottom: 20, backgroundColor: '#1e3a5f', // Manual: add navy background padding: 15, // Manual: add padding color: 'white' // Manual: change text color }, title: { fontSize: 24, fontWeight: 'bold', color: 'white' // Manual: update for contrast }, // ... update every other style manually tableRow: { flexDirection: 'row', borderBottom: 1, borderColor: '#e5e5e5' // Manual: subtle gray }, // What about "more modern"? That's subjective. // react-pdf can't interpret design intent.});
// Every style change requires:// 1. Code modification// 2. Re-build// 3. Re-deployThe difference: Glyph understands design intent and applies comprehensive changes. react-pdf requires explicit property-by-property updates.
Providing End-User Customization
Section titled “Providing End-User Customization”<!-- Drop-in component for user editing --><script src="https://sdk.glyph.you/glyph.min.js"></script>
<glyph-editor api-key="gk_your_key" template="invoice-clean" :data="invoiceData"></glyph-editor>
<!-- Users can: - Click any section to select it - Type "make this blue" or "add my logo here" - See changes in real-time - Download final PDF All with zero additional code.-->// react-pdf generates PDFs but provides no editing UI.// You would need to build:
// 1. A preview component (react-pdf/renderer can show in browser)import { PDFViewer } from '@react-pdf/renderer';<PDFViewer><Invoice data={data} /></PDFViewer>
// 2. A complete editing interfaceconst [styles, setStyles] = useState(defaultStyles);const [content, setContent] = useState(defaultContent);
// 3. Color pickers, font selectors, spacing controls...<ColorPicker value={styles.header.backgroundColor} onChange={...} /><FontSelect value={styles.page.fontFamily} onChange={...} /><SpacingControl value={styles.page.padding} onChange={...} />
// 4. Logic to map UI changes to StyleSheet updates// 5. State management for undo/redo// 6. Save/export functionality
// This is 500-1000+ lines of code minimum.// And users still can't describe changes in natural language.The difference: Glyph provides complete end-user editing with natural language. react-pdf is render-only.
When to Use react-pdf
Section titled “When to Use react-pdf”react-pdf remains the right choice when you need:
- Pure React ecosystem - You want everything in JSX/React components
- Programmatic layouts - Layouts are computed dynamically from complex logic
- No external dependencies - Everything runs in your Node.js process
- Tight React integration - You’re already using react-pdf in production
- Complex component reuse - You have intricate React component hierarchies
- Client-side generation - PDFs must be generated in the browser
When to Use Glyph
Section titled “When to Use Glyph”Glyph is the better choice when:
- Templates over code - Your documents follow predictable structures
- Non-developers customize - End-users should modify documents without coding
- Speed to production - You want PDFs working today, not next week
- AI-native editing - Natural language modifications are valuable
- Design quality - You need professional templates without design expertise
- Framework agnostic - You’re not using React, or want API-based generation
- Maintenance burden - You don’t want to maintain layout code
Feature Deep Dive
Section titled “Feature Deep Dive”Layout Approach
Section titled “Layout Approach”| Aspect | Glyph | react-pdf |
|---|---|---|
| Layout model | Full HTML/CSS | Yoga (flexbox subset) |
| Grid support | CSS Grid | Not supported |
| Positioning | Full CSS positioning | Limited (no absolute in some contexts) |
| Responsive | Media queries | Manual breakpoint logic |
| CSS features | Full browser CSS | Subset (no gradients, limited shadows) |
Styling Capabilities
Section titled “Styling Capabilities”| Feature | Glyph | react-pdf |
|---|---|---|
| Gradients | Yes (CSS) | No |
| Box shadows | Yes (CSS) | Limited |
| Border radius | Yes (CSS) | Yes |
| Custom fonts | Yes (any web font) | Yes (must register) |
| SVG | Yes (inline) | Yes (basic) |
| Images | Yes (any format) | Yes |
Developer Experience
Section titled “Developer Experience”| Aspect | Glyph | react-pdf |
|---|---|---|
| Time to first PDF | 5 minutes | 30-60 minutes |
| Learning curve | Low (templates + data) | Medium (component APIs) |
| Debugging | Browser DevTools + logs | React DevTools + console |
| Hot reload | Yes (preview API) | Yes (with React setup) |
| Type safety | JSON Schema validation | TypeScript types |
AI Capabilities
Section titled “AI Capabilities”| Capability | Glyph | react-pdf |
|---|---|---|
| Natural language edits | Native | Not available |
| Style interpretation | AI understands “make it modern” | Explicit values only |
| Content guardrails | Self-checking validator | N/A |
| Design suggestions | AI-powered | N/A |
Migration Guide: react-pdf to Glyph
Section titled “Migration Guide: react-pdf to Glyph”Step 1: Identify Your Document Types
Section titled “Step 1: Identify Your Document Types”List the types of documents you generate:
// Before: Multiple react-pdf componentsconst Invoice = ({ data }) => <Document>...</Document>;const Quote = ({ data }) => <Document>...</Document>;const Receipt = ({ data }) => <Document>...</Document>;Map these to Glyph templates (use built-in or create custom).
Step 2: Extract Data Schemas
Section titled “Step 2: Extract Data Schemas”From your react-pdf component props, create JSON schemas:
// Your react-pdf componentconst Invoice = ({ client, // { name, email, address } lineItems, // [{ description, quantity, price }] totals // { subtotal, tax, total }}) => ...{ "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "required": ["client", "lineItems", "totals"], "properties": { "client": { "type": "object", "properties": { "name": { "type": "string" }, "email": { "type": "string" }, "address": { "type": "string" } } }, "lineItems": { "type": "array", "items": { "type": "object", "properties": { "description": { "type": "string" }, "quantity": { "type": "number" }, "price": { "type": "number" } } } }, "totals": { "type": "object", "properties": { "subtotal": { "type": "number" }, "tax": { "type": "number" }, "total": { "type": "number" } } } }}Step 3: Convert Layout to HTML Template
Section titled “Step 3: Convert Layout to HTML Template”Transform your react-pdf components to HTML with Mustache:
// Before (react-pdf)<View style={styles.header}> <Text style={styles.title}>INVOICE</Text> <Text>{data.invoice.number}</Text></View>
{data.lineItems.map((item, i) => ( <View key={i} style={styles.row}> <Text>{item.description}</Text> <Text>${item.price}</Text> </View>))}<!-- After (Glyph template) --><div class="header" data-glyph-region="header"> <h1>INVOICE</h1> <span>{{invoice.number}}</span></div>
{{#lineItems}}<div class="row" data-glyph-region="line-item"> <span>{{description}}</span> <span>${{price}}</span></div>{{/lineItems}}Step 4: Move Styles to CSS
Section titled “Step 4: Move Styles to CSS”Convert StyleSheet objects to CSS:
// Before (react-pdf)const styles = StyleSheet.create({ header: { flexDirection: 'row', justifyContent: 'space-between', padding: 20, backgroundColor: '#f5f5f5' }});/* After (CSS in template) */.header { display: flex; flex-direction: row; justify-content: space-between; padding: 20px; background-color: #f5f5f5;}Step 5: Upload and Use
Section titled “Step 5: Upload and Use”# Upload custom templatecurl -X POST https://api.glyph.you/v1/templates \ -H "Authorization: Bearer gk_your_api_key" \ -F "name=my-invoice" \ -F "template=@./template.html" \ -F "schema=@./schema.json"// Replace generation code// Beforeconst blob = await pdf(<Invoice data={data} />).toBlob();
// Afterconst response = await fetch('https://api.glyph.you/v1/create', { method: 'POST', headers: { 'Authorization': 'Bearer gk_your_api_key', 'Content-Type': 'application/json' }, body: JSON.stringify({ template: 'my-invoice', data })});const { url } = await response.json();Step 6: Add End-User Editing (Bonus)
Section titled “Step 6: Add End-User Editing (Bonus)”With Glyph, you can now offer something react-pdf never could:
<glyph-editor api-key="gk_your_key" template="my-invoice" :data="invoiceData" @glyph:ready="onEditorReady" @glyph:generated="onPdfGenerated"></glyph-editor>Users can now customize their documents with natural language.
Cost Comparison
Section titled “Cost Comparison”| Factor | Glyph | react-pdf |
|---|---|---|
| Library cost | API pricing ($0-129/mo) | Free (MIT license) |
| Development time | Hours | Days to weeks |
| Design expertise | Not required (templates) | Required (build layouts) |
| Maintenance | Zero (SaaS) | Ongoing (your code) |
| End-user editing | Included | Build from scratch |
Summary
Section titled “Summary”Choose Glyph if your documents follow templates, you want AI-powered customization, you need end-user editing, or you want to ship fast without writing layout code.
Choose react-pdf if you need everything in React components, your layouts are highly dynamic/computed, you want zero external dependencies, or you have significant existing react-pdf investment.
Both tools generate PDFs. Glyph is template-first with AI superpowers. react-pdf is code-first with React ergonomics. Choose based on whether your documents are template-based or programmatically constructed.
Next Steps
Section titled “Next Steps”- Quick Start - Generate your first PDF in 5 minutes
- Templates - Browse built-in templates
- Custom Templates - Create your own templates
- SDK Overview - Add end-user editing to your app