Private, paid community for Spanish-speaking builders, entrepreneurs, and tech professionals working with AI and AI agents. Tagline: "GPU compartida. Modelos open-source. Comunidad de builders."
NaN is a shared GPU infrastructure project for a paid community. The website covers:
- Landing — Presentation, models, pricing, and links to account creation (open signup)
- Documentation — Public API docs for connecting tools (Cursor, Cline, OpenCode, etc.)
All community activity (chat, forums, events, model voting) lives in Discord.
Account creation is open: anyone can create a free account on cloud.nan.builders (the site only links there: hero, nav, pricing, footer), and every product (community, inference, premium, workspaces, spaces) unlocks with a purchase on the NaN Platform, which also handles payment, onboarding and API keys. Spec: platform/cloud-api/docs/OPEN-SIGNUP.md.
| Layer | Technology | Why |
|---|---|---|
| Framework | Astro v6.0.8 (SSR mode, output: 'server') |
Static by default, SSR where needed |
| Interactive bits | Vanilla TS scripts (home effects, nav); Preact islands only where needed (events) | Zero framework JS on the marketing pages |
| Styling | Tailwind CSS v4.2.2 (Vite plugin) | Dark theme, technical typography |
| Code highlighting | rehype-pretty-code + shiki | Syntax highlighting in docs |
| Deployment | Cloudflare Workers (static assets + SSR) | Assets from CDN, SSR/API from Workers edge |
| Backend | NaN Platform cloud-api (Go + PostgreSQL) | Accounts, member lifecycle, billing, sign-in emails (English magic link) |
| Language | TypeScript (strict mode) | Type safety across the stack |
Node requirement: >=22.12.0
Everything runs as a single Cloudflare Worker (deployed via wrangler deploy, configured in wrangler.jsonc):
nan.builders (Cloudflare Worker)
│
├── CDN (Global Edge — static assets)
│ ├── Landing page (SSR-rendered at request time)
│ ├── Docs pages (SSR-rendered)
│ └── Static assets (CSS, JS, fonts, images, favicon)
│
└── Worker (Edge Functions)
├── /api/auth/login-request POST — magic-link login from the events pages (proxy)
├── /api/events/* events API proxy
├── /api/docs/* docs manifest + markdown for the Discord bot
└── SSR pages /, /es, /community, /events, /projects, /docs/*
- Static requests (assets, images, favicon): served directly from CDN.
- SSR requests (/, /docs/*): routed to Worker. Runs Astro SSR.
- API requests (/api/*): routed to Worker. Validates input, then forwards to cloud-api backend (PostgreSQL).
- No servers, no containers, no regions. Workers run at the nearest edge location.
| Route | Mode | Client JS |
|---|---|---|
/, /es |
SSR (not prerendered) | Vanilla scripts: hero dither, reveal (the hero CTA's ?plan= is resolved in SSR, no JS) |
/community, /es/community |
SSR (not prerendered) | None beyond the shared shell (CTA links to the platform signup) |
/docs* |
SSR (not prerendered) | Minimal (sidebar mobile menu, TOC, copy-to-clipboard) |
| Product | Price | Signup link |
|---|---|---|
nan_member · glm 5.3 premium |
200€/mo | https://cloud.nan.builders/signup?plan=premium |
nan_member (inference) |
70€/mo | https://cloud.nan.builders/signup?plan=inference |
nan_community |
14,99€/mo | https://cloud.nan.builders/signup?plan=community |
| Workspace slots | from 4,99€/mo | https://cloud.nan.builders/signup?plan=workspace |
Billed in euros from every region, taxes included, month to month. Links are built with signupUrl() in src/lib/signup.ts.
| Component | Specification |
|---|---|
| GPU | NVIDIA RTX PRO 6000 Blackwell |
| VRAM | 96 GB GDDR7 ECC |
| RAM | 256 GB DDR5 ECC |
| CPU | 48 threads · Xeon Gold 5412U |
| Inference | vLLM → LiteLLM |
| Embedding | HuggingFace TEI → LiteLLM |
| TTS | kokoro-fastapi → LiteLLM |
| STT | speaches → LiteLLM |
| State | Description |
|---|---|
free |
Account created (open signup), no product purchased yet |
subscribed |
Active member with a community, inference or premium subscription |
declined |
Manual: test/junk entries kept for audit |
banned |
Manual: membership revoked |
The legacy waitlist/invited rows are migrated to free by cloud-api. All transitions are managed by the NaN Platform, not by this website.
Static sections, SSR-rendered (src/pages/_home.astro, components in src/components/nan/home/):
| Section | Component | Client JS |
|---|---|---|
| Nav (Login + Create account) | nan/Nav.astro |
Small inline script (mobile menu) |
| Hero: Create account + Log in buttons | Hero.astro |
Canvas dither only |
| What is NaN | WhyNan.astro |
None |
| Built with NaN | BuiltWithNan.astro |
None |
| Models | Models.astro |
None |
| Privacy | Privacy.astro |
None |
| Pricing + workspaces | Pricing.astro |
None |
| Who is behind | WhoBehind.astro |
None |
| FAQ | Faq.astro |
None (<details>) |
/community (src/pages/_community.astro) has no form of its own: its CTAs link to signup?plan=community, and the platform runs the per-user Stripe Checkout.
| Route | Description |
|---|---|
/docs |
Introduction, hardware specs, rates, next steps |
/docs/getting-started |
Step-by-step connection guide |
/docs/models |
Available model specs |
/docs/examples |
Code snippets (Python, Node.js, curl) |
/docs/api |
OpenAI-compatible API reference (endpoints, auth, rate limits) |
Sidebar navigation comes from each guide's frontmatter (src/content.config.ts): group picks the section, order the position, and an optional parent (the entry id of another guide, identical in EN and ES) lists the page as an indented sub-item right under that guide, in the parent's group. The library supports any depth, but content is kept to one level (enforced in DocsShell.test.ts), and a child's order must be the slot right after its parent so the flat order (/api/docs manifest) matches the sidebar. URLs stay flat (/docs/<id>); the breadcrumb and prev/next follow the sidebar's visual order. Logic and tests: src/lib/docsNav.ts; markup: src/components/docs/DocsSidebarNav.astro + DocsNavList.astro (rendered in tests with the Astro Container API, *.render.test.ts, see vitest.render.config.ts).
There is no signup route on the site. The hero's Create account button links to https://cloud.nan.builders/signup, carrying the landing's ?plan= when it is one of community | inference | premium | workspace | space (the legacy ?premium=1 maps to plan=premium; anything else is dropped). Log in links to https://cloud.nan.builders/. Models, footer and 404 CTAs link to the bare signup; pricing cards add their plan. Links are built with signupUrl() / heroSignupHref() in src/lib/signup.ts. The platform collects the profile, sends the magic link and runs checkout.
The site is bilingual: English at the root (/) and Spanish under /es. Catalogs live in i18n/en.json and i18n/es.json (same shape, enforced by i18nParity.test.ts) and are read through src/lib/i18n.ts (useT, t, tArr, tObj, getLang, switchLocalePath). Emails sent by the platform are English only.
| Mechanism | Implementation |
|---|---|
| CSP | Strict policy in NanBase.astro (connect-src 'self', no external scripts, no frames, no objects) |
| Bot protection | No public write form on the marketing pages; signup lives on cloud.nan.builders (cloud-api per-IP/per-email limits). Events forms go through /api/events/* |
| IP detection | cf-connecting-ip only (never x-forwarded-for on Cloudflare) |
| Secrets | All in Cloudflare Pages dashboard via wrangler secret put, never in code |
| Error handling | Intentionally opaque error responses (no internal details leaked) |
website/
├── src/
│ ├── pages/
│ │ ├── _home.astro, index.astro, es/index.astro # Landing (EN root, ES under /es)
│ │ ├── _community.astro, community.astro # Community page (CTA to platform signup)
│ │ ├── privacy.astro, terms.astro, cookies.astro # Legal (+ es/ versions)
│ │ ├── api/
│ │ │ ├── auth/login-request.ts # POST — magic-link login proxy (events)
│ │ │ ├── events/[...path].ts # Events API proxy
│ │ │ └── docs/ # Docs manifest + markdown
│ │ ├── docs/, events/, projects.astro, gauntlet.astro, survey.astro
│ ├── components/
│ │ ├── nan/ # Nav, Footer, CookieBanner, home/ sections
│ │ ├── docs/ # Docs shell components
│ │ └── events/ # Events islands (Preact)
│ ├── scripts/ # Vanilla client scripts (reveal, dither, ...)
│ ├── lib/
│ │ ├── signup.ts # Links to the platform signup (plans, ?plan= carry-through)
│ │ ├── i18n.ts # Translation helpers
│ │ └── ... # docs, events, rate limits, models
│ ├── layouts/ # NanBase (CSP, head), NanPage (shell), Docs, NanLegal
│ ├── tests/ # Vitest suites (api/, lib/, landing/, layouts/, legal/, pages/)
│ └── env.d.ts # Cloudflare env type declarations
├── i18n/ # en.json, es.json
├── public/ # Static assets, _routes.json
├── astro.config.mjs, wrangler.jsonc, vitest.config.ts, tsconfig.json, package.json
└── .env.example
| Variable | Type | Purpose |
|---|---|---|
CLOUD_API_URL |
string |
Backend API base URL (e.g. https://cloud-api.nan.builders), used by the events proxy, events SSR and the events login |
RATE_LIMIT_RPM / RATE_LIMIT_PARALLEL |
string (optional) |
Per-key limits shown in the docs (defaults in src/lib/rateLimits.ts) |
RESEND_API_KEY, RESEND_FROM_EMAIL and CLOUD_API_WAITLIST_KEY are no longer used by the site (the waitlist and its confirmation email are gone; cloud-api sends the sign-in email).
All secrets are stored in Cloudflare via wrangler secret put. Never committed to the repository.
Triggered on PRs to main:
npm ci— install dependenciesnpm test— run Vitest suitenpx astro check— TypeScript type checkingnpm run build— production build
Triggered on push to main:
npm ci— install dependenciesnpm test— run testsnpm run build— production buildnpx wrangler deploy— deploy to Cloudflare
Uses CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID secrets.
npm run buildRuns astro check --quiet (type check, non-blocking) then astro build. Copies public/_routes.json to dist/client/ for Cloudflare routing rules.
npm test # Run all tests (Vitest)
npm run test:watch # Watch modeTests are in src/**/*.test.ts (Node) and src/**/*.render.test.ts (Astro Container API). Open-signup suites:
src/tests/lib/signup.test.ts— plans,?plan=parsing, signup URLssrc/tests/landing/heroCta.test.ts— hero has no form, CTA hrefs and copy, dead code gone, no#signuplinkssrc/tests/landing/heroCta.server.test.ts— SSR hero hrefs with?plan=/?premium=1,POST /api/signupis a 404src/tests/landing/openSignup.test.ts— CTA targets, no waitlist copy, legal pagessrc/tests/layouts/noWebSearch.test.ts— web search stays removed
| Resource | Free tier | Expected usage |
|---|---|---|
| Cloudflare Pages | Unlimited deploys, 500 builds/month | More than enough |
| Workers | 100K requests/day | Negligible usage |
| Domain | — | Already owned (nan.builders) |
Estimated infrastructure cost: $0/month