βοΈ Configuration
Change starter.config.json. Run setup. Do not hand-edit the generated copies.
There are three configuration layers.
| Layer | Where | What belongs there |
|---|---|---|
| Product | starter.config.json | App name, branding, support email, feature flags |
| Marketing | apps/web/src/config/marketing.ts | Public website copy, section visibility, legal identity |
| Secrets | apps/web/.env.local, apps/api/.env | API keys, database URL, Stripe, Resend, Sentry |
starter.config.json is committed. Never put secrets in it.
There is no root .env. Each app has its own file.
Donβt edit the generated config files. Change the root file and let GoShipped sync them.
Start with the product file
Before you redesign anything, replace the shipped identity in starter.config.json:
app.name/app.description/app.defaultLocalebranding.logo,branding.logoDark,branding.favicon,branding.colorssupport.emailfeatures.*
The shipped values are working examples. They are not your product.
Keep the app name at 24 characters or fewer (32 is the hard maximum). Put logo files in apps/web/public/ and point the config at them, for example "/my-logo.svg".
While pnpm dev is running, edits to starter.config.json sync automatically. You usually do not restart the server.
pnpm config:check # validate only
pnpm config:sync # validate + copy into both appspnpm dev and pnpm build already run sync. Do not edit the generated copies:
apps/web/src/config/generated/starter.config.jsonapps/web/src/config/generated/starter-theme.cssapps/api/app/generated/starter_config.json
Those exist so Vercel can deploy apps/web and apps/api as separate projects.
Marketing copy is separate
Product name and colors stay in starter.config.json so the app and the website stay aligned.
Everything the public site says lives in apps/web/src/config/marketing.ts:
- hero, features, FAQ, footer
sections.*β set a section tofalseto hide it- company legal name, address, jurisdiction
Legal pages are starter templates, not legal advice. Review them before production.
Secrets stay in env files
| App | Example | Local file |
|---|---|---|
| Frontend | apps/web/.env.local.example | apps/web/.env.local |
| Backend | apps/api/.env.example | apps/api/.env |
pnpm run setup copies the examples when the local files are missing. It never overwrites existing files.
Typical env concerns: Supabase, OpenAI, Anthropic, Stripe, Resend, Sentry, the database URL.
Prefer the wizard
If you copy apps/api/.env.example by hand, some fields must be valid JSON for pydantic-settings: ALLOWED_EMAILS=[], SHOPPING_FALLBACK_PROVIDERS=["ebay"], DATABASE_NULL_POOL=false. Setup applies those fixes for you.
Feature flags
Flags in starter.config.json turn capabilities on or off for the whole product β UI, API, and runtime. They are not βhide this buttonβ.
{
"features": {
"signup": true,
"onboarding": true,
"billing": true,
"files": true,
"memory": true,
"deepResearch": true,
"mcp": false,
"tools": {
"webResearch": true,
"urlReader": true,
"weather": true,
"stocks": true,
"shopping": true,
"domains": true
}
}
}| Value | Meaning |
|---|---|
true | The capability exists in this product |
false | It is disabled everywhere, not only hidden |
Plans still decide which enabled features each user can access. A flag set to false cannot be turned back on by a plan.
Product capability β Plan entitlement β Usage quota β RequestDirect API calls to a disabled capability return 404 with feature_disabled.
What each flag controls
| Flag | When false |
|---|---|
signup | No register UI (/register). Supabase Auth is still the real gate. |
onboarding | No first-run overlay |
billing | No checkout, portal, or billing settings. Stripe webhooks no-op. Plans still work. |
files | No uploads, no file context in chat |
memory | No memory settings, retrieval, or writes |
deepResearch | No Deep Research mode |
mcp | No MCP tools. Native tools still work. |
tools.* | Hides that built-in tool (web_research, read_url, weather, stocks, shopping, domains) |
Helpers, if you need them in code:
- Frontend:
apps/web/src/config/features.tsβisFeatureEnabled("billing") - Backend:
apps/api/app/features.pyβis_feature_enabled/require_feature
There is no remote flag service and no flags table in the database.
Only pay for what you enable
GoShipped should only require credentials for functionality you actually turn on.
Doctor follows that rule. Disabled product features are skipped and do not require their exclusive secrets.
| Capability | Enabled | Disabled |
|---|---|---|
| Billing | Stripe keys and prices required | Stripe optional. App boots without it. |
| Files | SUPABASE_SERVICE_ROLE_KEY for Storage uploads | Upload stack not required |
| Memory | OpenAI key for embeddings | No extra memory setup |
| MCP | MCP_CONFIG_PATH / servers as needed | No MCP setup (false by default) |
| Deep Research | Database for checkpoints + an AI provider | Deep Research-only setup not required |
EMAIL_ENABLED=true then Resend keys | Default is off. Auth mail stays on Supabase. | |
| Sentry | DSN set | Empty DSN = off |
Chat still needs at least one AI provider: OPENAI_API_KEY and/or ANTHROPIC_API_KEY.
Two small exceptions
Billing skip β billing off. If features.billing is true and you skipped Stripe in setup, doctor still treats Stripe keys as required. Set the flag to false until you are ready.
Files and Memory need OpenAI embeddings while those flags stay on, even if Anthropic is your chat provider.
Without Stripe, every user gets DEFAULT_PLAN_WHEN_BILLING_DISABLED (default pro). Checkout and the customer portal stay unavailable until you add keys.
Setup and doctor
Use these instead of editing env files from memory:
pnpm run setup # guided, interactive, writes missing files
pnpm run doctor # read-only report, safe in CIUse `pnpm run`
Always pnpm run setup and pnpm run doctor. Bare pnpm setup and pnpm doctor are pnpm builtins.
Setup asks for missing values. Skipped optional services are later tasks, not red errors β except Stripe while features.billing is still true.
Doctor groups include Configuration, Environment, Supabase, AI, Billing, Files, Memory, Deep Research, MCP, Email, Observability, and Tools. When something is missing, it tells you the file and where to get the value.
What to do next
You know where identity, copy, flags, and secrets live. That is enough to start building.