Skip to content

Spectrewolf8/isometric-contributions-embeds

Repository files navigation

logo Isometric Contributions

Generate beautiful 3D isometric visualizations of GitHub contribution graphs. Available as both a CLI tool and a fast, cached API server.

Examples

GitHub Theme
GitHub Theme
Light Theme
Light Theme
Dark Theme
Dark Theme
Neon Theme
Neon Theme
Ocean Theme
Ocean Theme
Minimal Theme
Minimal Theme
Without Stats
Without Stats
Without Credit
Without Credit
Default Theme
One Year
365-Day Rolling Window
365-Day Rolling Window (Default)

Features

  • Fast API with intelligent caching and revalidation
  • 🎨 6 Built-in Themes: GitHub, Dark, Light, Neon, Minimal, Ocean
  • 📊 Statistics Overlay: Contributions, streaks, averages
  • 🖼️ Customizable: Dimensions, year selection, credits, themes
  • 🚀 Minimal: Lightweight with no framework overhead
  • 💾 Smart Caching: Efficient daily caching with instant updates
  • 📅 365-Day Rolling Window: Default view showing last 365 days of activity

Installation

npm install

Quick Start

CLI Usage

Generate an isometric contribution graph:

npm run generate -- <username> [year] [output] [options]

Examples:

# Basic usage
npm run generate -- spectrewolf8

# Specific year with stats
npm run generate -- spectrewolf8 2025 graph.png --stats --credit

# Custom dimensions
npm run generate -- spectrewolf8 2025 graph.png --width 1920 --height 1080

CLI Options:

  • --stats - Include statistics overlay
  • --credit - Show username in bottom right
  • --width <px> - Canvas width (default: 1000)
  • --height <px> - Canvas height (default: 600)

API Server

Start the API server for web integration:

npm run server

Or with auto-reload during development:

npm run dev

Server runs on port 3000 (configurable via PORT environment variable).

API Documentation

Endpoint

GET /api/graph

Query Parameters

Parameter Type Required Default Description
username string ✅ Yes - GitHub username
year/y number/string No none (365 days) Year to fetch (e.g., 2025), or none for 365-day rolling window ending today
theme string No github Visual theme: github, dark, light, neon, minimal, ocean
width number No 1000 Image width in pixels
height number No 600 Image height in pixels
stats boolean No false Include statistics overlay
credit boolean No false Show username credit

API Examples

Basic Graph:

https://isometric-contributions-spectrewolf8.onrender.com/api/graph?username=spectrewolf8

With Statistics:

https://isometric-contributions-spectrewolf8.onrender.com/api/graph?username=spectrewolf8&stats=true

365-Day Rolling Window (Default):

https://isometric-contributions-spectrewolf8.onrender.com/api/graph?username=spectrewolf8

Specific Year:

https://isometric-contributions-spectrewolf8.onrender.com/api/graph?username=spectrewolf8&year=2025

With Theme:

https://isometric-contributions-spectrewolf8.onrender.com/api/graph?username=spectrewolf8&theme=dark&stats=true

With Credit:

https://isometric-contributions-spectrewolf8.onrender.com/api/graph?username=spectrewolf8&credit=true

Full Customization:

https://isometric-contributions-spectrewolf8.onrender.com/api/graph?username=spectrewolf8&year=2025&width=1200&height=700&stats=true&credit=true&theme=neon

Note: Use http://localhost:3000 for local testing.

Caching

The API implements intelligent daily caching:

  • Cache Duration: 1 hour with revalidation (ensures freshness)
  • Cache Strategy: One generation per username+params per day
  • Cache Headers: Check X-Cache header (HIT or MISS)
  • Benefits: Instant responses for repeated requests with fresh updates

Cache Response Headers:

Content-Type: image/png
Content-Length: <bytes>
Cache-Control: public, max-age=3600, must-revalidate
X-Cache: HIT | MISS

Additional Endpoints

Documentation:

GET /
GET /docs

Health Check:

GET /health

Programmatic Usage

Fetch Contributions

import {
  fetchContributions,
  parseContributionsData,
} from "./src/api-client.js";

const data = await fetchContributions("username", 2025);
const days = parseContributionsData(data);

Render Image

import { renderIsometricChart, exportToPNG, setTheme } from "./src/renderer.js";
import { DARK_THEME } from "./src/theme-config.js";
import { writeFileSync } from "fs";

// Set theme (optional)
setTheme(DARK_THEME);

// Render
const canvas = renderIsometricChart(days, {
  width: 1000,
  height: 600,
  username: "spectrewolf8", // optional credit
});

// Export
const buffer = await exportToPNG(canvas);
writeFileSync("output.png", buffer);

With Statistics

import { renderWithStats } from "./src/renderer.js";

const canvas = renderWithStats(days, {
  width: 1000,
  height: 600,
});

Available Themes

