HOSTING FOR AI-BUILT APPS
Deploy a React frontend and Express API together on Yeeted
The project-in-project sample: two services deployed together with
deploy_group, exercising the platform's group machinery end to end.
notes-group
├── api Express + managed postgres (self-migrating) + redis cache
└── web Vite + React SPA, served by nginx, talking to the api
Why this shape matters
Deployed with deploy_group(group_id: "notes", services: [api, web]), the
platform names the services notes-api and notes-web, and injects
.yeeted-group.json into each build. For the static web service that means
its nginx proxies /api/ to notes-api over the owner mesh - so the
browser calls /api/notes as a relative URL and it works, with no baked-in
API hostname, no CORS, and no rebuild when the api redeploys. The web code
therefore contains exactly zero configuration about where the api lives.
Deploy order is dependency order: api first, then web.
What each service demonstrates
- api:
DATABASE_URLpostgres with startup migrations tracked inschema_migrations; a redis cache (REDIS_URL) on the note-list read path, invalidated on writes; in-memory fallback for zero-service dev and unit tests. - web: a Vite SPA the build service detects and serves via nginx with the
SPA fallback; all api access through relative
/api/...paths.
Tests
cd api && npm test- unit, node:test, no servicescd web && npm test- unit tests on the pure client logicNOTES_API_URL=https://notes-api... node --test test/integration.test.js./api/smoke.sh https://notes-web...- smoke through the WEB service, proving the mesh proxy path, not just the api
Run locally
Use Node.js 20 or newer. From node/notes-group/api:
npm ci
npm test
npm start
In another terminal, from node/notes-group/web:
npm ci
npm test
npm run dev
Open the URL printed by Vite. Its development proxy forwards /api to
http://127.0.0.1:3000. Without connection strings, the API uses memory and
its cache is disabled. Set DATABASE_URL for PostgreSQL and REDIS_URL for
Redis when deliberately testing those paths.
Deploy the two services
Follow the deployment walkthrough. Ask your agent:
Deploy notes-group as a Yeeted development group with api and web members. Use api/ as the API source root and web/ as the frontend source root. Attach PostgreSQL to the API. Preserve group topology so the frontend proxies /api to its sibling API. Deploy the API before the web service, then verify note creation, tag filtering, and deletion through the web service URL.
Do not upload the parent folder as one Node application. The API listens on
port 3000; the frontend becomes static files served by nginx. Browser requests
use relative paths such as /api/notes. Test that path through the web URL,
not just the API URL, to exercise the group routing.
From the notes-group directory, with PREVIEW_URL set to the web URL:
sh api/smoke.sh "$PREVIEW_URL"
The script lists notes, creates one tagged smoke, finds a matching tag, and
deletes the created note. For a stronger manual check, confirm the returned
note ID appears in the filtered response. From api/, use
NOTES_API_URL="$API_PREVIEW_URL" node --test test/integration.test.js
to check the API directly as well.
What to change before real use
This is a shared notes demo without authentication or per-user ownership. Do not put private notes into it. Cache behavior needs a real Redis instance; the general platform examples suite does not test that path. Startup SQL migrations are not coordinated across replicas, so arrange one migration runner before scaling the API.