Vibe-coding shareable, infinitely scalable personal apps — Simon Mayes
Article 6 June 2026 vibe-codingpkceoauthstatic-sitesai<br>Vibe-coding shareable, infinitely scalable personal apps
PKCE for the backends and APIs you already trust: add OpenRouter to make them smart — all for free, or next to nothing.
I’ve built two personal apps with no backend at all — marshal.msyea.com (GitLab roadmaps, my way) and affinity.msyea.com (understanding my music taste with Spotify and AI). No server, no database, no running costs: each user brings their own storage and their own AI spend, so my costs never grow — however many people use them. PKCE is pronounced pixie, so that’s what I call them: Pixie apps . Here’s the pattern.
flowchart LR<br>you([You])<br>subgraph host["Static host: GitLab / GitHub Pages"]<br>app["Pixie app (React + Vite SPA)"]<br>end<br>provider["Provider API + your storage"]<br>ai["OpenRouter (AI models)"]<br>you --> app<br>app -->|OAuth 2.0 PKCE| provider<br>app -->|OAuth 2.0 PKCE| ai<br>No server in the middle — the static page in your browser talks straight to each provider, authenticated as you.
Most apps have a missing feature or a nit that’s hugely frustrating, or there’s a workflow you can’t quite achieve with what you already use. Building personal local-first, self-hosted, or unhosted apps is a time-tested answer — and the architecture below makes it safe and quick.
Personal apps aren’t production apps
I write about software quality and take it<br>seriously — so to be clear, this is deliberately not that. Matching your engineering<br>rigour to the stakes is part of the discipline, and a personal app’s stakes are low:<br>with a careful architecture you can smash these out and happily skip the production<br>apparatus — tests, CI gates, observability, scale. The one thing you don’t get to skip<br>is security. These apps hold live tokens and a money-spending key, so that bar stays high.
How to get the data? #
Most APIs require a token. Most tokens are secrets. Managing and distributing them is difficult and requires proper infrastructure. Luckily there is another way to establish trust. Introducing the OAuth 2.0 Authorization Code flow with PKCE (Proof Key for Code Exchange), as a public client . PKCE (without a secret — yes, I’m looking at you, GitHub) is the pixie dust that lets web apps fetch API tokens in the browser and hit up APIs directly. Static API tokens and other OAuth flows that require a client secret (a confidential client) are immediately dismissed. The Device Authorization Grant (device code) is considered, but the public PKCE flow is better UX (no copy/paste).
What type of app? #
The public PKCE flow really points to a web app. I could consider a localhost or Electron-style app, but I want to be able to share the app easily and access it from multiple devices.
My other constraints: I want zero-maintenance, minimal security concerns, and for it to be basically free — and I also want AI. This points towards a static site hosted somewhere, and the key AI unlock — OpenRouter supports the public-client PKCE flow.
Where to host? #
The obvious vibe coder’s destination of choice would be GitHub, but i) I’m a GitLab guy, and ii) GitHub does not support the public-client PKCE flow (community discussion). If you’re not intending to use GitHub as a backend (see below), GitHub Pages is still a great place to host.
How to build? #
I would advocate using React+Vite because there is so much training data there and Claude (or your AI of choice) will just nail the scaffolding. If you’re an expert in another static site/frontend framework, or feeling fruity, use whatever you like.
Security #
You’re holding sensitive API keys in the browser, so XSS is the risk that matters — if hostile JavaScript runs in your page, it can read anything the page can, tokens included. Be careful rendering third-party, unverified user-generated content (UGC), consider the blast radius of what you’re exposing, lock down a CSP, and escape/sanitise any HTML you consume from an API.
XSS
Cross-site scripting — an attacker getting their JavaScript to execute in your page, where it can read tokens from localStorage and call your APIs as you. It’s the main threat for a browser-only app.
CSP
Content Security Policy — a browser policy (set via a header or meta tag) that restricts what your page can load and, crucially, where it can send data. Locking connect-src to just your providers is the control that contains a leaked token.
Secrets
Use OAuth with public-client PKCE and short-lived tokens. Do not hardcode sensitive tokens or secrets into your frontend app. Consider carefully what OAuth tokens you persist to localStorage.
Access Control
Your app consumers will authenticate with their own credentials. The API will resolve access controls automatically. Use minimal scopes where possible. Consider only fetching elevated scopes just-in-time before privileged actions.
Storage #
The obvious place to store data for a backendless static site is to use...