# SponsorKit: Turning Sponsorships From Seven Platforms Into One SVG

> 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.

**antfu-collective/sponsorkit** — 💖 Toolkit for generating sponsors images 😄

- Repository: https://github.com/antfu-collective/sponsorkit
- Stars: 836 · Forks: 73
- Language: TypeScript
- License: MIT
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/antfu-collective-sponsorkit

## 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.

```ini
SPONSORKIT_GITHUB_TOKEN=
SPONSORKIT_GITHUB_LOGIN=
SPONSORKIT_MODE=sponsors
```

Each 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.

```ts
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:

```bash
npx sponsorkit kofi-webhook
```

The 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.

```bash
npx sponsorkit --force
```

There 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.

```bash
npx sponsorkit
```

The configuration file is a JavaScript module using the `defineConfig` helper from the package.

```ts
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 `pnpm@11.18.0`, 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.

```ts
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.

## 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.

## FAQ

### 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 pnpm@11.18.0.

## Sources

- [antfu-collective/sponsorkit on GitHub](https://github.com/antfu-collective/sponsorkit)
- [Issues](https://github.com/antfu-collective/sponsorkit/issues)
- [License: MIT](https://github.com/antfu-collective/sponsorkit/blob/main/LICENSE)
- [README](https://github.com/antfu-collective/sponsorkit/blob/main/README.md)
- [Releases](https://github.com/antfu-collective/sponsorkit/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/antfu-collective-sponsorkit
