About bounded-frontend
bounded-frontend is a skill for building Bounded app clients, aimed at developers working on web or mobile interfaces. It covers the SDK, end-user authentication, and hosted frontends, with client writes governed by policy.
Key features
- 01Guide SDK reads, writes, and subscriptions
- 02Build web and mobile frontends
- 03Configure end-user authentication
- 04Explain guest accounts and wallet login
- 05Cover hosted frontends and app URLs
Use cases
- 01Build interfaces with live data updates
- 02Configure email or OAuth sign-in for app users
- 03Implement guest-account or wallet-login flows
- 04Host a frontend and locate its app URL
MCP support
This is an Agent skill for Bounded frontend development; the input does not specify a concrete relationship to MCP.
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ bounded-sh/ skill --skill bounded-frontendAfter installing, type/bounded-frontendin Claude Code to confirm it loaded.
Bundled files
References and scripts installed along with SKILL.md.
docs/anonymous-accounts.mdapp-auth.mdauth.mdautomatic-login-completion.mdbuilding-a-webapp.mdbuilding-for-react-native.mdconnected-accounts.mdfrontend-hosting.mdsdk-reference.mdserver-apps.mdDetails
From the project READMEBounded frontend
The client side of a Bounded app: the SDK your web or mobile app calls, how end users authenticate, and how the hosted frontend is served. Policy still governs every write from the client, so pair this with the bounded-backend skill when a client action needs a rule or invariant, and bounded-deploy for hosting and domains. To route across the family, see the root bounded skill.
Reference Router
Read only the row matching the current task or term.
| Task or term | Read |
|---|---|
SDK reads, writes, subscriptions, paging, queryAggregate, count, filters, sort, cursor, setMany, set(path, null) | SDK reference |
| Build a web frontend | web app guide |
Local dev server (npm run dev, Vite, localhost), login popup fails, redirect_uri origin is not a registered origin, CORS during local development | develop on localhost |
Refresh timer, setInterval, polling, "keep it fresh", countdown, stale UI | SDK reference |
| Build for React Native / mobile | React Native guide |
App-user email OTP, OAuth, openBoundedWidget, unified login widget, default Turnkey auth | app auth |
Bring-your-own wallet login; walletLogin, authMethod:'phantom', supportsWalletSignIn, unsupported wallet / Wallet Standard | wallet login |
Wallet login lost on refresh, getCurrentUser() null after reload, bounded_last_auth_method, session restore method | wallet login - "Wallet sessions survive reloads" |
| Guests, anonymous users, invite links, account upgrade | anonymous accounts |
Link a user's X account, connect('x'), completeConnection, getConnections, verified X handle, __connections__ | connected accounts |
| Hosted frontend and app URLs | frontend hosting |
Hide or limit the hosted widget, /__bounded/widget.js, openApps.widget.visibility | hide the widget |
| A Next.js app that runs its server (vinext), its secrets and limits | server apps |
CLI developer login or bounded login | developer accounts |
Embedded wallet, auth.wallets, @user.address after email/social login | embedded wallets |
onramp(), buy SOL/USDC by card, Coinbase Onramp, wallet top-up | onramp |
Rules Of Thumb
- Every client write is governed by policy; a
403on a write is a rule denial, not a client bug. See the bounded-backend skill for the rule. - Denied reads return empty
200responses, never403. - Live by default; never poll. Every collection is push-based, so a
setIntervalthat re-reads a path is a bug, not a tuning choice - useuseQuery(React) orsubscribe. Countdowns tick on local clock state, not on a re-read. For the few surfaces that are not live (runQuery,functions.invoke, third-party), poll deliberately: pause on a hidden tab, scope the timer to the state that needs it, back off, and bound it. See sdk-reference.md. - Batch reads for lists of computed values with
runQueryMany; never maprunQueryover a list. See sdk-reference.md. - Put provider API keys in Bounded secrets (backend), never in frontend code.
- If
npm auditreportsuuidadvisory GHSA-w5hq-g745-h8pq through@solana/web3.js -> jayson, use the scoped override recipe. It addresses that advisory; runnpm audit --omit=devon the installed lockfile and investigate any remaining findings separately. - Keep the auth defaults for most apps. Do not add
authModeorauth.walletsto "enable wallets": default Turnkey email/social login already carries@user.address. Deploy"auth": { "wallets": true }only for an EXTERNAL-keypair session (bring-your-own wallet login, a server-SDK keypair client, the CLI keypair data lane). Full rule and the opt-outs: embedded-wallets.md. @user.id(the account id) is identity/ownership;@user.addressis the wallet. Key ownership, membership, and auth guards on@user.id(always present). Reach for@user.addressonly for wallet/onchain semantics - never as the identity key.- Wallet login on a phone needs the Solana Mobile adapter. A phone browser never injects wallet apps; keep
@solana-mobile/wallet-standard-mobileinstalled (legacy-peer-deps=truein.npmrc) and never pre-checkwindow.solanabefore opening the widget. See Solana Mobile.