Skip to main content

Overview

Who To Bother follows a clear, domain-driven structure organized by feature and functionality. The codebase uses TypeScript throughout with strict type checking enabled.

Root Directory

who-to-bother/
├── src/                    # Source code
├── public/                 # Static assets
├── node_modules/           # Dependencies
├── dist/                   # Build output
├── package.json            # Dependencies and scripts
├── tsconfig.json           # TypeScript configuration
├── vite.config.ts          # Vite build configuration
├── wrangler.jsonc          # Cloudflare deployment config
├── tailwind.config.ts      # Tailwind CSS configuration
├── biome.json              # Biome/Ultracite linting config
└── README.md               # Project documentation

Source Directory (src/)

Complete Structure

src/
├── app/                    # Routes and pages (TanStack Start)
│   ├── __root.tsx         # Root layout component
│   ├── index.tsx          # Home page (/)
│   ├── $company.tsx       # Dynamic company page (/:company)
│   ├── search.tsx         # Search page (/search)
│   ├── stats.tsx          # Statistics page (/stats)
│   ├── sponsors.tsx       # Sponsors page (/sponsors)
│   ├── login.tsx          # Login page (/login)
│   ├── dashboard.tsx      # User dashboard (/dashboard)
│   ├── opengraph.tsx      # OG image generator (/opengraph)
│   ├── api/               # API routes
│   │   ├── auth/          # Authentication endpoints
│   │   │   └── $.ts       # Better Auth handler
│   │   └── github/        # GitHub integration
│   │       ├── fork.ts    # Fork repository
│   │       ├── companies.ts    # Get company data
│   │       └── create-pr.ts    # Create pull request
│   ├── contribute/        # Contribution workflow
│   │   ├── index.tsx      # Contribution home
│   │   ├── add.tsx        # Add new company
│   │   ├── edit.tsx       # Edit company list
│   │   └── edit.$company.tsx   # Edit specific company
│   └── og/                # Open Graph images
│       ├── $company.tsx   # Company OG image
│       └── search.tsx     # Search OG image

├── components/            # React components
│   ├── ui/               # Reusable UI primitives
│   │   ├── avatar.tsx    # User avatar
│   │   ├── badge.tsx     # Status badges
│   │   ├── button.tsx    # Button variants
│   │   ├── input.tsx     # Form inputs
│   │   ├── kbd.tsx       # Keyboard shortcuts
│   │   ├── label.tsx     # Form labels
│   │   ├── popover.tsx   # Popover overlay
│   │   ├── tabs.tsx      # Tab navigation
│   │   ├── textarea.tsx  # Multi-line input
│   │   ├── toggle.tsx    # Toggle switch
│   │   └── toggle-group.tsx   # Toggle group
│   │
│   ├── contribute/       # Contribution-specific components
│   │   ├── company-form.tsx   # Company edit form
│   │   ├── pr-status.tsx      # PR status display
│   │   └── svg-uploader.tsx   # Logo SVG uploader
│   │
│   ├── company-logos.tsx      # Company logo display
│   ├── contacts-list.tsx      # Contact list component
│   ├── header.tsx            # Site header
│   ├── footer.tsx            # Site footer
│   ├── theme-provider.tsx    # Dark mode provider
│   └── theme-toggle.tsx      # Theme switcher

├── data/                 # Static data and schemas
│   └── companies/        # Company data directory
│       ├── schema.ts     # Valibot validation schema
│       ├── schema.json   # Generated JSON Schema
│       ├── vercel.json   # Example: Vercel company data
│       ├── appwrite.json # Example: Appwrite company data
│       └── ...           # Additional company files

├── lib/                  # Utility libraries
│   ├── auth.ts          # Authentication setup
│   ├── auth-client.ts   # Auth client utilities
│   ├── auth-middleware.ts    # Auth middleware
│   ├── github.ts        # GitHub API integration
│   ├── search.ts        # Fuse.js search setup
│   ├── seo.ts           # SEO utilities
│   ├── theme.ts         # Theme management
│   ├── use-theme.ts     # Theme React hook
│   └── utils.ts         # General utilities

├── scripts/             # Build and utility scripts
│   ├── generate-favicons.ts   # Generate favicon assets
│   ├── generate-sitemap.ts    # Generate sitemap.xml
│   ├── generate-json-schema.ts     # Generate JSON Schema
│   └── validate-companies.ts      # Validate company data

├── types/               # TypeScript type definitions
│   └── ...              # Global types

├── routeTree.gen.ts    # Generated route tree (auto-generated)
└── vite-env.d.ts       # Vite environment types

Key Directories

/src/app - Routes & Pages

TanStack Start uses file-based routing where each file in app/ becomes a route.
__root.tsx
Layout
Root layout component wrapping all pages.Contains:
  • Global providers (theme, auth)
  • Common layout elements (header, footer)
  • Error boundaries
index.tsx
Page
Home page (/) - Landing page with company directory
$company.tsx
Dynamic Route
Individual company page (/:company)
  • URL parameter: company (company ID)
  • Displays company details and contacts
  • Dynamic OG images
