Skip to content

Architecture Overview

Zaal Panthaki edited this page Mar 29, 2026 · 1 revision

Architecture Overview

ZAO OS is a Next.js 16 application using the App Router with React 19 Server Components and Client Components. Data lives in Supabase PostgreSQL with Row-Level Security. Social features run on the Farcaster protocol via Neynar. Everything is TypeScript.


Tech Stack

Layer Technology Purpose
Framework Next.js 16, React 19, TypeScript 5 App shell, routing, SSR/RSC
Styling Tailwind CSS v4 Utility-first CSS, dark theme
Database Supabase PostgreSQL Data storage, RLS, real-time
Auth iron-session Encrypted httpOnly cookies, 7-day TTL
Social Neynar SDK (Farcaster) Casts, reactions, signers, channels
Messaging XMTP (MLS protocol) E2E encrypted DMs and groups
Web3 (EVM) Wagmi, Viem, RainbowKit Wallet connections, contract reads
Web3 (Solana) Solana Web3.js, Wallet Adapter WaveWarZ integration
Voice 100ms HMS SDK Live audio rooms
Video Jitsi React SDK Video calls
Streaming Livepeer SDK Multistream, recording, clipping
Storage Arweave, ArDrive Turbo Permanent music storage
Analytics PostHog Event tracking, user identification
Rate Limiting Upstash Redis Per-IP API rate limits
Validation Zod Input validation on all API routes
State React Query (@tanstack) Server state, caching, mutations
Cross-posting twitter-api-v2, @atproto/api, @hiveio/dhive, discord.js Multi-platform publishing

Project Structure

src/
├── app/                      # Next.js App Router
│   ├── (auth)/               # Protected routes (requires session)
│   │   ├── home/             # Dashboard
│   │   ├── chat/             # Farcaster channel feed
│   │   ├── music/            # Music player & library
│   │   ├── messages/         # XMTP encrypted DMs
│   │   ├── governance/       # Snapshot polls
│   │   ├── fractals/         # Fractal governance
│   │   ├── respect/          # Respect leaderboard
│   │   ├── library/          # Knowledge base
│   │   ├── directory/        # Member directory
│   │   ├── settings/         # User preferences
│   │   ├── admin/            # Admin dashboard (7 tabs)
│   │   ├── wavewarz/         # Solana prediction market
│   │   ├── ecosystem/        # Partner integrations
│   │   └── ...               # notifications, social, calls, etc.
│   ├── api/                  # Route handlers
│   │   ├── auth/             # SIWF, SIWE, session, signers
│   │   ├── chat/             # Messages, threads, reactions, search
│   │   ├── music/            # Library, playlists, trending, radio, mint
│   │   ├── members/          # Directory, profiles
│   │   ├── admin/            # Users, allowlist, health, sync
│   │   ├── respect/          # Leaderboard, sync, transfers
│   │   ├── fractals/         # Sessions, proposals, analytics
│   │   ├── publish/          # Cross-platform posting
│   │   ├── platforms/        # OAuth for X, Twitch, YouTube, etc.
│   │   ├── hats/             # Hats Protocol checks
│   │   ├── zounz/            # Nouns Builder proposals
│   │   ├── snapshot/         # Snapshot polls
│   │   ├── 100ms/            # Voice room tokens
│   │   └── ...               # search, upload, notifications, etc.
│   ├── spaces/               # Public voice channel pages
│   ├── members/              # Public profile pages
│   └── page.tsx              # Landing / login
├── components/               # React components by feature
│   ├── music/                # 30+ components (player, queue, EQ, etc.)
│   ├── chat/                 # 16 components (messages, compose, search)
│   ├── admin/                # 12 components (dashboard tabs)
│   ├── governance/           # Snapshot + fractal components
│   ├── spaces/               # Voice room components
│   ├── messages/             # XMTP DM components
│   └── ...                   # members, settings, hats, zounz, etc.
├── hooks/                    # Custom React hooks
│   ├── useAuth.ts            # Authentication state
│   ├── useChat.ts            # Channel chat operations
│   ├── usePlayerQueue.ts     # Music queue management
│   ├── useRadio.ts           # Radio mode state
│   ├── useListeningRoom.ts   # Listening room state
│   └── ...                   # 16 total hooks
├── contexts/                 # React contexts
│   ├── QueueContext.tsx       # Music queue state
│   └── XMTPContext.tsx        # XMTP messaging state (500+ lines)
├── providers/                # Provider wrappers
│   └── audio/                # PlayerProvider, HTMLAudioProvider, etc.
├── lib/                      # Utilities by domain
│   ├── auth/                 # iron-session config
│   ├── db/                   # Supabase client setup
│   ├── farcaster/            # Neynar SDK client
│   ├── music/                # Curation, audio filters, Audius, Arweave
│   ├── publish/              # Cross-platform publishing
│   ├── gates/                # Allowlist gating
│   ├── hats/                 # Hats Protocol client
│   ├── validation/           # Zod schemas
│   ├── moderation/           # AI content moderation
│   └── ...                   # ens, bluesky, snapshot, discord, etc.
└── types/                    # TypeScript type definitions

