Session 15: CSP bugs fixed, QA passed, marketing materials ready
This commit is contained in:
parent
0cefaf71d1
commit
58bbc9965d
9 changed files with 456 additions and 19 deletions
146
projects/business/marketing/devto-article.md
Normal file
146
projects/business/marketing/devto-article.md
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
---
|
||||
title: "I Built an HTML-to-PDF API in a Day — Here's How It Works"
|
||||
published: false
|
||||
tags: node, javascript, api, pdf
|
||||
---
|
||||
|
||||
Every developer has that one problem they keep solving over and over. For me, it's PDF generation.
|
||||
|
||||
Invoice for a freelance project? PDF. Report for a dashboard? PDF. Receipt for an e-commerce app? PDF. And every time, I'd end up in the same rabbit hole: installing wkhtmltopdf, fighting with Docker images, or configuring Puppeteer from scratch.
|
||||
|
||||
So I built [DocFast](https://docfast.dev) — a simple API that takes HTML or Markdown and returns a PDF. Here's how it works under the hood.
|
||||
|
||||
## The Architecture
|
||||
|
||||
DocFast is straightforward:
|
||||
|
||||
- **Express** handles the API layer
|
||||
- **Puppeteer** (headless Chromium) does the actual rendering
|
||||
- A **pool of browser instances** keeps things fast
|
||||
|
||||
The core flow is:
|
||||
|
||||
1. You POST HTML/Markdown + options to the API
|
||||
2. The server loads it into a pooled Chromium page
|
||||
3. Chromium renders it and exports to PDF
|
||||
4. You get the PDF back
|
||||
|
||||
That's it. No queue, no webhook callback, no async polling. Request in, PDF out.
|
||||
|
||||
## Why Puppeteer Over wkhtmltopdf?
|
||||
|
||||
I tried both. wkhtmltopdf is fast but uses an ancient WebKit engine — modern CSS (flexbox, grid, custom properties) breaks in weird ways. Puppeteer uses actual Chromium, so if it looks right in Chrome, it looks right in the PDF.
|
||||
|
||||
The tradeoff is resource usage. Chromium is heavy. That's where the browser pool comes in — instead of launching a new browser per request, I maintain a pool of warm instances. A new page in an existing browser takes ~50ms vs ~2s for a cold start.
|
||||
|
||||
## API Design Choices
|
||||
|
||||
I wanted the API to feel obvious. If you've used any REST API, you already know how to use DocFast.
|
||||
|
||||
### Basic HTML to PDF
|
||||
|
||||
```bash
|
||||
curl -X POST https://docfast.dev/v1/convert/html \
|
||||
-H "Authorization: Bearer YOUR_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"html": "<h1>Invoice #1042</h1><p>Amount: $250.00</p>"}' \
|
||||
--output invoice.pdf
|
||||
```
|
||||
|
||||
### Markdown to PDF
|
||||
|
||||
```bash
|
||||
curl -X POST https://docfast.dev/v1/convert/html \
|
||||
-H "Authorization: Bearer YOUR_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"markdown": "# Monthly Report\n\n| Metric | Value |\n|--------|-------|\n| Users | 1,204 |"}' \
|
||||
--output report.pdf
|
||||
```
|
||||
|
||||
### With Options
|
||||
|
||||
```javascript
|
||||
const response = await fetch('https://docfast.dev/v1/convert/html', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': 'Bearer YOUR_API_KEY',
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
html: '<h1>Styled Doc</h1>',
|
||||
css: 'h1 { color: navy; font-family: Georgia; }',
|
||||
options: {
|
||||
format: 'A4',
|
||||
margin: { top: '20mm', bottom: '20mm' },
|
||||
header: '<div style="font-size:10px;text-align:right;">Page <span class="pageNumber"></span></div>',
|
||||
footer: '<div style="font-size:10px;text-align:center;">Confidential</div>'
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
const pdf = await response.blob();
|
||||
```
|
||||
|
||||
A few design decisions I'm happy with:
|
||||
|
||||
- **HTML and Markdown in the same endpoint.** Send `html` or `markdown` — the API figures it out. No separate routes.
|
||||
- **CSS as a separate field.** Keeps your HTML clean. You can also inline it, obviously.
|
||||
- **Sensible defaults.** If you send just `{"html": "..."}`, you get an A4 PDF with reasonable margins. No required options.
|
||||
|
||||
## Built-in Templates
|
||||
|
||||
This is the part I'm most excited about. DocFast ships with templates for common document types:
|
||||
|
||||
```javascript
|
||||
const response = await fetch('https://docfast.dev/v1/convert/html', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': 'Bearer YOUR_API_KEY',
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
template: 'invoice',
|
||||
data: {
|
||||
company: 'Acme Inc.',
|
||||
items: [
|
||||
{ description: 'Web Development', quantity: 40, rate: 150 },
|
||||
{ description: 'Design Review', quantity: 5, rate: 150 }
|
||||
],
|
||||
due_date: '2026-03-01'
|
||||
}
|
||||
})
|
||||
});
|
||||
```
|
||||
|
||||
You pass structured data, the template handles layout and styling. No HTML authoring needed for standard documents. Currently there are templates for invoices, receipts, and reports — more coming based on what people actually need.
|
||||
|
||||
## Performance
|
||||
|
||||
Some rough numbers from production:
|
||||
|
||||
- Simple HTML (text, basic styling): **~200ms**
|
||||
- Complex HTML (tables, images, custom fonts): **~800ms**
|
||||
- Template with data injection: **~400ms**
|
||||
|
||||
Most of the time is Chromium rendering. The API overhead is minimal. For comparison, spinning up Puppeteer yourself (cold start in a Lambda/Cloud Function) typically takes 3-8 seconds.
|
||||
|
||||
## Pricing and Why There's a Free Tier
|
||||
|
||||
Free tier: **100 PDFs/month**, no credit card required. Enough for side projects, prototyping, or low-volume internal tools.
|
||||
|
||||
Pro: **$9/month for 10,000 PDFs**. That's $0.0009 per PDF.
|
||||
|
||||
I wanted the free tier to be actually usable, not a glorified trial. If you're generating fewer than 100 PDFs a month, you never need to pay. If your project takes off and you need more, $9/mo is less than most developers spend on coffee in a week.
|
||||
|
||||
## What I'd Do Differently
|
||||
|
||||
If I rebuilt this from scratch:
|
||||
|
||||
- **I'd start with templates earlier.** The raw HTML→PDF conversion was the obvious MVP, but templates are what people actually get excited about.
|
||||
- **I'd add a preview endpoint sooner.** Being able to see the PDF in-browser before committing to generation saves a lot of back-and-forth.
|
||||
|
||||
## Try It
|
||||
|
||||
The docs are at [docfast.dev/docs](https://docfast.dev/docs). You can grab an API key in about 30 seconds.
|
||||
|
||||
If you have feedback on the API design, templates you'd want, or bugs — I'm all ears. Building this solo, so every piece of feedback actually gets read.
|
||||
66
projects/business/marketing/reddit-posts.md
Normal file
66
projects/business/marketing/reddit-posts.md
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
# Reddit Posts
|
||||
|
||||
---
|
||||
|
||||
## r/webdev
|
||||
|
||||
**Title:** Built an HTML-to-PDF API — looking for feedback on the API design
|
||||
|
||||
**Body:**
|
||||
|
||||
Hey r/webdev,
|
||||
|
||||
I've been working on a small API service called [DocFast](https://docfast.dev) that converts HTML or Markdown to PDF. The idea came from rebuilding the same Puppeteer-based PDF pipeline across multiple projects.
|
||||
|
||||
The basic idea: POST your HTML, get a PDF back. It also has built-in templates for common docs like invoices so you can just pass JSON data instead of writing HTML.
|
||||
|
||||
Quick example:
|
||||
|
||||
```javascript
|
||||
const res = await fetch('https://docfast.dev/v1/convert/html', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': 'Bearer YOUR_KEY',
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
html: '<h1>Hello</h1><p>This becomes a PDF.</p>',
|
||||
options: { format: 'A4' }
|
||||
})
|
||||
});
|
||||
```
|
||||
|
||||
There's a free tier (100 PDFs/month, no credit card) if anyone wants to try it.
|
||||
|
||||
I'm specifically looking for feedback on:
|
||||
- The API design — does the interface feel intuitive?
|
||||
- What templates would be most useful? (Currently have invoice, receipt, report)
|
||||
- Anything you'd expect from a PDF API that's missing?
|
||||
|
||||
Docs are at https://docfast.dev/docs. Happy to answer any questions about the architecture too (Express + Puppeteer with a browser pool).
|
||||
|
||||
---
|
||||
|
||||
## r/node
|
||||
|
||||
**Title:** Managing a Puppeteer browser pool for PDF generation — lessons learned
|
||||
|
||||
**Body:**
|
||||
|
||||
I built an API service ([DocFast](https://docfast.dev)) that generates PDFs from HTML using Puppeteer, and wanted to share some things I learned about running Puppeteer in production with Node.
|
||||
|
||||
**The problem:** Launching a new Chromium instance per request is slow (~2-3s). For an API that needs to respond quickly, that's not acceptable.
|
||||
|
||||
**The solution:** A browser pool. I keep a set of warm Chromium instances and create new *pages* (not browsers) per request. New page creation takes ~50ms vs seconds for a cold browser launch.
|
||||
|
||||
Key things I learned:
|
||||
|
||||
1. **Memory management matters.** Each Chromium instance uses 100-300MB. You need to cap your pool size based on available memory and restart instances periodically to avoid leaks.
|
||||
|
||||
2. **Page cleanup is critical.** After each PDF generation, you need to properly close the page and clean up listeners. Forgetting this leads to slow memory leaks that only show up after hours of traffic.
|
||||
|
||||
3. **Graceful degradation.** If all pooled instances are busy, you have two choices: queue the request or spin up a temporary instance. I went with queuing + a small overflow pool.
|
||||
|
||||
4. **Font rendering is OS-dependent.** The same HTML can look different depending on what fonts are installed on the host system. I ended up bundling a standard set of fonts in the Docker image.
|
||||
|
||||
The API is live at https://docfast.dev if anyone wants to poke at it (free tier, 100 PDFs/mo). But mostly curious if others have dealt with similar Puppeteer pooling challenges and what approaches worked for you.
|
||||
25
projects/business/marketing/show-hn.md
Normal file
25
projects/business/marketing/show-hn.md
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
# Show HN: DocFast – HTML/Markdown to PDF API with built-in templates
|
||||
|
||||
I built a simple API for generating PDFs from HTML or Markdown. It's at https://docfast.dev
|
||||
|
||||
**Why I built it:** Every time I needed to generate invoices, reports, or receipts in a side project, I'd end up wrestling with wkhtmltopdf configs or spinning up a headless browser. I wanted a single API call that just works.
|
||||
|
||||
**What it does:**
|
||||
- Send HTML or Markdown, get a PDF back
|
||||
- Built-in templates for common docs (invoices, receipts, reports)
|
||||
- Supports custom CSS, headers/footers, page sizes
|
||||
- Fast — most PDFs generate in under 2 seconds
|
||||
|
||||
**Quick example:**
|
||||
|
||||
```bash
|
||||
curl -X POST https://docfast.dev/v1/convert/html \
|
||||
-H "Authorization: Bearer YOUR_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"html": "<h1>Hello World</h1><p>Generated with DocFast.</p>"}' \
|
||||
--output hello.pdf
|
||||
```
|
||||
|
||||
**Pricing:** Free tier gives you 100 PDFs/month (no credit card). Pro is $9/mo for 10,000 PDFs.
|
||||
|
||||
Built it solo. Would appreciate any feedback on the API design or docs (https://docfast.dev/docs).
|
||||
98
projects/business/marketing/strategy.md
Normal file
98
projects/business/marketing/strategy.md
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
# DocFast 30-Day Launch Marketing Plan
|
||||
|
||||
**Budget: $0** — organic channels only.
|
||||
|
||||
---
|
||||
|
||||
## Week 1: Launch (Days 1–7)
|
||||
|
||||
### Day 1 — Launch Day
|
||||
| Channel | Action | Expected Impact |
|
||||
|---------|--------|-----------------|
|
||||
| Hacker News | Post "Show HN" (see show-hn.md) | 50–200 visits if it gains traction; HN is hit-or-miss but high-quality traffic |
|
||||
| Twitter/X | Tweet #1 (announcement) + #5 (pain point) | Reach depends on existing following; pin the announcement tweet |
|
||||
| DEV.to | Publish article (see devto-article.md) | Steady long-tail traffic; DEV.to articles rank well on Google |
|
||||
|
||||
### Day 2–3
|
||||
| Channel | Action | Expected Impact |
|
||||
|---------|--------|-----------------|
|
||||
| Reddit r/webdev | Post feedback request (see reddit-posts.md) | 20–100 visits; genuine feedback |
|
||||
| Reddit r/node | Post technical discussion (see reddit-posts.md) | Smaller but more targeted audience |
|
||||
| Indie Hackers | Post in "Show IH" — focus on the solo-builder story, pricing decisions | Community is supportive of solo launches |
|
||||
|
||||
### Day 4–7
|
||||
| Channel | Action | Expected Impact |
|
||||
|---------|--------|-----------------|
|
||||
| Twitter/X | Tweet #2 (code example) | Code snippets get good engagement from devs |
|
||||
| DEV.to | Engage with comments on your article | Builds credibility, surfaces article in feeds |
|
||||
| HN | If Show HN didn't gain traction, resubmit once (allowed by HN rules) | Second attempts sometimes work better |
|
||||
|
||||
---
|
||||
|
||||
## Week 2: Content (Days 8–14)
|
||||
|
||||
Focus: Create useful content that naturally references DocFast.
|
||||
|
||||
| Day | Channel | Content |
|
||||
|-----|---------|---------|
|
||||
| 8 | DEV.to | "5 Ways to Generate PDFs in Node.js (Compared)" — honest comparison including DocFast |
|
||||
| 10 | Twitter/X | Tweet #3 (comparison) + short thread on PDF generation approaches |
|
||||
| 12 | Reddit r/webdev | Comment helpfully on any PDF-related questions (don't force it — only if genuinely relevant) |
|
||||
| 14 | Twitter/X | Tweet #4 (use case — invoices) |
|
||||
|
||||
---
|
||||
|
||||
## Week 3: Community (Days 15–21)
|
||||
|
||||
Focus: Engage where developers already discuss PDF problems.
|
||||
|
||||
| Action | Where | Notes |
|
||||
|--------|-------|-------|
|
||||
| Answer PDF-related questions | Stack Overflow, Reddit | Don't shill. Answer the question, mention DocFast only if it's genuinely the best answer |
|
||||
| Post on r/SaaS | Reddit | "I launched a developer API at $9/mo — here's what I learned in the first 2 weeks" |
|
||||
| Share usage stats / lessons | Indie Hackers, Twitter | Transparency builds trust. Share real numbers |
|
||||
| DEV.to article #2 | DEV.to | "How I Handle 10,000 PDFs/Month with Express + Puppeteer" — technical deep-dive |
|
||||
|
||||
---
|
||||
|
||||
## Week 4: Iterate (Days 22–30)
|
||||
|
||||
Focus: Double down on what worked, drop what didn't.
|
||||
|
||||
| Action | Details |
|
||||
|--------|---------|
|
||||
| Review analytics | Which channel drove the most signups? Most API usage? |
|
||||
| Write a "1 month in" post | Indie Hackers or DEV.to — share real metrics, lessons, what you'd change |
|
||||
| Engage repeat visitors | If anyone tweeted about DocFast, reply and thank them |
|
||||
| Plan month 2 | Based on data: more content? Different subreddits? Guest posts? |
|
||||
|
||||
---
|
||||
|
||||
## Ongoing (Every Week)
|
||||
|
||||
- **Monitor Reddit/HN/SO** for "pdf generation" discussions — contribute genuinely
|
||||
- **Tweet 2–3x/week** — mix of product updates, developer tips, and PDF-related content
|
||||
- **Respond to every piece of feedback** within 24 hours
|
||||
|
||||
---
|
||||
|
||||
## Channel Summary
|
||||
|
||||
| Channel | Effort | Expected Impact | Best For |
|
||||
|---------|--------|-----------------|----------|
|
||||
| Hacker News | Low (1 post) | High variance — could be 10 or 10,000 visits | Launch spike |
|
||||
| DEV.to | Medium (2–3 articles) | Steady long-tail SEO traffic | Ongoing discovery |
|
||||
| Twitter/X | Medium (2–3 tweets/week) | Builds over time; compounds | Developer brand |
|
||||
| Reddit | Low-Medium | Targeted, high-intent traffic | Early feedback |
|
||||
| Indie Hackers | Low (2 posts) | Small but supportive community | Solo founder story |
|
||||
| Stack Overflow | Low (answer questions) | Very high intent (people searching for solutions) | Long-tail conversions |
|
||||
|
||||
---
|
||||
|
||||
## Key Principles
|
||||
|
||||
1. **Be useful first.** Every post should provide value even if DocFast didn't exist.
|
||||
2. **Don't post and ghost.** Reply to every comment. People remember that.
|
||||
3. **Share real numbers.** "We got 47 signups in 2 weeks" is more compelling than "growing fast."
|
||||
4. **One channel at a time.** Don't try to be everywhere on day 1. Stagger posts across the week.
|
||||
5. **Track everything.** UTM parameters on every link. Know what works.
|
||||
57
projects/business/marketing/tweets.md
Normal file
57
projects/business/marketing/tweets.md
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
# DocFast Launch Tweets
|
||||
|
||||
## 1. Announcement
|
||||
|
||||
I built an HTML-to-PDF API because I was tired of configuring Puppeteer for every side project.
|
||||
|
||||
→ Send HTML or Markdown, get a PDF back
|
||||
→ Built-in templates (invoices, receipts, reports)
|
||||
→ Free tier: 100 PDFs/mo
|
||||
|
||||
https://docfast.dev
|
||||
|
||||
## 2. Code Example
|
||||
|
||||
Generate a PDF in one curl command:
|
||||
|
||||
```
|
||||
curl -X POST https://docfast.dev/v1/convert/html \
|
||||
-H "Authorization: Bearer $KEY" \
|
||||
-d '{"html": "<h1>Done.</h1>"}' \
|
||||
-o doc.pdf
|
||||
```
|
||||
|
||||
No config files. No Docker. No Puppeteer setup.
|
||||
|
||||
Free tier: 100 PDFs/mo → https://docfast.dev
|
||||
|
||||
## 3. Comparison to Alternatives
|
||||
|
||||
PDF generation options for developers:
|
||||
|
||||
• wkhtmltopdf — ancient WebKit, breaks on modern CSS
|
||||
• Self-hosted Puppeteer — works, but you're managing Chromium in prod
|
||||
• Enterprise APIs — $50+/mo for basic usage
|
||||
|
||||
I built DocFast: modern rendering, simple API, free tier (100/mo), $9/mo for 10K.
|
||||
|
||||
https://docfast.dev
|
||||
|
||||
## 4. Use Case
|
||||
|
||||
If your app generates invoices, you've probably spent more time on PDF layout than on the actual billing logic.
|
||||
|
||||
DocFast has built-in invoice templates. Pass your data as JSON, get a styled PDF back. No HTML required.
|
||||
|
||||
https://docfast.dev/docs
|
||||
|
||||
## 5. Pain Point
|
||||
|
||||
The PDF generation starter pack:
|
||||
- Install Puppeteer
|
||||
- Debug Chromium dependencies on Linux
|
||||
- Figure out why fonts look wrong
|
||||
- Add 800MB to your Docker image
|
||||
- Question your career choices
|
||||
|
||||
Or just call an API: https://docfast.dev
|
||||
Loading…
Add table
Add a link
Reference in a new issue