This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Discord GitHub Preview is a web application that generates SVG representations of Discord user profiles for embedding in GitHub READMEs and websites. The application uses a Discord bot to fetch real-time user presence data and renders it as customizable SVG cards.
- Bot Layer (
src/bot.ts): Discord.js client that maintains a connection to Discord's gateway and provides user presence data - Express Server (
src/server.ts,src/app.ts): HTTP server with caching middleware that serves the web interface and API endpoints - API Layer (
src/api/index.ts): Request handlers that validate parameters, fetch user data, and generate SVG responses - Rendering Pipeline (
src/helpers/card.ts): React-based SVG rendering system that transforms user data into styled SVG markup - Component System: Modular "displayables" that render different aspects of user profiles
Displayable Components (src/displayables/, src/types.ts):
- Each displayable implements the
DisplayableComponent<T>interface matches(): Determines if the component should render (e.g., Spotify activity only shows when user is listening to Spotify)fetchServerProp(): Async function to fetch data needed for rendering (e.g., app icons, images)render: React functional component that produces SVG markup- The system processes displayables in order, calculating Y positions dynamically based on component heights
SVG Generation Flow:
- User data fetched via Discord.js from the guild member cache
- Displayables are matched against user activities
- All async resources (avatar, banner, decoration, app icons) are fetched in parallel and converted to base64
- React components render to static SVG markup using
renderToStaticMarkup - SVG is served with appropriate headers and caching
Image Handling:
- All external images are converted to base64 via
URItoBase64()helper to make SVGs self-contained - Discord CDN images are fetched at appropriate sizes based on the
widthparameter - Avatar decorations use custom URL building since discord.js doesn't support all parameters
Required in .env:
DISCORD_TOKEN: Bot token for Discord API accessDISCORD_GUILD_ID: The guild where the bot monitors user presenceDISCORD_GUILD_INVITE: Invite link shown to users in the web interfaceDEFAULT_USER_ID: Fallback user ID for the web interface demo
pnpm dev # Run development server with hot reload (uses tsx watch)
pnpm build # Clean, compile TypeScript, and copy static assets
pnpm start # Run production server from dist/
pnpm clean # Remove dist/ directorypnpm test # Run Jest test suite
pnpm lint # Run ESLint on TypeScript filesdocker-compose up # Run containerized instance (see README for details)- The bot must be in the guild specified by
DISCORD_GUILD_ID - Users must have "Activity Privacy" enabled for the guild to allow the bot to see their activities
- The bot requires these intents:
Guilds,GuildMembers,GuildPresences - User IDs are validated to be 17+ digit numbers (Discord snowflake IDs)
- Development mode: 1 second cache (
NODE_ENV=development) - Production mode: 30 second cache (default)
- Caching is handled by
apicachemiddleware on the/api/user/:idand/api/username/:idendpoints
- URL parameters are validated using Zod v4 schemas in
src/api/index.ts - Theme-specific color requirements are enforced via Zod
.check()method - Hex colors must be provided without
#prefix and are automatically transformed - Invalid parameters return error SVGs with status 400
- Create a new file in
src/displayables/implementingDisplayableComponent<T> - Add the displayable to either
singleMatchers(for non-activity components) oractivityMatchers(for activity-based components) insrc/helpers/card.ts - Components are rendered in array order, which determines visual stacking
- Target: ES2020, Module: node16
- React JSX is enabled for TSX files
- Output directory:
./dist - Strict mode is enabled