{
  "$type": "site.standard.document",
  "bskyPostRef": {
    "cid": "bafyreib4mfrhldzjyfq3b5x6kub5d72pazjp3zx3363autfvlznkco7ba4",
    "uri": "at://did:plc:t4aigbwuwix7x3q42qzjc6mn/app.bsky.feed.post/3mln3n4x7nib2"
  },
  "coverImage": {
    "$type": "blob",
    "ref": {
      "$link": "bafkreibx3ir2jtvkzh4yvvwohxaappa53lg5crs4xm642fimjfn47zby6a"
    },
    "mimeType": "image/jpeg",
    "size": 58789
  },
  "path": "/link/535/17338414/a-little-more-flexibility-for-your-github-contribution-graphs",
  "publishedAt": "2026-05-11T13:00:00.000Z",
  "site": "https://brett.trpstra.net",
  "tags": [
    "published last week",
    "TerminalWidget",
    "open sourced the Contrib project on GitHub",
    "contact page",
    "interactive tester",
    "tester",
    "widget",
    "chart formats",
    "beta is public",
    "TerminalWidget mailing list",
    "Check out the Contrib API",
    "on Mastodon",
    "Bluesky",
    "Twitter",
    "Click here if you'd like to help out.",
    "Mastodon",
    "GitHub",
    "everywhere else"
  ],
  "textContent": "The Contrib API I published last week for generating GitHub contribution heatmaps as a PNG you can drop into a TerminalWidget, blog post, or slide deck, now goes further than “pick a username and theme.”\n\nFirst of all, I’ve open sourced the Contrib project on GitHub. Feel free to fork and play with it if you want to. The version on my server will continue to run as a publicly-available API, but you can do what you will with the code.\n\n> As a real-life application (outside of TerminalWidget), I’ve used the API to add a contribution graph to my contact page. It just uses a Markdown image tag with a Contrib API url as the source. So every time my contact page loads, you get an up-to-date graph. If my Contact page were higher traffic, I’d have to look into caching a bit. The API scales pretty well for 10-100 simultaneous hits, but anything more than that would require some adjustment. I’ve added a SCALING.md file to the repo that details a potential path, should that ever become necessary.\n\n### Additions\n\nYou can now specify weeks instead of months, how chunky the squares look (all the way down to circles), whether the background is transparent, and which font drives the captions. You can also specify header and/or footer text to be rendered in the image.\n\nEverything below works two ways: play with it in the interactive tester on the Contrib page, or pass the same parameters on the **REST-style image endpoint** (`GET /contrib/generate?...`).\n\n#### Time range: months or exact week columns\n\nYou can still ask for a span in **months** , but if you want the grid to match a specific number of **week columns** (aligned like GitHub’s Sunday-based weeks, ending “now”), use `weeks=N`. When `weeks` is present it wins over `months`, and the calendar trims to that many columns.\n\nExample:\n\n\n    GET https://brettterpstra.com/contrib/generate?username=octocat&weeks=16&theme=light&width=1200\n\n#### Padding and corner radius\n\n**`padding`** is the margin around the chart in pixels (handy when you are compositing the PNG onto something else). **`corner_radius`** is a 0–100 control for how round each cell is: `0` is square, `100` pushes to circles, and the default (20) keeps the familiar lightly rounded look unless you override it.\n\n#### Transparent backgrounds (opt-in)\n\nTransparency is **off** unless you ask for it. Pass something truthy like `transparent=1` (or `true` / `yes` / `on`) and you get an RGBA PNG with a transparent canvas while the contribution squares and caption text stay readable. The tester shows a checkerboard behind the preview so you can see what is actually see-through.\n\n### Caption fonts and scaling\n\n**`font`** picks a caption preset (Helvetica-style default, DejaVu, Liberation, Arial, Inter, Noto, Georgia, system UI, and friends). Caption size and spacing **scale with output width** , so wide exports do not end up with tiny labels. If your range crosses January, **year labels center over each calendar year** instead of looking pasted on wrong.\n\n#### Headers and Footers\n\nYou can use **`header=TEXT`** and **`footer=TEXT`** along with **`headerAlign=[l|c|r]`** and **`footerAlign=[l|c|r]`** to add custom headers. Text should be URL encoded, and will inherit the font used for the rest of the captions. Headers are rendered 30px above the top of any captions, or 30px below the chart.\n\n### Using the Tester vs the API\n\nThe tester has been updated with the new options, and builds the same query string the API expects: set username, theme, width, `months` or `weeks`, captions, download behavior, `transparent`, `padding`, `corner_radius`, and `font`. Sliders update the live preview on a short delay so typing and dragging do not spam the server; toggles and dropdowns refresh immediately. Copy the generated URL or open it in a new tab when you’re happy.\n\nThe **API** is the same contract: one GET request returns a PNG. Pair it with `download=1` when you want a download-friendly response for automation.\n\nIf you already use the graph embed, try `weeks`, `padding`, and `corner_radius` first; they are the fastest way to get a layout that fits your page (or widget) without an extra crop step.\n\n### In TerminalWidget\n\nWith these changes, I can now make a TerminalWidget widget with an image that fits the format of the widget perfectly, showing exactly the right number of columns to fill the widget, with circles, squares, or rounded rectangles, and a transparent background so I can apply my own widget background.\n\nThe command that created the above widget is:\n\n\n    terminal-widget --target github \\ --image \"https://brettterpstra.com/contrib/generate?username=ttscoff&weeks=15&theme=sunset&font=georgia&width=800&corner_radius=100&caption_year=0&caption_month=0&caption_day=0&transparent=1&padding=0&download=0\" \\ --padding 0 --bg 1d1128\n\nThere’s also a TerminalWidget-specific option for outputting just chart data in a string TerminalWidget can turn into its own chart. Just add `chart-data=1` to output a string of values instead of a PNG.\n\nThis string can be used to generate charts in any of TerminalWidgets chart formats.\n\nThe command to generate something like these would be:\n\n\n    curl \"https://brettterpstra.com/contrib/generate?username=ttscoff&chart-data=1&weeks=16\" | terminal-widget --target github2 --chart - --chart-format smooth --bg 333333 --fg e0ff4f --caption --text \"GitHub Contributions\" --label-y\n\n### Join the TerminalWidget beta!\n\nFor those interested in trying out TerminalWidget, the beta is public. Unfortunately the latest version of the macOS build hasn’t been approved yet (still “Waiting for review” after a full week), but it will be updated soon 🤞. Join the TerminalWidget mailing list if you’d like to be notified about progress.\n\nCheck out the Contrib API in the meantime. I think GitHub users will find it useful!\n\nLike or share this post on Mastodon, Bluesky, or Twitter.\n\n* * *\n\nBrettTerpstra.com is supported by readers like you. Click here if you'd like to help out.\n\nFind Brett on Mastodon, Bluesky, GitHub, and everywhere else.",
  "title": "A little more flexibility for your GitHub contribution graphs",
  "updatedAt": "2026-05-11T13:00:00.000Z"
}