An open API service indexing awesome lists of open source software.

https://github.com/nichtlegacy/letterboxd-graph

Generates a GitHub-style contribution graph based on your Letterboxd diary. Uses Node.js to scrape data, process entries, and create daily updated SVG visuals via GitHub Actions.
https://github.com/nichtlegacy/letterboxd-graph

contribution-graph github-actions javascript letterboxd movies nodejs svg web-scraping

Last synced: 2 months ago
JSON representation

Generates a GitHub-style contribution graph based on your Letterboxd diary. Uses Node.js to scrape data, process entries, and create daily updated SVG visuals via GitHub Actions.

Awesome Lists containing this project

README

          

# 🎬 Letterboxd Contribution Graph


GitHub Workflow Status
GitHub Release
Made with Node.js
JavaScript
License


Transform your Letterboxd film diary into a beautiful GitHub-style contribution graph






Letterboxd contribution graph


---

## ✨ Features

| Feature | Description |
|---------|-------------|
| 🎨 **Light & Dark Themes** | Automatically adapts to GitHub's theme preference |
| 📊 **Activity Heatmap** | GitHub-style contribution graph showing film activity |
| 👤 **Profile Integration** | Shows profile picture, display name, stats, and member badge |
| 🏆 **Pro/Patron Badges** | Displays Letterboxd Pro (orange) or Patron (cyan) status |
| 📅 **Multi-Year Support** | Generate graphs spanning multiple years |
| 🎯 **Streak Highlighting** | Hover over "Day Streak" to highlight your longest streak |
| 💬 **Interactive Tooltips** | Hover over cells to see film details (in browser) |
| ⭐ **Rating Mode** | Color cells by average rating instead of watch count |
| 📦 **JSON Export** | Writes `images/letterboxd-data.json` for external widgets (e.g. Glance `custom-api`) |
| 🔄 **Daily Updates** | Automated updates via GitHub Actions |

---

## 🚀 Quick Start

### 1. Fork this Repository

Click the **Fork** button at the top-right of this page.

### 2. Update Your Username

Edit `.github/workflows/update-graph.yml`:

```yaml
- run: npm start YOUR_LETTERBOXD_USERNAME -o images/github-letterboxd
```

### 3. Enable GitHub Actions

Go to **Actions** tab → Enable workflows if prompted.

### 4. Run the Workflow

The graph updates daily at midnight UTC, or trigger manually via the **Actions** tab.

---

## 📸 Examples

### Patron User (Single Year)



### Pro User (Single Year)



### Multi-Year Graph



### Interactive Features

Hover over stats to reveal additional information (visible when opening the SVG in a browser):


Day Streak Highlight
Days Active Tooltip
Film Count Tooltip





---

## 📖 CLI Usage

```bash
# Install dependencies
npm install

# Basic usage
node src/cli.js

# With options
node src/cli.js [options]
```

### Arguments

| Flag | Description | Default |
|------|-------------|---------|
| `-y ` | Year(s) to generate, comma-separated (e.g. `2024,2023`) | Current year |
| `-w ` | Week start: `sunday` or `monday` | `sunday` |
| `-o ` | Output path (without extension) | `images/github-letterboxd` |
| `-g ` | Enable username gradient: `true` or `false` | `true` |
| `-p` | Export PNG files in addition to SVG | Disabled |
| `-m ` | Graph mode: `count` or `rating` | `count` |

### Examples

```bash
# Single year with custom output
node src/cli.js nichtlegacy -y 2025 -o images/my-graph

# Multiple years (2024 + 2025)
node src/cli.js nichtlegacy -y 2025,2024

# Start week on Monday, no gradient
node src/cli.js nichtlegacy -w monday -g false

# Rating mode with PNG export
node src/cli.js nichtlegacy -m rating -p
```

---

## 🔧 GitHub Actions Setup

### Workflow File

Create `.github/workflows/update-graph.yml`:

```yaml
name: Update Letterboxd Graph

# ╔════════════════════════════════════════════════════════════════╗
# ║ CONFIGURATION - Edit these values for your Letterboxd profile ║
# ╚════════════════════════════════════════════════════════════════╝
env:
LETTERBOXD_USERNAME: "YOUR_USERNAME" # Replace with your username
YEARS: "" # e.g. "2025,2024" or leave empty for current year
EXPORT_PNG: "false" # Set to "true" to also generate PNG files
WEEK_START: "sunday" # "sunday" or "monday"
GRADIENT: "true" # "true" for colored name, "false" for white

on:
schedule:
- cron: "0 0 * * *" # Daily at midnight UTC
workflow_dispatch: # Manual trigger

permissions:
contents: write

jobs:
update-graph:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'

- run: npm ci

- name: Generate Graph
run: |
# Build command based on configuration
CMD="node src/cli.js ${{ env.LETTERBOXD_USERNAME }} -o images/github-letterboxd"

if [ -n "${{ env.YEARS }}" ]; then CMD="$CMD -y ${{ env.YEARS }}"; fi
if [ "${{ env.WEEK_START }}" = "monday" ]; then CMD="$CMD -w monday"; fi
if [ "${{ env.GRADIENT }}" = "false" ]; then CMD="$CMD -g false"; fi
if [ "${{ env.EXPORT_PNG }}" = "true" ]; then CMD="$CMD -p"; fi

echo "Running: $CMD"
eval $CMD

- name: Commit and Push
run: |
git config --global user.name 'github-actions[bot]'
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
git add images/

if git diff --staged --quiet; then
echo "No changes to commit"
else
git commit -m "Update Letterboxd graph"
git push
fi
```

### Configuration

You can customize the graph directly in the workflow file by editing the `env` section at the top:

- **LETTERBOXD_USERNAME**: Your Letterboxd profile name
- **YEARS**: Comma-separated list of years (e.g., `2025,2024`)
- **EXPORT_PNG**: Set to `true` if you want PNG versions alongside SVGs
- **WEEK_START**: Start week on `sunday` or `monday`
- **GRADIENT**: Toggle the username text gradient

---

### Glance Widgets (custom-api)

The generator also writes `images/letterboxd-data.json`, so you can build Glance widgets without running an extra backend container.

Raw URL format:

```
https://raw.githubusercontent.com//letterboxd-graph/main/images/letterboxd-data.json
```

Example payload shape:

```json
{
"user": "nichtlegacy",
"year": 2026,
"stats": { "films": 123, "daysActive": 80, "streak": 7 },
"cells": [
{
"date": "2026-02-16",
"count": 2,
"ratingAvg": 3.5,
"films": [
{ "title": "Film A", "year": "2024", "rating": 3.5, "url": "https://letterboxd.com/..." }
],
"url": "https://letterboxd.com//films/diary/for/2026/02/16/"
}
],
"recent": [
{ "date": "2026-02-16", "title": "Film A", "year": "2024", "rating": 3.5, "url": "https://letterboxd.com/..." }
]
}
```

You can use this to build:

- a compact heatmap widget (GitHub-like)
- a separate stats widget (`films`, `daysActive`, `streak`)
- an optional recent-watches list

## 📂 Project Structure

```
letterboxd-graph/
├── .github/
│ ├── assets/ # README images and examples
│ └── workflows/
│ └── update-graph.yml # GitHub Actions workflow
├── fonts/
│ ├── Inter-Bold.ttf
│ ├── Inter-Medium.ttf
│ ├── Inter-Regular.ttf
│ └── Inter-SemiBold.ttf # Primary font for text measurement
├── images/
│ ├── github-letterboxd-dark.svg # Generated dark theme
│ ├── github-letterboxd-light.svg # Generated light theme
│ └── letterboxd-data.json # Generated JSON data for widgets
├── src/
│ ├── cli.js # CLI entry point
│ ├── fetcher.js # Letterboxd data fetching
│ ├── generator.js # SVG generation
│ ├── stats.js # Statistics calculations
│ └── exporter.js # PNG export functionality
├── package.json
└── README.md
```

---

## 🖼️ Embed in Your README

Add this to your profile README to display the graph with automatic theme switching:

```html






Letterboxd contribution graph



```

Replace `YOUR_GITHUB_USERNAME` and `YOUR_LETTERBOXD_USERNAME` with your usernames.

---

## 🎨 Themes & Modes

### Graph Modes

| Mode | Description |
|------|-------------|
| **Count** (default) | Cell color intensity based on number of films watched |
| **Rating** | Cell color based on average rating of films that day |

### Member Badges

The graph automatically detects and displays your Letterboxd membership status:

| Status | Badge Color | Location |
|--------|-------------|----------|
| **Pro** | Orange (#ff8000) | Bottom-left of profile picture |
| **Patron** | Cyan (#40bcf4) | Bottom-left of profile picture |

---

## 🛠️ Requirements

- **Node.js** v18 or higher
- **Public Letterboxd profile** with diary entries
- **GitHub account** with Actions enabled (for automated updates)

---

## 🤝 Contributing

Contributions are welcome! Feel free to:

- 🐛 Report bugs
- 💡 Suggest features
- 🔧 Submit pull requests

---

## 📄 License

MIT License - see [LICENSE](LICENSE) for details.