Capability Guardrails
Before building, check the user's request against these lists. If a feature falls under "Not Possible," tell the user clearly in plain language and suggest the alternative.
What run402 CAN do
- Postgres database — tables, columns, constraints, indexes, SQL queries
- REST API — full CRUD (create, read, update, delete) with filtering, pagination, ordering via PostgREST
- Row-level security — expose manifest policies:
user_owns_rows,public_read_authenticated_write,public_read_write_UNRESTRICTED,custom. Tables are dark by default. - User authentication — email/password signup, login, token refresh, logout; Google OAuth built in
- File storage — content-addressed CDN with SRI integrity. Upload via presigned PUT (
POST /storage/v1/uploads); reads viaGET /storage/v1/blob/:key. - Static site hosting — deploy HTML/CSS/JS via unified
(await r.project(id)).apply()(SDK 2.0+), get a shareable URL. SPA support; clean URLs viasite.public_paths. - Same-origin web routes — map
/adminand/admin/*patterns to Node 22 Fetch functions on the same domain as the static site. - Multiple tiers — Prototype (FREE on testnet, 7 days), Hobby ($5, 30 days), Team ($20, 30 days)
- Testnet (free) — Base Sepolia with faucet for test USDC
- run402 serverless functions (Node 22) — server-side logic for things that can't run in the browser (e.g., password hashing). Deployed via
functions.replacein the unified deploy spec. - AI image generation — generate images from text prompts via
POST /generate-image/v1($0.03/image)
What run402 CANNOT do
These features are not available on run402. If the user asks for any of these, explain the limitation in plain language and suggest the alternative.
| Not Possible | Tell the user | Alternative |
|---|---|---|
| Fully custom domain names (myapp.com) | "You can't use your own domain name (like myapp.com) right now, but you can get a memorable subdomain like myapp.run402.com." | Claim a subdomain inline as part of the deploy spec (subdomains.set: ["myapp"]) in Step 15. Your app gets a URL like https://myapp.run402.com. |
| Server-side compute beyond run402 functions | "Most of your app runs in the browser, but for things that need to happen on a server — like password hashing — we can use run402's built-in serverless functions. You can't run your own custom server, though." | Use run402 functions (Node 22 Fetch handlers) for server-side logic that can't run client-side (e.g., bcrypt hashing, atomic operations). Deploy via functions.replace in (await r.project(id)).apply(). All other logic runs client-side in JavaScript. |
| Real-time WebSocket connections | "Live instant updates aren't available. But your app can check for new data every few seconds automatically." | Use polling (timed fetch every 3-10 seconds) for "near real-time" updates. |
| Email / SMS / push notifications | "Your app can't send emails, texts, or notifications. But it can show alerts inside the app itself." | In-app notifications, badge counters, or "new items" indicators that appear on page load/refresh. |
| Payment processing (beyond x402) | "Your app can't take payments from your users (no credit cards, no Stripe checkout)." | Track IOUs or balances in the database. Use external payment links if needed. |
| OAuth providers other than Google | "Sign-in is email/password or Google. No 'Sign in with Facebook/GitHub/Apple' button right now." | Email/password and Google OAuth are both built in (zero-config). |
| Custom database extensions | "You can use standard database features but can't add special add-ons." | Use standard PostgreSQL features (JSON columns, generated columns, etc.). |
| Files over the tier storage cap (250 MB on Prototype, 1 GB Hobby, 10 GB Team) | "Your app's total storage is capped per tier. Prototype gets 250 MB, which is plenty for most apps but no large video files." | Optimize images. Use the content-addressed CDN ((await r.project(id)).assets.put) for assets — deploys are no longer body-capped (bytes ride through CAS). |
| More than 100 requests/second | "Your app can handle about 100 people using it at the same time. For bigger events, some requests might be delayed." | Design for reasonable concurrency. Use caching strategies in the client. |
How to use this page
During the spec phase (steps 1-4), check the user's feature requests against the "Not Possible" list above. If a match is found:
- Tell the user clearly using the suggested language in the "Tell the user" column.
- Offer the alternative.
- Ask if they'd like to proceed with the alternative or skip that feature.
- Never attempt to build something that will fail — catch it here.
During the implement phase (steps 9-14), if you realize a planned feature hits a guardrail, stop and revisit with the user before continuing.