Skip to content

Repository files navigation

FreeAPI — AI API Site Directory

English | 中文 | 日本語

License: MIT React 19 TypeScript Vite 8 Tailwind CSS Zustand 5 last commit stars

Live Demo

weed33834.github.io/FreeAPI — deployed on GitHub Pages with Supabase authentication (Email/Password).

A static, front-end directory of 278 AI API sites — LinuxDo community free stations, free chat mirrors, free/paid API relays, overseas official free tiers, domestic LLM platforms, plus an open-source framework index and a blacklist of dead endpoints. Live availability probing, deep API health checks, side-by-side site comparison, a built-in guide, and zh / en / ja UI, with zero backend by default.

FreeAPI collects the fragmented landscape of "free / cheap" LLM access points into a single filterable surface. Each entry is tagged by category, type (free / freemium / paid), status, supported models, and a short feature list (free, daily check-in, free quota, domestic, low-latency, Linux.do gated, etc.). Availability is probed from the browser with a cached fetch-based check.

The project is opinionated about not pretending: domain reachability is not API availability, and that distinction is surfaced in the UI rather than hidden.

Highlights

  • 278 curated entries across 8 categories — counts as of the last data refresh:

    Category Slug Count Coverage
    Paid relay paidrelay 104 Commercial resellers of GPT / Claude at lower unit price
    Free chat freechat 83 Mirror / aggregator chat sites, no key required
    Overseas free tier overseas 23 OpenRouter / Groq / Gemini / Cloudflare / Cohere official free tiers
    Community free linuxdo 21 LinuxDo community-run free / welfare API stations
    Blacklist blacklist 14 Confirmed dead (domain resold, SSL expired, service shut down)
    Frameworks & nav tool 12 Open-source relay frameworks, benchmarks, index sites
    Domestic official domestic 11 PRC LLM vendor official API platforms
    Free relay freerelay 10 API forwarders offering a free quota
    Total 278
  • Live availability probing — front-end fetch against API endpoints and site homepages with a 1-hour localStorage cache. Probing confirms domain reachability; see the "Live health check" section for an honest explanation of its limits.

  • Deep health check — on demand, useDeepHealthCheck goes beyond domain reachability and actually calls the API: HEAD {apiBase}/models, falling back to a minimal POST {apiBase}/chat/completions, reporting the real HTTP status code and latency so you can tell whether the API truly serves.

  • Site comparison — pin up to 4 sites (useCompareStore) and open CompareModal to contrast models, pricing, status, and features side by side.

  • Shareable filter URLsuseUrlFilters two-way syncs the toolbar state to the URL hash (#/?cat=linuxdo&type=free&kw=gpt&model=claude&status=ok&api=1), debounced 300ms, so any view is copy-paste shareable and bookmarkable.

  • Keyboard shortcuts/ focuses the search box, Esc clears all filters (home view only; suppressed while typing in inputs).

  • Toast notifications — a global ToastContainer backed by useToastStore surfaces copy / auth / report feedback without modal interruptions.

  • Theme toggle — default cyberpunk dark theme with an optional light theme (useThemeStore, persisted to localStorage under FreeAPI-theme).

  • Built-in guide#/guide renders a 5-section collapsible guide with curl / Python / Node examples for wiring a relay site into OpenAI-compatible clients.

  • Trilingual UIzh / en / ja, preference persisted to localStorage (FreeAPI-lang); site data (name / desc / tagline) stays in its source language, only framework strings are translated.

  • Mobile-first — responsive grid (2 cols on phone → 8 cols on wide screens), compact spacing, stacked toolbar.

  • Cyberpunk terminal aesthetic — dark-first palette, monospaced data, scan-line animation, with a light theme option.

  • Installable PWApublic/manifest.json (standalone display, themed, maskable icon) lets you add FreeAPI to your home screen.

  • No backend dependency by default — all site data is compiled into the bundle; deployable to any static host.

UI & theme

Token Hex Use
cyber.bg #0a0e14 Page background
cyber.cyan #00e5ff Primary accents, "online"
cyber.magenta #ff2e88 Free-chat category
cyber.amber #ffb020 Paid relay, "unstable"
cyber.green #34d399 "OK" status
cyber.violet #7c5cff Free relay
cyber.blue #60a5fa Domestic official
cyber.dead #ef4444 Blacklist / "dead"

Typography: Chakra Petch (display) + JetBrains Mono (monospaced data) + Noto Sans SC (body). The muted token was raised to #8b95a8 to clear WCAG AA contrast (≥ 4.6:1) against the background.

Tech stack

Layer Choice
Framework React 19.2 + TypeScript 7.0
Build Vite 8
Styling Tailwind CSS 4 (dark-mode class, light theme toggle)
State Zustand 5 (theme + favorites persisted; filter state in-memory)
Auth Supabase (Email/Password)
Routing custom hash routing (#/blacklist, #/me, #/guide)
Icons lucide-react
Probing Front-end fetch (HEAD) + deep POST /chat/completions check
PWA Web App Manifest (public/manifest.json)

Architecture

flowchart LR
  subgraph Bundle["Static bundle (dist/)"]
    A[React UI] --> S[sites.ts<br/>278 entries]
    A --> F[useFilterStore<br/>Zustand]
    A --> UF[useUrlFilters<br/>hash ↔ filters]
    A --> H[useSiteHealth]
    A --> DC[useDeepHealthCheck]
    A --> CMP[useCompareStore]
    A --> TH[useThemeStore]
    A --> T[useToastStore]
  end
  H -->|fetch HEAD /models or /| B[(Browser localStorage<br/>1h TTL cache)]
  DC -->|HEAD /models + POST /chat/completions| N[(Network)]
  A -->|auth + favorites| SB[(Supabase<br/>auth + DB)]
  A --> R{hash route}
  R -->|#/blacklist| BL[Blacklist page]
  R -->|#/me| PF[Profile page]
  R -->|#/guide| GD[Guide page]
  R -->|default| HM[Home page]
Loading

Quick start

# install (pnpm recommended; npm works too)
pnpm install

# dev server at http://localhost:5173
pnpm dev

# type-check + production build → dist/
pnpm check && pnpm build

# lint
pnpm lint

Requires Node 20+ and a recent pnpm.

Environment variables (create a .env file — never commit it):

VITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_ANON_KEY=your-anon-key

Without these, login is disabled and the site works as a read-only directory.

Project structure

freeapi/
├── src/
│   ├── components/
│   │   ├── Hero.tsx            # header, category stat cards, live badge
│   │   ├── Toolbar.tsx         # search / model / sort / type / status filters
│   │   ├── SiteGrid.tsx        # grouped + flat grid rendering
│   │   ├── SiteCard.tsx        # single entry card + feature tags
│   │   ├── DetailDrawer.tsx    # per-site detail drawer + deep health check
│   │   ├── CompareModal.tsx    # side-by-side comparison of up to 4 sites
│   │   ├── ToastContainer.tsx  # global toast notification stack
│   │   ├── AuthModal.tsx       # Email/Password register & login modal
│   │   ├── PasswordInput.tsx   # password field with show/hide toggle
│   │   ├── UserMenu.tsx        # user dropdown with profile link & logout
│   │   ├── LangSwitcher.tsx    # zh / en / ja switcher
│   │   ├── ReportModal.tsx     # site issue reporting modal
│   │   └── ErrorBoundary.tsx   # top-level error fallback
│   ├── data/sites.ts           # canonical site list + category/type/status meta
│   │                           #   + deriveFeatures() auto-tagging
│   ├── i18n/
│   │   ├── translations.ts     # zh / en / ja dictionary + format()
│   │   └── useI18n.ts          # zustand store + useT() + translateFeature()
│   ├── lib/
│   │   ├── supabase.ts         # Supabase client + AUTH_ENABLED flag
│   │   ├── auth-utils.ts       # Email validation + error mapping
│   │   ├── constants.ts        # FEATURE_COLOR, CAT_ORDER, LIVE_COLOR
│   │   ├── date-utils.ts       # relative-time formatting helpers
│   │   └── utils.ts            # cn() + copyToClipboard
│   ├── store/
│   │   ├── useFilterStore.ts   # filter state + derived visible sites + live status
│   │   ├── useAuthStore.ts     # Supabase session + user
│   │   ├── useFavoritesStore.ts# favorites with DB sync + localStorage
│   │   ├── useCompareStore.ts  # compare tray (max 4) + modal open state
│   │   └── useToastStore.ts    # toast queue + push / dismiss
│   ├── hooks/
│   │   ├── useSiteHealth.ts    # batched reachability probing + useDeepHealthCheck
│   │   ├── useUrlFilters.ts    # two-way sync of filters ↔ URL hash
│   │   ├── useKeyboard.ts      # `/` focus search, `Esc` clear filters
│   │   ├── useTheme.ts         # dark/light theme store + <html> class
│   │   └── useUserProfile.ts   # profile data fetch + cache
│   ├── pages/
│   │   ├── Home.tsx
│   │   ├── Blacklist.tsx       # #/blacklist
│   │   ├── Profile.tsx         # #/me — saved favorites, user info
│   │   └── Guide.tsx           # #/guide — usage guide with code examples
│   ├── App.tsx                 # hash router (home / blacklist / me / guide / 404)
│   └── main.tsx
├── scripts/                    # site export / verification scripts
└── public/
    ├── manifest.json           # PWA manifest (standalone, themed, maskable icon)
    ├── favicon.svg
    ├── robots.txt
    └── sitemap.xml

Data model

All entries live in src/data/sites.ts:

interface Site {
  id: string;
  name: string;
  url: string;
  category: 'linuxdo' | 'freechat' | 'freerelay' | 'paidrelay'
          | 'overseas' | 'domestic' | 'tool' | 'blacklist';
  type: 'free' | 'freemium' | 'paid';
  status: 'ok' | 'unstable' | 'unknown' | 'dead';
  models: string[];
  desc: string;
  tagline?: string;          // one-line positioning under the name
  features?: string[];        // explicit tags; auto-derived if absent
  apiBase?: string;
  billing?: string;
  register?: string;
  payment?: string;
  note?: string;
  pros?: string[];            // site advantages (shown in detail drawer)
  cons?: string[];            // site disadvantages (shown in detail drawer)
  tips?: string;              // usage tips (shown in detail drawer)
  blacklistReason?: string;   // only for category === 'blacklist'
  blacklistReasonType?: 'domain-sale' | 'http-error' | 'not-found'
                       | 'repo-removed' | 'service-stopped'
                       | 'ssl-error' | 'timeout' | 'other';
}

When features is omitted, deriveFeatures() infers tags from type / billing / note / register / desc (e.g. type === 'free'免费, mention of "签到" → 签到). Tag → colour mapping lives in FEATURE_COLOR inside src/lib/constants.ts.

Internationalisation

  • Three locales: zh / en / ja, dictionary in src/i18n/translations.ts.
  • useT() for component strings; translate() for non-hook contexts.
  • Site data (name / desc / tagline) is kept in its source language — only framework UI is translated.
  • Feature tags translate via translateFeature() keyed as feat.<source-label>.
  • Language choice persists to localStorage under FreeAPI-lang; missing keys fall back to Chinese.

Live health check

The front-end probe is deliberately honest about its limits: a fetch HEAD against API endpoints or site homepages can only confirm that the domain responds, not that the API serves. Relay home pages almost always return 200, so "domain up" ≠ "API usable". The UI labels this distinction rather than masking it.

For when reachability is not enough, the per-site detail drawer offers a deep health check (useDeepHealthCheck): it issues HEAD {apiBase}/models and, if that is inconclusive, a minimal POST {apiBase}/chat/completions, then surfaces the real HTTP status code and latency. This is the closest a zero-backend, browser-only probe can get to verifying that an API actually serves — bounded, as ever, by CORS (no-cors fallbacks return unknown rather than a false "up").

sequenceDiagram
  participant U as User opens app
  participant F as useSiteHealth
  participant LS as localStorage cache
  participant Net as Network (fetch HEAD)
  U->>F: mount
  F->>LS: read FreeAPI:live-status
  alt cache fresh (< 1h)
    F-->>U: render cached status instantly
  else stale
    F->>Net: batched probe (8 sites / 300ms gap)
    Net-->>F: HTTP status → up | timeout → down
    F->>LS: write updated entries
    F-->>U: progressive UI update + progress bar
  end
Loading

User system

FreeAPI supports optional login via Supabase:

  • Email/Password — register with email + password + username, no email verification required
  • Password reset — forgot password? send a reset link to email, update password on return

Once logged in, you can favorite sites (heart icon on each card) and view them later on the Profile page (#/me). Favorites sync to the database (cross-device) with localStorage as offline cache.

Auth state is managed in useAuthStore (Zustand) and session is synced with Supabase in real-time. The UI adapts: unauthenticated users see a "Login" button; logged-in users see their avatar with a dropdown to navigate to Profile or sign out.

Deployment

The front-end is deployed to GitHub Pages via GitHub Actions (.github/workflows/deploy.yml). On every push to main, the workflow:

  1. Checks out the repo and installs pnpm dependencies
  2. Injects VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY from GitHub Secrets
  3. Builds the production bundle with pnpm build
  4. Uploads and deploys the dist/ artifact to GitHub Pages

The site is served from https://weed33834.github.io/FreeAPI/. Hash routing (#/blacklist, #/me) requires no server-side rewrite rules.

For self-hosting: pnpm build produces dist/, uploadable to any static host (Vercel, Netlify, GitHub Pages).

Contributing

Site additions, status corrections, and translation fixes are all welcome. Add entries to src/data/sites.ts following the schema above; fill tagline and features where possible since deriveFeatures() only covers the common cases. When adding a new feature tag, also extend feat.<label> in all three languages and update FEATURE_COLOR in src/lib/constants.ts. See CONTRIBUTING.md for the full workflow and submission norms.

The project does not list sites that violate applicable law or ship malware / phishing / crypto-mining payloads. Dead sites are moved to blacklist with a recorded reason rather than silently deleted.

License

MIT © 2026 weed

About

AI API Site Directory - 240+ entries, live probing, zh/en/ja, Supabase Auth

Topics

Resources

Contributing

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages