Transform your Plex movie watch history into a beautiful GitHub-style contribution graph
| Feature | Description |
|---|---|
| π¨ Light & Dark Themes | Automatically adapts to GitHub's theme preference |
| π Activity Heatmap | GitHub-style contribution graph showing movie activity |
| βοΈ Plex Cloud Integration | Fetches watch history via community.plex.tv, no port-forwarding required |
| π¬ Movies Only | Focused on your film collection (series support coming later) |
| π Multi-Year Support | Generate graphs spanning multiple years |
| π¬ Interactive Tooltips | Hover over cells to see film details with release years |
| π Daily Updates | Automated updates via GitHub Actions |
Click the Fork button at the top-right of this page.
You need your X-Plex-Token. Find it in your browser's network tab when logged into Plex Web, or follow this guide.
Go to Settings > Secrets and variables > Actions and add:
PLEX_TOKEN: Your Plex authentication tokenPLEX_USER: Your Plex username
Edit .github/workflows/update-graph.yml and set your desired years.
Go to Actions tab β Enable workflows if prompted.
The graph updates daily at midnight UTC, or trigger manually via the Actions tab.
Note: You must have "Sync My Watch State and Ratings" enabled in your Plex account settings.
# Install dependencies
npm install
# Basic usage (requires PLEX_TOKEN in .env or environment)
node src/cli.js -y 2025
# With options
node src/cli.js [options]| Flag | Description | Default |
|---|---|---|
-y <years> |
Year(s) to generate, comma-separated (e.g. 2025,2024) |
Current year |
-w <day> |
Week start: sunday or monday |
sunday |
-o <path> |
Output path (without extension) | images/plex-graph |
-g <bool> |
Enable username gradient: true or false |
true |
-p |
Export PNG files in addition to SVG | Disabled |
# Single year
node src/cli.js -y 2025
# Multiple years
node src/cli.js -y 2025,2024
# Start week on Monday, with PNG export
node src/cli.js -y 2025 -w monday -p
# Custom output path
node src/cli.js -y 2025 -o images/my-graphCreate .github/workflows/update-graph.yml:
name: Update Plex Graph
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# β CONFIGURATION - Edit these values for your Plex profile β
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
env:
YEARS: "2025" # Years to generate (e.g. "2025,2024")
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
env:
PLEX_TOKEN: ${{ secrets.PLEX_TOKEN }}
run: |
CMD="node src/cli.js -o images/plex-graph"
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
TIMESTAMP=$(date -u +"%Y-%m-%d %H:%M UTC")
git commit -m "Update Plex graph - $TIMESTAMP"
git push
fi| Secret | Description |
|---|---|
PLEX_TOKEN |
Your Plex authentication token |
plex-graph/
βββ .github/
β βββ workflows/
β βββ update-graph.yml # GitHub Actions workflow
βββ fonts/
β βββ Inter-Bold.woff2
β βββ Inter-Medium.woff2
β βββ Inter-Regular.woff2
β βββ Inter-SemiBold.woff2
βββ images/
β βββ plex-graph-2025-dark.svg
β βββ plex-graph-2025-light.svg
βββ src/
β βββ cli.js # CLI entry point
β βββ fetcher.js # Plex API data fetching
β βββ generator.js # SVG generation
β βββ stats.js # Statistics calculations
β βββ exporter.js # PNG export functionality
βββ plex-logo.svg # Plex branding
βββ package.json
βββ README.md
Add this to your profile README to display the graph with automatic theme switching:
<p align="center">
<a href="https://www.plex.tv/" target="_blank">
<picture>
<source
media="(prefers-color-scheme: dark)"
srcset="https://github.com/YOUR_GITHUB_USERNAME/plex-graph/blob/main/images/plex-graph-2025-dark.svg"
/>
<source
media="(prefers-color-scheme: light)"
srcset="https://github.com/YOUR_GITHUB_USERNAME/plex-graph/blob/main/images/plex-graph-2025-light.svg"
/>
<img
alt="Plex contribution graph"
src="https://github.com/YOUR_GITHUB_USERNAME/plex-graph/blob/main/images/plex-graph-2025-light.svg"
/>
</picture>
</a>
</p>Replace YOUR_GITHUB_USERNAME with your GitHub username.
- Node.js v18 or higher
- Plex account with "Sync Watch State" enabled
- GitHub account with Actions enabled (for automated updates)
Contributions are welcome! Feel free to:
- π Report bugs
- π‘ Suggest features
- π§ Submit pull requests
MIT License - see LICENSE for details.