Skip to content

ProjectStats

Combined statistics interface for project metrics. This is an intersection type that merges stats from all supported platforms.

Definition

tsx
interface GitHubStats {
  stars?: number
  forks?: number
}

interface NpmStats {
  downloads?: string
  version?: string
}

interface ProductHuntStats {
  upvotes?: number
  comments?: number
  launchDate?: string
}

interface YouTubeStats {
  subscribers?: number
  views?: number
  latestVideoTitle?: string | null
  latestVideoUrl?: string | null
  latestVideoPublishedAt?: string | null
}

interface GumroadStats {
  formattedRevenue?: string
  salesCount?: number
  subscriberCount?: number
}

interface LemonSqueezyStats {
  formattedMRR?: string
  orderCount?: number
  customerCount?: number
}

interface DevToStats {
  articleCount?: number
  totalViews?: number
  totalReactions?: number
}

type ProjectStats = GitHubStats & NpmStats & ProductHuntStats & YouTubeStats & GumroadStats & LemonSqueezyStats & DevToStats

All Properties

GitHub Stats

PropertyTypeSourceDescription
starsnumberGitHub APIRepository star count
forksnumberGitHub APIRepository fork count

Available for: github, hybrid

NPM Stats

PropertyTypeSourceDescription
downloadsstringnpm Downloads APIMonthly download count (as string)
versionstringnpm RegistryLatest published version

Available for: npm, hybrid

Product Hunt Stats

PropertyTypeSourceDescription
upvotesnumberProduct Hunt APITotal upvotes
commentsnumberProduct Hunt APITotal comments
launchDatestringProduct Hunt APIDate featured (ISO 8601)

Available for: product-hunt

YouTube Stats

PropertyTypeSourceDescription
subscribersnumberYouTube Data API v3Channel subscriber count
viewsnumberYouTube Data API v3Total channel view count
latestVideoTitlestring | nullYouTube Data API v3Title of the most recent upload
latestVideoUrlstring | nullYouTube Data API v3URL of the most recent upload
latestVideoPublishedAtstring | nullYouTube Data API v3Publish date of the most recent upload

Available for: youtubeRequires: YOUTUBE_TOKEN environment variable

Gumroad Stats

PropertyTypeSourceDescription
formattedRevenuestringGumroad APIFormatted revenue string (e.g., "$1,234.56")
salesCountnumberGumroad APITotal number of sales
subscriberCountnumberGumroad APITotal number of subscribers

Available for: gumroadRequires: GUMROAD_TOKEN environment variable

Lemon Squeezy Stats

PropertyTypeSourceDescription
formattedMRRstringLemon Squeezy APIFormatted Monthly Recurring Revenue (e.g., "$1,234.56")
orderCountnumberLemon Squeezy APITotal number of orders
customerCountnumberLemon Squeezy APITotal number of customers

Available for: lemonsqueezyRequires: LS_TOKEN environment variable

Dev.to Stats

PropertyTypeSourceDescription
articleCountnumberDev.to APITotal number of articles published
totalViewsnumberDev.to APISum of page views across all articles
totalReactionsnumberDev.to APITotal reactions across all articles

Available for: devtoRequires: No authentication (public API). Optional: DEV_TO_API_KEY env var enables page_views_count for accurate totalViews.

Stats by Project Type

TypeGitHub StatsNPM StatsPH StatsYouTube StatsGumroad StatsLS StatsDevTo Stats
github
npm
hybrid
product-hunt
youtube
gumroad
lemonsqueezy
devto
manual

Usage

tsx
import type { ProjexProject } from '@manningworks/projex'

function formatStats(project: ProjexProject): string[] {
  const stats: string[] = []
  
  if (project.stats?.stars) {
    stats.push(`${project.stats.stars} stars`)
  }
  if (project.stats?.downloads) {
    stats.push(`${project.stats.downloads} downloads`)
  }
  if (project.stats?.subscribers) {
    stats.push(`${project.stats.subscribers} subscribers`)
  }
  if (project.stats?.formattedRevenue) {
    stats.push(`${project.stats.formattedRevenue} revenue`)
  }
  if (project.stats?.articleCount) {
    stats.push(`${project.stats.articleCount} articles`)
  }
  
  return stats
}

Null Safety

The stats property on ProjexProject can be null:

tsx
if (project.stats) {
  // Safe to access stats properties
  console.log(project.stats.stars)
}

Manual projects that don't provide explicit stats will have stats: null.

Normalization

Use normalizeStats to format all stats for display:

tsx
import { normalizeStats } from '@manningworks/projex'

const formattedStats = normalizeStats(project.stats || {}, project.type)
// [{ label: 'Stars', value: '1.2K' }, { label: 'Revenue', value: '$1,234.56' }, ...]

See normalizeStats for all output labels.

Manual Stats Override

For manual project types, you can provide any stats values directly:

tsx
{
  id: 'client-project',
  type: 'manual',
  status: 'shipped',
  name: 'Client Website',
  stats: {
    // You can use any stat field as a manual override
    downloads: '5000',
    version: '2.1.0',
  }
}

For fetched types, input stats override values are merged with fetched data (input values take precedence).