import {
  GITHUB_THEME,
  DARK_THEME,
  LIGHT_THEME,
  NEON_THEME,
  MINIMAL_THEME,
  OCEAN_THEME,
} from "./src/theme-config.js";
import { setTheme } from "./src/renderer.js";

// Apply theme before rendering
setTheme(NEON_THEME);

Embedding in README

Markdown

![GitHub Contributions](https://isometric-contributions-spectrewolf8.onrender.com/api/graph?username=spectrewolf8&stats=true)

With theme:

![GitHub Contributions](https://isometric-contributions-spectrewolf8.onrender.com/api/graph?username=spectrewolf8&theme=dark&stats=true)

HTML

<img
  src="https://isometric-contributions-spectrewolf8.onrender.com/api/graph?username=spectrewolf8&theme=neon&stats=true"
  alt="GitHub Contributions"
/>

Scripts

Command Description
npm run generate Generate graph via CLI
npm run server Start API server
npm run dev Start server with auto-reload
npm run test:api Test API endpoints
npm run cleanup Manually run cache cleanup
npm run cleanup:scheduler Start automatic cleanup scheduler

Output

Generates PNG images with:

  • Resolution: Customizable (default 1000x600)
  • Format: PNG with transparency
  • Size: ~20-30 KB (varies with dimensions)

Statistics Displayed

  • Total contributions
  • Best day (max contributions)
  • Average per day
  • Longest streak
  • Current streak

Cache Management

The project includes automatic cache cleanup to remove old files from Supabase Storage.

Setup

  1. Add environment variables to .env:

    SUPABASE_ANON_KEY=your-anon-key
    CACHE_RETENTION_DAYS=1
    CLEANUP_SCHEDULE=0 3 * * *  # Daily at 3 AM
    RUN_ON_STARTUP=true
    TZ=UTC
  2. Add DELETE policy to Supabase (one-time setup):

    Run this in your Supabase SQL Editor:

    CREATE POLICY "Anon delete access"
      ON storage.objects
      FOR DELETE
      TO anon
      USING (bucket_id = 'isometric-cache');
    
    GRANT DELETE ON storage.objects TO anon;
  3. Start the scheduler:

    npm run cleanup:scheduler

The scheduler runs automatically in Docker/production (see Dockerfile).

Manual Cleanup

Run cleanup on-demand:

npm run cleanup

Cron Schedule Examples

  • 0 3 * * * - Daily at 3 AM
  • 0 */6 * * * - Every 6 hours
  • 0 */12 * * * - Every 12 hours
  • */30 * * * * - Every 30 minutes
  • 0 0 * * 0 - Weekly on Sunday at midnight

How It Works

The cleanup script:

  1. Lists all files in the Supabase Storage bucket
  2. Checks each file against retention criteria:
    • Files with created_at older than retention period
    • Files in date folders (e.g., username/2026-02-01/) older than retention
    • .emptyFolderPlaceholder files
  3. Deletes matching files using Supabase Storage API
  4. Logs results with counts and examples

Production Deployment

Docker/Render/Railway:

The Dockerfile automatically starts both processes:

CMD ["sh", "-c", "node server.js & node cleanup-scheduler.js & wait"]

Just add the environment variables to your hosting platform.

Troubleshooting

Cache Cleanup Issues

No files deleted:

  • Check CACHE_RETENTION_DAYS - files must be older than this
  • Verify DELETE policy is set up in Supabase (see setup step 2)
  • Check file dates in Supabase dashboard

Permission errors:

  • Ensure DELETE policy exists for anon role on storage.objects
  • Run the setup SQL in Supabase SQL Editor (see Cache Management section)
  • Verify bucket name matches SUPABASE_BUCKET_NAME

Scheduler not running:

  • Verify cron expression is valid
  • Check timezone setting (TZ environment variable)
  • Ensure process stays running (use PM2 or Docker)
  • Check logs: pm2 logs cache-cleanup (if using PM2)

Manual testing:

# Test cleanup manually
npm run cleanup

# With different retention
CACHE_RETENTION_DAYS=7 npm run cleanup

Check cleanup logs:

The cleanup script outputs logs:

🧹 Cleaning cache (retention: 1 day(s))
📅 Deleting folders older than 2026-02-02
✅ No old folders to delete

✨ Cleanup completed

Acknowledgements

This project builds upon the excellent work of:

  • Core Renderer: Based on isometric-contributions by Jason Long - the foundational isometric rendering logic was taken and modified for this implementation
  • Contributions API: Uses the GitHub Contributions API by Joe Gruber - an unofficial but reliable API for fetching GitHub contribution data

Contributing

Feel free to open issues or submit PRs for improvements!

License

This project is licensed under the MIT License.

About

Generate beautiful 3D isometric visualizations of GitHub contribution graphs. Available as both a CLI tool and a fast, cached API.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors