FckSignups Architecture Explained: React SPA + Cloudflare Worker Design

FckSignups (now NoSignups) uses a client-heavy React + TypeScript single-page application with a lightweight serverless Cloudflare Worker backend for handling tool submissions, reports, and suggestions.

The FckSignups architecture prioritizes speed, privacy, and zero user tracking by running entirely in the browser with minimal server-side logic. This guide breaks down how the front-end handles data flow, state management, and modal interactions, plus how the Cloudflare Worker manages form submissions through GitHub issues.

Front-End Architecture: React SPA with Custom Hooks

The browser application follows a hook-driven design that centralizes data fetching, filtering, and UI state in reusable TypeScript modules.

Root Component and Global Providers

[src/App.tsx](https://github.com/BraveOPotato/FckSignups/blob/main/src/App.tsx) serves as the application entry point. It mounts three core providers:

  • ModalProvider – manages modal visibility and submission flows
  • ReportProvider – supplies the floating report widget context
  • Tool data context – implicitly provided through the useTools hook consumed by child components

This provider pattern ensures that modal state and reporting functionality remain available throughout the component tree without prop drilling.

Data Layer: The useTools Hook

[src/hooks/useTools.ts](https://github.com/BraveOPotato/FckSignups/blob/main/src/hooks/useTools.ts) is the central data engine. It handles:

  1. JSON loading – Fetches from DEV_JSON_URL or PROD_JSON_URL with FALLBACK_DATA as a static safety net
  2. Search scoring – Tokenizes queries and computes matchScore for relevance ranking
  3. Category filtering – Groups tools into featured, editors-pick, and meetsCriteria sections
  4. Memoized computation – Uses useMemo to avoid recalculating filtered results on every render
// src/hooks/useTools.ts – core data hook signature
export function useTools() {
  const [searchQuery, setSearchQuery] = useState("");
  const [activeCategory, setActiveCategory] = useState<string | null>(null);
  
  // Inside: fetch logic, scoring algorithm, section building
  return {
    filteredTools,
    isSearching,
    categories,
    featuredTools,
    setSearchQuery,
    setActiveCategory,
  };
}

Source: [src/hooks/useTools.ts](https://github.com/BraveOPotato/FckSignups/blob/main/src/hooks/useTools.ts)

The modal architecture splits responsibilities across two files:

import { useModal } from "./hooks/useModal";

function SubmitButton() {
  const { showModalWithID } = useModal();
  
  return (
    <button onClick={() => showModalWithID("submit-tool")}>
      Submit a Tool
    </button>
  );
}

Source: [src/hooks/useModal/useModal.tsx](https://github.com/BraveOPotato/FckSignups/blob/main/src/hooks/useModal/useModal.tsx)

Reporting System: Floating Widget Pattern

[src/hooks/useReport.tsx](https://github.com/BraveOPotato/FckSignups/blob/main/src/hooks/useReport.tsx) implements a ReportProvider that renders a persistent ReportFloatingWidget. Unlike modals, this remains mounted globally and accepts a toolId parameter to pre-populate which tool is being reported.

UI Component Structure

The src/components/ directory organizes reusable pieces:

Styling splits between global CSS in [src/styles/index.css](https://github.com/BraveOPotato/FckSignups/blob/main/src/styles/index.css) and component-scoped CSS modules.

Data Flow: From Fetch to Filtered Render

Understanding FckSignups data flow reveals how the architecture maintains responsiveness without a traditional backend:

  1. Initial load – useTools executes fetch() against the production or development JSON endpoint
  2. Network failure – Falls back to static FALLBACK_DATA from [src/constants/fallbackData.ts](https://github.com/BraveOPotato/FckSignups/blob/main/src/constants/fallbackData.ts)
  3. User input – setSearchQuery or setActiveCategory triggers useMemo recomputation
  4. Scoring – Each tool receives a matchScore based on token frequency in name, description, and tags
  5. Section assignment – Tools route to featured, editors-pick, or standard meetsCriteria arrays
  6. Render – Components consume filteredTools and render with zero additional network requests

This entirely client-side pipeline eliminates loading states between filter changes and keeps the application functional offline after initial load.

Back-End Architecture: Cloudflare Worker Router

The serverless backend in cloudflare-worker/ handles three POST operations, all creating GitHub issues rather than persisting to a database. This design choice removes authentication requirements and creates an audit trail through GitHub's native interface.

Worker Entry Point

[cloudflare-worker/worker.ts](https://github.com/BraveOPotato/FckSignups/blob/main/cloudflare-worker/worker.ts) implements a minimal router:

Endpoint Handler Purpose
/submit-tool handleSubmitTool Creates GitHub issue for new tool submissions
/report-tool handleReportTool Creates issue flagging problematic tools
/suggest-tool handleSuggestTool Creates issue for tool suggestions
// cloudflare-worker/worker.ts – simplified router structure
export default {
  async fetch(request: Request, env: Env, ctx: ExecutionContext) {
    const url = new URL(request.url);
    const origin = request.headers.get("Origin") || "";
    
    if (url.pathname === "/submit-tool") {
      return handleSubmitTool(request, env, origin);
    }
    // ... additional routes
  }
};

Handler Implementation: GitHub Issue Creation

[cloudflare-worker/urlHandlers/handleSubmitTool.ts](https://github.com/BraveOPotato/FckSignups/blob/main/cloudflare-worker/urlHandlers/handleSubmitTool.ts) demonstrates the serverless pattern:

export async function handleSubmitTool(
  request: Request, 
  env: Env, 
  origin: string
) {
  const body = await request.json();
  
  const issue = {
    title: `[New Tool] ${body.name}`,
    body: `**URL:** ${body.url}\n` +
          `**Description:** ${body.description}\n` +
          `**Category:** ${body.category}\n` +
          `**Submitted by:** ${body.submitterEmail || "Anonymous"}`,
    labels: ["new-tool", "pending-review"]
  };
  
  const response = await fetch(
    `https://api.github.com/repos/${env.GITHUB_REPO_OWNER}/${env.GITHUB_REPO_NAME}/issues`,
    {
      method: "POST",
      headers: {
        "Authorization": `Bearer ${env.GITHUB_TOKEN}`,
        "Content-Type": "application/json",
        "Accept": "application/vnd.github+json"
      },
      body: JSON.stringify(issue)
    }
  );
  
  return jsonResponse(
    { success: response.ok, issueUrl: response.ok ? (await response.json()).html_url : null },
    response.ok ? 201 : 500,
    origin
  );
}

Source: [cloudflare-worker/urlHandlers/handleSubmitTool.ts](https://github.com/BraveOPotato/FckSignups/blob/main/cloudflare-worker/urlHandlers/handleSubmitTool.ts)

CORS and Utility Layer

[cloudflare-worker/utils.ts](https://github.com/BraveOPotato/FckSignups/blob/main/cloudflare-worker/utils.ts) centralizes cross-origin handling and JSON response formatting. All handlers import jsonResponse() to ensure consistent CORS headers and content-type settings.

Secret Management

The FckSignups architecture keeps credentials out of source code through Wrangler secrets:

  • GITHUB_TOKEN – Personal access token with repo scope
  • GITHUB_REPO_OWNER – Organization or user name
  • GITHUB_REPO_NAME – Target repository for issues

These bind to the env parameter in each handler and are never exposed to the client bundle.

Build and Deployment Pipeline

Tool Purpose Key File
Vite Bundling and dev server vite.config.mts
Wrangler Cloudflare Worker deployment [wrangler.toml](https://github.com/BraveOPotato/FckSignups/blob/main/wrangler.toml)

The build process produces:

  • Static assets deployable to Vercel, Netlify, or any static host
  • Worker script pushed to Cloudflare's edge network via wrangler deploy

This decoupled deployment allows the React front-end and serverless back-end to scale independently and update separately.

Summary

  • FckSignups architecture centers on a React + TypeScript SPA with zero server-side rendering
  • Custom hooks (useTools, useModal, useReport) manage all state, data, and UI interactions
  • Client-side filtering with matchScore ranking eliminates backend queries during searches
  • Cloudflare Worker provides three POST endpoints that create GitHub issues instead of database records
  • Secrets inject via Wrangler; no authentication or tracking systems exist in the client
  • Vite + Wrangler toolchain enables fast local development and independent deployment of front-end and worker

Frequently Asked Questions

What state management library does FckSignups use?

FckSignups uses React Context and custom hooks exclusively. No Redux, Zustand, or Jotai appears in the codebase. The ModalProvider in [src/hooks/useModal/useModal.tsx](https://github.com/BraveOPotato/FckSignups/blob/main/src/hooks/useModal/useModal.tsx) and ReportProvider in [src/hooks/useReport.tsx](https://github.com/BraveOPotato/FckSignups/blob/main/src/hooks/useReport.tsx) demonstrate this pattern.

How does FckSignups handle offline functionality?

The useTools hook implements a fallback data strategy. If both DEV_JSON_URL and PROD_JSON_URL network requests fail, it immediately returns static FALLBACK_DATA from [src/constants/fallbackData.ts](https://github.com/BraveOPotato/FckSignups/blob/main/src/constants/fallbackData.ts), keeping the application usable without connectivity.

Why does FckSignups use GitHub issues instead of a database?

The serverless GitHub issues architecture eliminates authentication flows, database hosting costs, and administrative interfaces. According to the source code, all three worker handlers (handleSubmitTool, handleReportTool, handleSuggestTool) POST to GitHub's REST API, creating reviewable, auditable records with built-in notification and assignment workflows.

Can the FckSignups architecture scale to thousands of tools?

Yes, with adjustments. The current client-side filtering architecture loads the entire tools JSON into memory. For larger datasets, the useTools hook would need server-side search endpoints or virtualized rendering. The Cloudflare Worker layer already scales automatically, though GitHub API rate limits (5,000 requests/hour for authenticated users) would govern submission throughput.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →