shieldcn
Docs
Studio
Showcase
Sponsor
jal-co/shieldcn623
shieldcn

Member of the Vercel OSS Program

Analytics provided by OpenPanel

Monitored by Sentry

Powered by Neon.

Community

GitHubjal-co/uiStatsllms.txtPrivacyContact

Product

DocumentationAPI ReferenceToken PoolGeneratorAgent Skill

inspired by shields.io and badgen.net

Made with in by Justin Levine

shieldcn
Docs
Studio
Showcase
Sponsor
jal-co/shieldcn623

Search documentation

Search all badge providers, guides, and reference docs.

Getting Started

IntroductionREADME StudioCLIAgent SkillNewSelf-HostingAPI ReferenceToken PoolSponsor

Badges

Badge GroupStatic BadgeDynamic JSONHTTPS Endpoint

Charts

OverviewStar history

Headers

OverviewGenerator

Sponsors

OverviewGenerator

Contributors

OverviewGenerator
shieldcn

Member of the Vercel OSS Program

Analytics provided by OpenPanel

Monitored by Sentry

Powered by Neon.

Community

GitHubjal-co/uiStatsllms.txtPrivacyContact

Product

DocumentationAPI ReferenceToken PoolGeneratorAgent Skill

inspired by shields.io and badgen.net

Made with in by Justin Levine

Self-Hosting

Run your own shieldcn badge engine with Docker.

Run your own shieldcn badge engine — no reliance on shieldcn.dev infrastructure.

Quick Start

Create a docker-compose.yml file:

services:
  engine:
    image: ghcr.io/jal-co/shieldcn/engine:latest
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgresql://shieldcn:shieldcn@postgres:5432/shieldcn
    depends_on:
      postgres:
        condition: service_healthy
    restart: unless-stopped

  postgres:
    image: postgres:17-alpine
    environment:
      POSTGRES_USER: shieldcn
      POSTGRES_PASSWORD: shieldcn
      POSTGRES_DB: shieldcn
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U shieldcn"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped

volumes:
  pgdata:

Then run:

docker compose up -d

# Verify it's working
curl http://localhost:3000/api/health/
curl http://localhost:3000/badge/self--hosted-green.svg

Badges are served at http://localhost:3000. Use them the same way as shieldcn.dev — just swap the domain:

![npm](http://localhost:3000/npm/v/react.svg)
![stars](http://localhost:3000/github/stars/facebook/react.svg)

All query parameters work — variant, size, mode, theme, logo, color, gradient, etc.

Environment Variables

VariableRequiredDescription
DATABASE_URL✅PostgreSQL connection string
GITHUB_TOKEN—Single GitHub token fallback (5,000 req/hr)
GITHUB_OAUTH_CLIENT_ID—OAuth app for token pool
GITHUB_OAUTH_CLIENT_SECRET—OAuth app secret
YOUTUBE_API_KEY—YouTube Data API key
UPSTASH_REDIS_REST_URL—Upstash Redis for persistent cache
UPSTASH_REDIS_REST_TOKEN—Upstash Redis token
NEXT_PUBLIC_URL—Engine base URL (default: http://localhost:3000)

GitHub Badges

Without a GITHUB_TOKEN, GitHub badges are limited to 60 requests/hour. Add a token to raise this to 5,000/hour.

GitHub badges hit the GitHub API which has a rate limit of 60 requests/hour without authentication. To raise this to 5,000/hour, add a GITHUB_TOKEN to your environment:

services:
  engine:
    image: ghcr.io/jal-co/shieldcn/engine:latest
    environment:
      - DATABASE_URL=postgresql://shieldcn:shieldcn@postgres:5432/shieldcn
      - GITHUB_TOKEN=ghp_your_token_here

Create a token at github.com/settings/tokens — no scopes needed (public data only).

For higher throughput, set up the token pool to distribute requests across multiple tokens.

What's Included

The self-hosted engine serves all badge endpoints:

  • All 30+ badge providers (npm, GitHub, PyPI, Docker Hub, etc.)
  • SVG, PNG, and JSON output formats
  • All variants, themes, gradients, and customization options
  • GitHub token pool with OAuth flow
  • Memo badges (persistent badges with Bearer auth)
  • Health check at /api/health/

What's Not Included

The engine does not include:

  • Documentation site
  • Gallery, showcase, or landing pages
  • Analytics (OpenPanel)
  • shadcn component registry

These are only in the packages/web site at shieldcn.dev.

Token Pool Setup

The token pool distributes GitHub API requests across multiple OAuth tokens to stay under rate limits.

Option 1: Single Token (Simple)

Set GITHUB_TOKEN to a personal access token with no scopes (public data only).

Option 2: OAuth Token Pool (Scalable)

  1. Create a GitHub OAuth App at github.com/settings/developers
  2. Set the callback URL to {NEXT_PUBLIC_URL}/api/auth/github/callback
  3. Set GITHUB_OAUTH_CLIENT_ID and GITHUB_OAUTH_CLIENT_SECRET
  4. Users can authorize at {NEXT_PUBLIC_URL}/api/auth/github

Reverse Proxy

If you want to serve badges from a custom domain:

Nginx

server {
    listen 80;
    server_name badges.example.com;

    location / {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Caddy

badges.example.com {
    reverse_proxy localhost:3000
}

Upgrading

docker compose pull
docker compose up -d

Data Source

The engine connects to the same upstream APIs as shieldcn.dev — npm registry, GitHub API, Docker Hub, etc. No data is proxied through shieldcn.dev.

On This Page

Quick StartEnvironment VariablesGitHub BadgesWhat's IncludedWhat's Not IncludedToken Pool SetupOption 1: Single Token (Simple)Option 2: OAuth Token Pool (Scalable)Reverse ProxyNginxCaddyUpgradingData Source