SponsorKit: Turning Sponsorships From Seven Platforms Into One SVG
💖 Toolkit for generating sponsors images 😄
At a glance
- What is it?
- SponsorKit is an MIT licensed TypeScript toolkit that fetches your sponsors from GitHub Sponsors, Patreon, OpenCollective, Afdian, Polar, Liberapay or Ko-fi and renders them as SVG, PNG, WebP or JSON. It suits maintainers who sponsor-hunt across several services and want the image regenerated in CI rather than by hand.
- Who is it for?
- SponsorKit is a good fit for a maintainer whose sponsor list is split across several platforms and who wants a sponsors image regenerated on a schedule from a single config file. It is the wrong tool when your sponsors live on a single service with a good built-in widget, or when you need historical tiers for platforms other than GitHub.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 5 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 25, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Seven sponsor services, one generated image
SponsorKit exists because sponsor lists get scattered. A maintainer may take money through GitHub Sponsors, Patreon, OpenCollective, Afdian, Polar, Liberapay and Ko-fi at the same time, and each service exposes its own API, its own auth token and its own idea of what counts as a sponsor. The toolkit's job is to normalize that into a list, then draw it. The project describes itself as a toolkit for fetching sponsors info and generating sponsors images, and it ships both a CLI and a programmatic entry point. The output is meant for a README, which is why the rendered artifact is an image rather than a badge or a JSON feed. The repository contains an `example/` directory with its own config and env sample, plus a pnpm workspace setup, so the intended workflow is a small project that depends on the package and commits the generated files.
Credentials live in a .env file, one provider at a time
Configuration is split in two: a `.env` file for secrets and a `sponsorkit.config.js` file for rendering choices. The env file holds a variable per provider, and the docs are explicit that only one provider has to be configured. A GitHub setup needs a token and a login, and the token comment states it requires the `read:user` and `read:org` scopes. The GitHub block also carries an optional mode switch where `sponsors` means people sponsoring you and `sponsees` means people you have sponsored, including past sponsorships.
SPONSORKIT_GITHUB_TOKEN=
SPONSORKIT_GITHUB_LOGIN=
SPONSORKIT_MODE=sponsorsEach other service has its own credential shape. Patreon wants a v2 API key created through its client registration page and the creator access token. OpenCollective wants an API key plus an identifier, and the docs give three interchangeable ways to say who you are: an ID, a slug or a GitHub handle, along with a type that must be `person` for a personal account. Afdian wants both a user id and a token from its developer dashboard. Polar wants a token and an organization name. Liberapay only needs a profile login. Ko-fi needs a verification token and optionally a path to a local event store.
Tiers or circles, drawn from the same sponsor list
Two renderers ship with the package. The `tiers` renderer lays sponsors out in rows by amount, and the `circles` renderer packs them into circles. Choosing between them is a layout decision rather than a data decision, and the config exposes the knobs that matter for a README banner: `width` for the overall canvas, `formats` for which files to emit, and `tiers` for the grouping rules. Tiers are objects with a `title`, an optional `monthlyDollars` threshold and a `preset` drawn from `tierPresets`. The example configuration maps past sponsors, backers, and dollar thresholds of 10, 50 and 100 onto preset sizes from `xs` through `xl`. The `formats` array accepts `json`, `svg`, `png` and `webp`, so the same run can produce a machine readable list next to the banner. Nothing in the docs suggests the formats are alternatives you pick between; they are outputs of one pass. The alternative to this approach is not another library so much as a different workflow: linking to each platform's own sponsor listing page from the README. That route needs no credentials and no scheduled job, but it gives you one platform's layout per link, no tier grouping and no static image that renders identically for every visitor. SponsorKit trades that simplicity for a build step and a set of API tokens.
Several images from one config through the renders field
A common complaint about generated sponsor graphics is that one layout cannot serve both a narrow sidebar and a wide README. The `renders` field exists for that. Each entry in the array gets a `name` and inherits the top-level configuration, so you can declare a tiers banner and a circles banner side by side and change only what differs.
import { defineConfig, tierPresets } from 'sponsorkit'
export default defineConfig({
github: { /* ... */ },
width: 800,
renders: [
{
name: 'sponsors.tiers',
formats: ['svg'],
},
{
name: 'sponsors.circles',
renderer: 'circles',
width: 600,
},
],
})The inheritance model is the point. Overriding `width` or `renderer` on one entry does not disturb the defaults the others rely on, and named outputs make it obvious which file is which when several land in the same directory. The docs also point at a scheduler workflow for GitHub Actions, which fits this design well, since a scheduled job can regenerate the whole set without anyone touching a laptop.
Ko-fi needs a webhook receiver because it has no listing API
Most providers in the list can be queried directly. Ko-fi cannot, so SponsorKit handles it differently. Instead of polling, you run a local receiver:
npx sponsorkit kofi-webhookThe receiver listens on `http://127.0.0.1:3456/kofi`, so it is bound to loopback only. You expose that address through an HTTPS tunnel and paste the public URL into the Ko-fi webhooks page. On receipt, SponsorKit verifies the webhook token, strips the token and the email address before anything is written to disk, deduplicates retries by `message_id`, and appends events to `./sponsorkit/kofi-events.json`. After Ko-fi sends a payment or a test payment, you generate the output as usual with the force flag, which is what makes the local event store part of the pipeline rather than a side file.
npx sponsorkit --forceThere is a known gap in the data model. Ko-fi does not send an event when a membership ends, so SponsorKit treats subscription payments as active for 35 days by default, and the `kofi.subscriptionEffectivity` setting changes that window. A lapsed subscriber will keep appearing in your image until the window closes.
Running the CLI for the first time
The first run is short. Create a `.env` with a single provider credential, put a `sponsorkit.config.js` next to it, and invoke the CLI. The docs show the invocation as a plain `npx` call, which means no global install is required.
npx sponsorkitThe configuration file is a JavaScript module using the `defineConfig` helper from the package.
import { defineConfig, tierPresets } from 'sponsorkit'
export default defineConfig({
mode: 'sponsors',
github: {
login: 'antfu',
type: 'user',
},
width: 800,
renderer: 'tiers', // or 'circles'
formats: ['json', 'svg', 'png', 'webp'],
})Two runtime constraints come from the package manifest rather than the usage notes. The `engines` field accepts Node `^22.18.0 || ^24.11.0 || >=26.0.0`, which defines the officially supported Node range. The declared package manager is `[email protected]`, and the repository carries a `pnpm-workspace.yaml`, which suggests the development flow is pnpm based even though the docs recommend running the published package through `npx`.
fetchSponsors when you need the data, not the image
Not every use of this data is a picture. The package also exports `fetchSponsors`, which returns the raw sponsor list for a given set of provider credentials.
import { fetchSponsors } from 'sponsorkit'
const sponsors = await fetchSponsors({
github: {
token,
login,
},
// ...
})That entry point is the one to reach for if you want to feed sponsors into your own site generator, a changelog or a dashboard, or if you want to diff the list over time. The docs point at the type definition or the source for the other utilities. Looking at the dependency list gives a hint about how the work is done underneath: `ofetch` for HTTP, `cac` for the argument parsing that the CLI is built on, `consola` for output, `unconfig` for loading configuration, `p-limit` for concurrency control, `normalize-url` for cleaning provider URLs, `d3-hierarchy` for laying out the packed circles, and `sharp` for the raster formats.
What SponsorKit does not cover
Several gaps are worth knowing before you rely on it. The Past Sponsors tier in the example configuration carries a comment that it currently supports GitHub only, so historical sponsor lists from other platforms are not something the config can express today. The Ko-fi activity window is a fixed default rather than an event driven value. The docs also do not describe any rollback or retry behaviour for a failed provider call, so a scheduled job that hits a rate limit has no documented recovery path, which matters because the whole design leans on unattended runs. On maintenance, the MIT licence covers the code, and the project sits under the `antfu-collective` organisation with Anthony Fu as author. Releases move quickly by version number, with v18.0.0 published on 2026-08-03 following v17.1.1 on 2026-05-20 and v17.1.0 on 2026-04-10, and the last push was on 2026-10-22. Because the version numbers climb that fast, treat the config file as the stable part of your setup and expect to read the changelog when you bump the dependency.
Editorial conclusion
SponsorKit is a good fit for a maintainer whose sponsor list is split across several platforms and who wants a sponsors image regenerated on a schedule from a single config file. It is the wrong tool when your sponsors live on a single service with a good built-in widget, or when you need historical tiers for platforms other than GitHub. Before adopting it, run npx sponsorkit once locally with a single provider token to confirm the tiers you set match the data that platform actually returns.
Frequently asked questions
Which sponsor platforms does SponsorKit support?
GitHub Sponsors, Patreon, OpenCollective, Afdian, Polar, Liberapay and Ko-fi are all listed as supported. Only one provider needs to be configured for a run.
How do I run SponsorKit to generate my sponsors image?
Create a .env file with a provider credential, add a sponsorkit.config.js file, then run npx sponsorkit. Output formats are chosen with the formats option, which accepts json, svg, png and webp.
How does SponsorKit handle Ko-fi, which has no sponsor listing API?
Ko-fi sponsors arrive through webhooks. You run npx sponsorkit kofi-webhook, expose http://127.0.0.1:3456/kofi through an HTTPS tunnel, and events are stored in ./sponsorkit/kofi-events.json before you regenerate with npx sponsorkit --force.
Can SponsorKit produce more than one sponsors image at once?
Yes. The renders field holds a list of named renders that each inherit the top-level config, so you can set a different width or renderer per entry while sharing the provider and tier settings.
What Node version does SponsorKit need?
The package manifest declares engines of ^22.18.0 || ^24.11.0 || >=26.0.0. The declared package manager is [email protected].
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/antfu-collective-sponsorkit)Was this useful?