Skip to main content

Introduction

The web app is the open-source part of OpenSource Together: a Next.js application covering project discovery, profiles, the contributor dashboard, and the Learn knowledge base. It’s the repository you clone, and where nearly every contribution lands. It talks to a closed-source REST API, but it also ships a complete local mock of that API, so the whole app runs offline with no credentials.

Run it in two commands

pnpm install && pnpm dev:mock

What it does

Project discovery

Infinite-scrolling project grid with search, tech-stack and category filters, and sorting

Project creation

A guided multi-step flow to import a repository from GitHub or GitLab, or claim an existing listing

Profiles

Contribution graph, pull requests, experiences, tech stacks, and pinned projects

Bookmarks & dashboard

Save projects for later; manage the ones you own

Learn

A 26-chapter MDX knowledge base, statically generated

Authentication

OAuth with GitHub and GitLab through better-auth, cookie-based sessions

Technology

  • Next.js 15.5: App Router, Turbopack in development
  • React 19.2
  • TypeScript 5.9: strict: true
  • Node 22+ and pnpm 10 (enforced: engines.node >= 22)
  • TanStack Query v5: all server state, with streaming hydration
  • Zustand v5: client state (exactly one store: the project-creation wizard)
  • React Hook Form + Zod: forms and validation
  • Tailwind CSS v4: CSS-first configuration, no tailwind.config file
  • shadcn/ui (new-york style) on Radix UI primitives
  • Motion for animation, React Icons for icons
  • Geist and Geist Mono via next/font
  • better-auth 1.6: client only; the server side lives in the private API
  • GitHub and GitLab OAuth providers
  • Biome 2.4: linting, formatting, and import organization in one tool
  • husky: a pre-commit hook that auto-formats staged files
  • MSW + Express: the local mock API
  • @opennextjs/cloudflare: Cloudflare Workers bundle
  • Docker: standalone Next.js output, published to GHCR
The project uses Biome, not ESLint and Prettier. pnpm lint checks lint rules, formatting, and import order in a single pass; pnpm lint:write fixes what it can.

How the code is organised

Code is grouped by feature, not by technical layer:
Each feature owns its own components, views, hooks, services, and types. Anything used by more than one feature moves to src/shared/.

Architecture guide

The data layer, naming conventions, and how the pieces connect.

Things worth knowing up front

next-themes is a dependency, but no theme provider is mounted and the stylesheet defines no dark token set. A handful of dark: utilities exist but aren’t reachable. Don’t assume dark mode works when styling.
Anything that comes from the API belongs to TanStack Query. Zustand holds exactly one thing: the multi-step project-creation form state.
One test file covers the mock API. There’s no component, e2e, or visual testing. Lint, types, and the builds are the safety net.

Next steps

Setup & scripts

Every script, environment variable, and tooling detail

Architecture

Conventions and the data layer

Features & routes

What lives where, and every URL in the app

Mock API

How local development works without a backend