api/
API Routes
Server-side API endpointsAuthentication (api/auth/):
  • Better Auth integration for GitHub OAuth
GitHub Integration (api/github/):
  • fork.ts - Fork repository for contributions
  • companies.ts - Fetch company data from GitHub
  • create-pr.ts - Create pull requests
contribute/
Feature Group
Contribution workflow pages
  • index.tsx - Contribution options
  • add.tsx - Add new company form
  • edit.tsx - Select company to edit
  • edit.$company.tsx - Edit specific company

/src/components - UI Components

ui/
Primitive Components
Low-level, reusable UI components built with Radix UI primitives.All components:
  • Use Tailwind CSS for styling
  • Support dark mode
  • Include accessibility features
  • Export component types for TypeScript
contribute/
Feature Components
Domain-specific components for the contribution workflow:
  • company-form.tsx: TanStack Form implementation for editing company data
  • pr-status.tsx: Shows PR creation status and GitHub link
  • svg-uploader.tsx: Logo upload and preview component
Root Components
Shared
  • company-logos.tsx: Company logo grid display
  • contacts-list.tsx: Searchable contact list with categories
  • header.tsx: Site navigation and search
  • footer.tsx: Footer with links
  • theme-provider.tsx: Dark mode context provider
  • theme-toggle.tsx: Light/dark mode switcher

/src/data/companies - Company Data

schema.ts
Valibot Schema
Source of truth for data validation.Exports:
  • CompanySchema - Valibot validation schema
  • Company - Inferred TypeScript type
  • Category - Category type
  • Contact - Contact type
See Data Schema for complete documentation.
schema.json
JSON Schema
Auto-generated JSON Schema for IDE autocomplete.Generated by: pnpm generate-schemaReferenced in company JSON files:
{
  "$schema": "./schema.json",
  ...
}
*.json
Company Data
Individual company data files.Naming convention: {company-id}.jsonExample: vercel.json, appwrite.json, cloudflare.json

/src/lib - Utility Libraries

auth.ts
Authentication
Better Auth configuration and setup.Handles:
  • GitHub OAuth provider
  • Session management
  • User data
github.ts
GitHub API
GitHub API integration for contribution workflow.Functions:
  • Fork repository
  • Create/update files
  • Create pull requests
  • Fetch company data
search.ts
Search
Fuse.js fuzzy search configuration.Searches across:
  • Company names
  • Descriptions
  • Product names
  • Contact handles
seo.ts
SEO
SEO utilities for meta tags and Open Graph images.
  • Dynamic page titles
  • OG image generation
  • Meta descriptions
theme.ts
Theme
Theme management utilities.
  • Dark/light mode toggle
  • System preference detection
  • Local storage persistence
utils.ts
General Utilities
Shared utility functions.Common utilities:
  • cn() - Merge Tailwind classes with clsx and tailwind-merge
  • String manipulation
  • Array helpers

/src/scripts - Build Scripts

generate-favicons.ts
Build Script
Generates favicon assets for all platforms.Run: pnpm generate-faviconsCreates:
  • favicon.ico
  • apple-touch-icon.png
  • Various sizes for PWA
generate-sitemap.ts
Build Script
Generates sitemap.xml for SEO.Run: pnpm generate-sitemapIncludes:
  • Home page
  • All company pages
  • Static pages (search, stats, sponsors)
validate-companies.ts
Validation
Validates all company JSON files against Valibot schema.Run: pnpm validateChecks:
  • Schema compliance
  • Required fields
  • Format validation (URLs, emails, handles)
Runs automatically in prebuild script.
generate-json-schema.ts
Schema Generation
Converts Valibot schema to JSON Schema.Run: pnpm generate-schemaOutput: src/data/companies/schema.jsonEnables IDE autocomplete for company JSON files.

Configuration Files

TypeScript Configuration

Vite Configuration

Cloudflare Configuration

Import Aliases

The project uses TypeScript path aliases for cleaner imports:
// Instead of: import { Button } from "../../../components/ui/button"
import { Button } from "@/components/ui/button";

// Instead of: import { Company } from "../../../data/companies/schema"
import type { Company } from "@/data/companies/schema";
Configuration: tsconfig.jsonpaths"@/*": ["./src/*"]

File Naming Conventions

Components
kebab-case
company-logos.tsx, contacts-list.tsx
Routes
kebab-case or $param
  • Static: search.tsx, stats.tsx
  • Dynamic: $company.tsx, edit.$company.tsx
Utilities
kebab-case
use-theme.ts, auth-client.ts
Company Data
kebab-case.json
vercel.json, better-auth.json, cloud-flare.json

Build Output

dist/
├── client/              # Client-side assets
│   ├── assets/         # Bundled JS/CSS
│   └── index.html      # Entry HTML
└── server/             # Server-side bundle
    └── index.js        # Cloudflare Worker entry

Build docs developers (and LLMs) love