A minimal demo app showcasing canary deployment architecture with edge-based routing.
- Single React App (
src/app/) - Unified codebase with environment-based builds - Stable Build (
src/stable/) - Production-ready version (build output) - Next Build (
src/next/) - Canary version for testing (build output) - CloudFront Function - Edge routing based on org membership
- AWS Cognito - User authentication and org management
This implementation uses a single codebase approach where the same React application is built twice with different environment variables (VITE_BUILD_TYPE=stable and VITE_BUILD_TYPE=next). This is more maintainable than separate codebases and mirrors real-world deployment patterns where the same code is deployed at different Git SHAs.
-
Install dependencies:
npm run install-all
-
Build both versions:
npm run build-all
-
Deploy to AWS:
npm run deploy
- User lands on app → no cookie → serves stable build
- User logs in → cookie with orgId is set
- Edge routing checks if org is in rollout list
- Routes to next build if org is in rollout, otherwise stable
- Update rollout config to control which orgs see next build
├── src/
│ ├── app/ # Single React app (source code)
│ ├── stable/ # Stable build output (gitignored)
│ ├── next/ # Next build output (gitignored)
├── edge-function/ # CloudFront edge function
├── template.yaml # AWS SAM template
└── scripts/ # Build and deploy scripts
The build process works as follows:
- Source Code: Single React app in
src/app/with environment-based configuration - Build Variants: Same codebase built twice with different
VITE_BUILD_TYPEvalues:VITE_BUILD_TYPE=stable→ produces stable build with green banner and v1.0.0VITE_BUILD_TYPE=next→ produces next build with orange banner and v2.0.0-canary
- Build Outputs: Generated builds are copied to
src/stable/andsrc/next/directories - Deployment: Both build outputs are uploaded to separate S3 buckets
- Edge Routing: CloudFront edge function routes users based on their
orgIdcookie