community.config.ts           # ALL community-specific configuration

Key Architecture Decisions

Single Config File

Everything community-specific — branding, channels, contracts, admin FIDs, partners, nav structure — lives in community.config.ts. This is the one file forkers need to change to make ZAO OS their own. See Fork Guide: Getting Started.

Server Components by Default

Pages are React Server Components unless they need interactivity. Client components use "use client" directive and are code-split with next/dynamic when heavy.

No ORM

Direct Supabase client queries instead of an ORM. Simpler, fewer abstractions, easier to understand what's happening at the database level. RLS handles authorization at the database layer.

iron-session Over JWT

Encrypted httpOnly cookies (iron-session) instead of JWTs. Can't be read by JavaScript, can't be stolen from localStorage, 7-day TTL with automatic refresh.

Dual Auth Methods

SIWF (Sign In With Farcaster) for social features, SIWE (Sign In With Ethereum) for token holders. Progressive onboarding — start with wallet, add Farcaster for posting, add XMTP for encrypted messaging.

Farcaster Casts Cached in Supabase

Public messages are Farcaster casts, but we cache them in Supabase for fast loading, search, and filtering. Neynar webhooks keep the cache fresh.

Provider Pattern for Audio

Each music platform has its own provider class. The PlayerProvider orchestrates them — detecting which provider to use based on the URL, managing playback state, and handling transitions (crossfade) between tracks.

React Query for Server State

All API data flows through @tanstack/react-query — automatic caching, background refetching, optimistic updates. No Redux, no Zustand, no global state libraries.

Middleware Rate Limiting

Per-IP rate limits on all API route families, enforced in src/middleware.ts via Upstash Redis. Protects against abuse without adding complexity to individual routes.


Data Flow

User Action
    → React Component (Client)
    → React Query mutation/query
    → API Route Handler (Server)
    → Zod validation
    → Session check (iron-session)
    → Supabase query (with RLS)
    → Response → React Query cache → UI update

For Farcaster operations:

User posts a cast
    → API Route → Neynar SDK → Farcaster network
    → Neynar webhook fires → API Route → Supabase cache updated
    → React Query invalidation → UI shows new cast

For XMTP messaging:

User sends DM
    → XMTPContext → XMTP SDK → MLS encryption → XMTP network
    → Recipient's XMTP stream receives → XMTPContext → UI update
    (Never touches our server — true E2E encryption)

Security Model

See the Fork Guide: Database & Auth for setup details. Key points:

  • RLS on all tables — Supabase Row-Level Security, not application-level auth checks
  • Server-only secretsSUPABASE_SERVICE_ROLE_KEY, NEYNAR_API_KEY, SESSION_SECRET, APP_SIGNER_PRIVATE_KEY never exposed to browser
  • Zod on all inputs — every API route validates with safeParse before processing
  • HMAC webhook verification — Neynar and Alchemy webhooks verified with SHA-512 signatures
  • No dangerouslySetInnerHTML — ever
  • CSP headers — Content Security Policy in middleware
  • Rate limiting — per-IP on all API routes

Clone this wiki locally