Skip to content

Commit d233c9d

Browse files
docs: enhance README with detailed features, usage instructions, and Docker setup
1 parent 0df930d commit d233c9d

1 file changed

Lines changed: 183 additions & 110 deletions

File tree

README.md

Lines changed: 183 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -4,182 +4,255 @@
44

55
---
66

7+
# Fast HTML to PDF, Screenshots, and Video API
78

9+
A lightweight, high-performance rendering API built on Puppeteer. This is the open-source version of the software powering [html2pdfapi.com](https://html2pdfapi.com).
810

11+
## Features
912

10-
# Fast HTML to PDF, Screenshots, and Video API
13+
- 📸 PNG, JPEG, WebP, GIF, AVIF screenshots from any URL or HTML
14+
- 📄 PDF generation with full page layout control
15+
- 🎬 MP4 video recording with smooth scroll animation
16+
- 🌐 Full HTML capture with all resources embedded inline
17+
- ⚡ Browser pool with configurable recycling and warmup
18+
- 🔧 Structured JSON logging (Pino)
19+
- 🐳 Docker-ready with CI pipeline
1120

12-
Welcome to the **Fast HTML to PDF, Screenshots, and Video API**! 🚀
21+
## Getting Started
1322

14-
This is a lightweight version of the software used at [html2pdfapi.com](https://html2pdfapi.com).
23+
### Requirements
1524

16-
It provides a basic yet performant wrapper along with additional features to enhance the standard Puppeteer experience.
25+
- Node.js 24+
26+
- FFmpeg (for video recording)
1727

18-
## Features
28+
### Local Development
1929

20-
✅ Generate PNG images from any URL or HTML content<br>
21-
✅ Generate PDFs from any URL or HTML content<br>
22-
✅ Generate Videos from any URL with smooth animation<br>
23-
**Direct HTML rendering** - Pass HTML content directly without needing a URL<br>
24-
✅ Support for custom headers (like Authorization)<br>
25-
✅ Support to render Lazy animations<br>
26-
✅ Additional support for blocking: Cookies, Ads, Trackers, Banner<br>
27-
✅ High-Performance webserver<br>
28-
✅ Extended and simplified API wrapper to Puppeteer
30+
```bash
31+
npm install
32+
npm run dev
33+
```
2934

35+
The server starts on `http://localhost:3000`. API docs are available at `/docs`.
3036

31-
## License
37+
For video support on macOS (Homebrew):
3238

33-
For usage in commercial services, please refer to the `license.txt` file in this repository.
39+
```bash
40+
FFMPEG_PATH=/opt/homebrew/bin/ffmpeg npm run dev
41+
```
3442

35-
Note: License is not enforced, but we are a small team, and any support to further develop this product would be greatly appreciated! 🙏
43+
### Docker
44+
45+
Pull from the GitHub Container Registry:
46+
47+
```bash
48+
docker pull ghcr.io/carbogninalberto/fast-html-to-pdf-api:latest
49+
docker run -p 3000:3000 ghcr.io/carbogninalberto/fast-html-to-pdf-api:latest
50+
```
51+
52+
Or build locally:
53+
54+
```bash
55+
docker build . -t bakney/fastrender
56+
docker run -p 3000:3000 bakney/fastrender
57+
```
58+
59+
For ARM-based machines (Apple Silicon):
60+
61+
```bash
62+
docker build --platform linux/amd64 . -t render
63+
docker run --platform linux/amd64 -p 3000:3000 render
64+
```
3665

3766
## API Usage
3867

39-
### Render from URL
68+
### Endpoints
69+
70+
| Endpoint | Method | Description |
71+
|----------|--------|-------------|
72+
| `/render` | POST | Render URL or HTML to PDF/Image/Video/HTML |
73+
| `/render?config=...` | GET | Same as above, with JSON config as query param |
74+
| `/health` | GET | Health check with browser pool stats |
75+
| `/ping` | GET | Simple connectivity check (returns `"pong"`) |
76+
| `/docs` | GET | Swagger API documentation |
77+
78+
### Request Parameters
79+
80+
| Parameter | Type | Required | Description |
81+
|-----------|------|----------|-------------|
82+
| `url` | string | One of `url` or `html` | URL to render |
83+
| `html` | string | One of `url` or `html` | Raw HTML content to render |
84+
| `type` | string | Yes | `image`, `pdf`, `video`, or `html` |
85+
| `device` | object | No | Viewport settings (width, height, userAgent) |
86+
| `render` | object | No | Render options (waitTime, fullPage, scroll) |
87+
| `image` | object | No | Image settings (type, quality, compression, crop, resize, rotation) |
88+
| `pdf` | object | No | PDF settings (format, margins, orientation, header/footer) |
89+
| `video` | object | No | Video settings (fps, duration, codec, bitrate, crf, preset) |
4090

41-
Use the Playground at [html2pdfapi](https://html2pdfapi.com/playground) (a free account is required), to create the API request in your favorite language.
42-
You can omit the `apiKey` parameter.
91+
### Examples
92+
93+
**Screenshot from URL:**
4394

44-
**Example - Generate PDF from URL:**
4595
```bash
4696
curl -X POST http://localhost:3000/render \
4797
-H "Content-Type: application/json" \
48-
-d '{
49-
"url": "https://example.com",
50-
"type": "pdf"
51-
}' \
52-
--output output.pdf
98+
-d '{"url": "https://example.com", "type": "image"}' \
99+
--output screenshot.png
53100
```
54101

55-
### Render from HTML Content
102+
**PDF from HTML:**
56103

57-
You can now pass HTML content directly to the API without needing a URL! This is perfect for:
58-
- Generating PDFs from dynamically created HTML
59-
- Creating images from HTML templates
60-
- Converting HTML email templates to images
61-
- Any scenario where you have HTML as a string
62-
63-
**Example - Generate PDF from HTML:**
64104
```bash
65105
curl -X POST http://localhost:3000/render \
66106
-H "Content-Type: application/json" \
67107
-d '{
68-
"html": "<!DOCTYPE html><html><head><title>My Document</title><style>body { font-family: Arial; padding: 40px; } h1 { color: #333; }</style></head><body><h1>Hello World!</h1><p>This PDF was generated from HTML content.</p></body></html>",
69-
"type": "pdf"
108+
"html": "<!DOCTYPE html><html><body><h1>Hello</h1></body></html>",
109+
"type": "pdf",
110+
"pdf": {"format": "A4", "margin": {"top": "20px", "bottom": "20px"}}
70111
}' \
71112
--output output.pdf
72113
```
73114

74-
**Example - Generate PNG from HTML:**
115+
**WebP image with custom quality:**
116+
75117
```bash
76118
curl -X POST http://localhost:3000/render \
77119
-H "Content-Type: application/json" \
78-
-d '{
79-
"html": "<!DOCTYPE html><html><head><style>body { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; display: flex; justify-content: center; align-items: center; height: 100vh; font-family: sans-serif; } .card { background: rgba(255,255,255,0.1); padding: 40px; border-radius: 20px; }</style></head><body><div class=\"card\"><h1>Beautiful Card</h1><p>Rendered from HTML!</p></div></body></html>",
80-
"type": "image",
81-
"image": { "type": "png" }
82-
}' \
83-
--output output.png
120+
-d '{"url": "https://example.com", "type": "image", "image": {"type": "webp", "quality": 80}}' \
121+
--output output.webp
84122
```
85123

86-
**Example - With Custom Options:**
124+
**Video with scroll animation:**
125+
87126
```bash
88127
curl -X POST http://localhost:3000/render \
89128
-H "Content-Type: application/json" \
90129
-d '{
91-
"html": "<html><body><h1>Custom Settings</h1></body></html>",
92-
"type": "pdf",
93-
"device": {
94-
"width": 800,
95-
"height": 600
96-
},
97-
"pdf": {
98-
"format": "Letter",
99-
"printBackground": true,
100-
"margin": {
101-
"top": "20px",
102-
"right": "20px",
103-
"bottom": "20px",
104-
"left": "20px"
105-
}
106-
}
130+
"url": "https://example.com",
131+
"type": "video",
132+
"video": {"fps": 24},
133+
"render": {"scroll": {"animate": true, "duration": 3000}}
107134
}' \
108-
--output custom.pdf
135+
--output output.mp4
109136
```
110137

111-
**Important Notes:**
112-
- Either `url` OR `html` must be provided (not both)
113-
- All standard options (device settings, PDF options, image options, etc.) work with both URL and HTML modes
114-
- When using HTML content, network idle wait conditions (`networkidle0`, `networkidle2`) are automatically adjusted to prevent timeouts
138+
**Full HTML capture (resources embedded as data URIs):**
115139

116-
The Saas solution of our service provides out-of-the-box async support so that you don't have to implement your own.
140+
```bash
141+
curl -X POST http://localhost:3000/render \
142+
-H "Content-Type: application/json" \
143+
-d '{"url": "https://example.com", "type": "html"}' \
144+
--output page.html
145+
```
117146

118-
There are many libraries you can use to achieve it, it depends on the language you are using, this is a very lightweight and versatile solution if you are looking
119-
for a simple, yet performant solution.
147+
**GET request with config parameter:**
120148

121-
## API Reference
149+
```bash
150+
curl "http://localhost:3000/render?config=%7B%22url%22%3A%22https%3A%2F%2Fexample.com%22%2C%22type%22%3A%22image%22%7D" \
151+
--output screenshot.png
152+
```
122153

123-
### Endpoints
154+
## Configuration
124155

125-
| Endpoint | Method | Description |
126-
|----------|--------|-------------|
127-
| `/render` | POST | Render URL or HTML to PDF/Image/Video |
128-
| `/render?config=...` | GET | Render URL using GET with JSON config parameter |
129-
| `/health` | GET | Health check with browser pool stats |
130-
| `/docs` | GET | Swagger API documentation |
156+
All settings are driven by environment variables with sensible defaults.
131157

132-
### Request Parameters
158+
### Server
133159

134-
| Parameter | Type | Required | Description |
135-
|-----------|------|----------|-------------|
136-
| `url` | string | Either url or html | URL to render |
137-
| `html` | string | Either url or html | HTML content to render |
138-
| `type` | string | Yes | Output type: `image`, `pdf`, `video`, `html` |
139-
| `device` | object | No | Device settings (width, height, userAgent, etc.) |
140-
| `render` | object | No | Render options (waitTime, fullPage, scroll, etc.) |
141-
| `image` | object | No | Image settings (type, quality, compression, etc.) |
142-
| `pdf` | object | No | PDF settings (format, margins, orientation, etc.) |
143-
| `video` | object | No | Video settings (fps, duration, codec, etc.) |
160+
| Variable | Default | Description |
161+
|----------|---------|-------------|
162+
| `SERVER_PORT` | `3000` | HTTP server port |
163+
| `BODY_LIMIT_BYTES` | `52428800` | Max request body size (50 MB) |
164+
| `SHUTDOWN_TIMEOUT_MS` | `30000` | Graceful shutdown timeout |
165+
| `LOG_LEVEL` | `info` | Log level (trace, debug, info, warn, error, fatal) |
144166

145-
For complete API documentation, visit `/docs` endpoint after starting the server.
167+
### Browser Pool
146168

147-
## Getting Started with Development
169+
| Variable | Default | Description |
170+
|----------|---------|-------------|
171+
| `POOL_MIN` | `2` | Minimum browser instances |
172+
| `POOL_MAX` | `10` | Maximum browser instances |
173+
| `POOL_ACQUIRE_TIMEOUT_MS` | `30000` | Max wait to acquire a browser |
174+
| `POOL_IDLE_TIMEOUT_MS` | `30000` | Idle time before eviction |
175+
| `BROWSER_MAX_AGE_MS` | `600000` | Max browser lifetime (10 min) |
176+
| `BROWSER_MAX_REQUESTS` | `100` | Max requests per browser before recycling |
177+
| `BROWSER_MAX_MEMORY_MB` | `500` | Memory limit per browser |
148178

149-
To get started, run the following commands:
179+
### Video
150180

151-
```
152-
npm i
153-
npm run dev
154-
```
181+
| Variable | Default | Description |
182+
|----------|---------|-------------|
183+
| `FFMPEG_PATH` | `/usr/bin/ffmpeg` | Path to FFmpeg binary |
184+
| `VIDEO_MAX_SCROLL_DURATION_MS` | `20000` | Max scroll animation duration |
155185

156-
## Build and Run in Docker
186+
### Viewport
157187

158-
### Quick usage
188+
| Variable | Default | Description |
189+
|----------|---------|-------------|
190+
| `DEFAULT_VIEWPORT_WIDTH` | `1920` | Default viewport width |
191+
| `DEFAULT_VIEWPORT_HEIGHT` | `1080` | Default viewport height |
159192

160-
Install the docker image from the Github registry of this repository
193+
## Testing
161194

162-
```
163-
docker pull ghcr.io/carbogninalberto/fast-html-to-pdf-api:latest
164-
docker run -p 3000:3000 ghcr.io/carbogninalberto/fast-html-to-pdf-api:latest
195+
### Unit Tests
196+
197+
```bash
198+
npm test
165199
```
166200

167-
### Prerequisites
201+
With coverage report (97% line coverage required):
168202

169-
- Docker installed on your system
203+
```bash
204+
npm run coverage
205+
```
170206

171-
### Build the Docker image
207+
### End-to-End Tests
172208

173-
To build the Docker image, run the following command in the project root directory:
209+
Requires a running server on port 3000:
174210

211+
```bash
212+
# Terminal 1: start the server
213+
FFMPEG_PATH=/opt/homebrew/bin/ffmpeg node app/server.js
214+
215+
# Terminal 2: run E2E tests
216+
npm run test:e2e
175217
```
176-
docker build --platform linux/amd64 . -t render
218+
219+
E2E tests validate output format correctness using magic bytes (PNG, WebP, PDF headers, MP4 ftyp box, HTML structure).
220+
221+
### CI
222+
223+
The GitHub Actions workflow runs on every push:
224+
225+
1. Unit tests with 97% coverage gate
226+
2. Docker build
227+
3. E2E tests against the running container
228+
229+
## Health Check
230+
231+
`GET /health` returns pool status and memory usage:
232+
233+
```json
234+
{
235+
"status": "healthy",
236+
"timestamp": "2026-01-22T12:00:00.000Z",
237+
"browserPool": {
238+
"available": 2,
239+
"borrowed": 1,
240+
"pending": 0,
241+
"min": 2,
242+
"max": 10
243+
},
244+
"uptime": 3600,
245+
"memory": {
246+
"used": "256 MB",
247+
"total": "512 MB"
248+
}
249+
}
177250
```
178251

179-
### Run the Docker container
252+
Returns `200` when healthy, `503` when degraded (no browsers available).
180253

181-
To run the Docker container, use the following command:
254+
## License
182255

183-
```
184-
docker run --platform linux/amd64 -p 3000:3000 render
185-
```
256+
For usage in commercial services, please refer to the `license.txt` file in this repository.
257+
258+
Note: License is not enforced, but we are a small team, and any support to further develop this product would be greatly appreciated! 🙏

0 commit comments

Comments
 (0)