Why Use AWS SAM for a React App
AWS Serverless Application Model (SAM) is a purpose-built framework for serverless apps on AWS. It simplifies deployment of infrastructure-as-code for common patterns including static React frontends served via Amazon S3 and Amazon CloudFront. This evergreen guide explains how to scaffold, develop, test, and deploy a React app with AWS SAM, focusing on durable workflows that reduce operational overhead over time.
You will understand project layout, build configurations, local invocation and testing, environment management, and cost-aware deployment practices. The approach favors managed services and repeatable pipelines, making it suitable for teams that want reliable, maintainable serverless frontends.
Prerequisites and Tooling
Core Requirements
- Node.js LTS (examples use 18–20) and npm or yarn
- AWS SAM CLI installed and configured with credentials
- An AWS account with programmatic access and sufficient IAM permissions
- Optional but recommended: Docker for local invocation that matches Lambda runtime behavior
Recommended Project Structure
A common pattern is to keep the React app inside a SAM app under a src/ folder, with a dedicated template manifest (template.yaml) and shared configuration for build and deployment. This keeps infrastructure and frontend source in a single repository while preserving clear separation of concerns.
| Path | Purpose | Notes |
|---|---|---|
template.yaml | AWS SAM infrastructure definition | Defines Lambda, API, S3, CloudFront, and permissions |
src/react-app/ | Create React App or Vite React source | Standard frontend tooling |
src/build/ | Compiled build output consumed by SAM | Populated by the build stage |
events/ | Sample event payloads for local testing | Optional, useful for unit tests |
Initialize the React Application
Start with a standard React project using Create React App, Vite, or another preferred builder. For consistency, initialize inside a src/react-app directory and configure the build output to a known folder such as build. This predictable output path simplifies SAM wiring later. Example with Vite:
mkdir -p src/react-app
cd src/react-app
npm create vite@latest . -- --template react
npm install
Ensure your production build command produces static assets in a folder you can reference from SAM. CRA uses npm run build and outputs to build/; you can remap or customize as needed for your toolchain.
Define the SAM Template
The SAM template declares the resources for your frontend. A minimal, production-aware template serves the built React assets from S3 and uses CloudFront for HTTPS, caching, and custom domains. It also exposes a simple Lambda function for future serverless endpoints tied to the same frontend.
AWS::Serverless::Functionfor optional APIs under the same domainAWS::Serverless::HttpApior API Gateway for lightweight endpointsAWS::S3::Bucketconfigured for static website hostingAWS::CloudFront::Distributionwith an origin pointing to the S3 bucket
Because React is static after build, the template avoids compute for serving files and relies on the managed performance and cost characteristics of S3 plus CloudFront.
Configure Build and Packaging
SAM can run local commands to produce the React build before packaging. Use the buildMethod field and the metadata section in template.yaml to define how the frontend is built. A common approach is a Makefile or npm run build invoked from the React source directory, producing artifacts that SAM copies into the Lambda layer or S3 bucket.
Consider separating concerns:
This separation keeps your pipeline explicit and easier to debug.
Local Testing and Invocation
Local Build and Serve
Before invoking SAM locally, build the React app in the target output folder. You can then use a local static server to validate routing and assets independently, or use SAM local invoke for API functions.
cd src/react-app
npm run build
For SAM local start-api, define a quick local start to verify endpoints and CORS behavior before deploying to AWS.
SAM CLI Commands
sam build— compiles and packages the appsam local invoke— test Lambda functions locallysam local start-api— test API endpoints locallysam deploy --guided— iterative deployment with prompts
Use sam build with the correct base image and definition directory to ensure the template and build output stay aligned.
Environment, Variables, and Routing
Manage environment variables for React at build time using REACT_APP_ prefix for public variables, and inject server-side values via Lambda environment or runtime fetch from AWS Systems Manager Parameter Store. For SPA routing, configure CloudFront error responses to default to /index.html and ensure your React router is set to use browser routing with appropriate fallback behavior.
| Variable Type | Where to Set | Use Case |
|---|---|---|
| Build-time React vars | .env in React app (REACT_APP_) | API URLs, feature flags |
| Lambda runtime vars | SAM template environment section | Secrets retrieved from SSM or Secrets Manager |
| CloudFront custom headers | Distribution configuration | Security tokens, cache control |
CI/CD and Change Management
Automate the pipeline by combining SAM CLI with your CI system. A typical flow includes linting and unit tests for both frontend and serverless functions, a build stage that runs sam build or equivalent, packaging with sam package, and deployment via sam deploy or CloudFormation change sets. For zero-downtime updates, rely on CloudFront origin changes and staged deployments, and use automated invalidation only when build outputs change.
Security and Cost Considerations
Use least-privilege IAM roles for Lambda and limit S3 access to read-only for CloudFront via origin access identity. For cost, S3 and CloudFront handle the bulk of static traffic at low cost; Lambda charges apply only if you include API functions. Monitor with AWS Budgets and CloudFront metrics to understand spend patterns as traffic grows.
Summary Checklist
- Initialize React with a build command that outputs to a known directory
- Define a SAM template with S3 + CloudFront for static hosting and optional Lambda for APIs
- Use
sam buildand local testing before deploying - Manage env vars carefully: REACT_APP_ for frontend and Lambda env for runtime secrets
- Automate build and deploy in CI with explicit packaging and change-set validation
- Secure the stack with least-privilege roles and an origin access identity
- Monitor costs via CloudFront and Lambda metrics and set budget alerts
By following this evergreen approach, you get a repeatable, secure, and cost-efficient way to host React apps with AWS SAM. The stack is straightforward, maintainable, and well-suited for long-term product and internal applications alike.