How to Deploy React App on Aws S3

Introduction Deploying a React application on Amazon S3 is one of the most popular, cost-effective, and scalable methods for hosting static web applications. With its global reach, high availability, and seamless integration with CloudFront, Route 53, and AWS Certificate Manager, S3 has become the go-to platform for developers seeking a reliable hosting solution. However, despite its simplicity, m

Oct 25, 2025 - 13:26
Oct 25, 2025 - 13:26
 0

Introduction

Deploying a React application on Amazon S3 is one of the most popular, cost-effective, and scalable methods for hosting static web applications. With its global reach, high availability, and seamless integration with CloudFront, Route 53, and AWS Certificate Manager, S3 has become the go-to platform for developers seeking a reliable hosting solution. However, despite its simplicity, many developers encounter issues during deploymentmisconfigured permissions, caching problems, incorrect routing, or broken asset pathsthat lead to frustrating downtime or poor user experiences.

This guide presents the top 10 trusted, battle-tested methods to deploy your React app on AWS S3. Each method has been validated by enterprise teams, open-source contributors, and DevOps professionals who rely on these techniques in production environments. We dont just list stepswe explain the why behind each decision, the potential pitfalls to avoid, and how to ensure your deployment is secure, fast, and resilient.

Whether youre a beginner deploying your first React app or an experienced engineer optimizing a high-traffic application, this guide gives you the clarity and confidence to deploy without guesswork. Trust isnt built on hypeits built on proven processes. Lets dive in.

Why Trust Matters

When deploying a React application to AWS S3, trust isnt a luxuryits a necessity. A misconfigured bucket policy, an expired SSL certificate, or a missing index.html redirect rule can cause your entire application to become inaccessible. Users wont wait for you to fix it. Theyll leave. And in todays competitive digital landscape, even a few seconds of downtime can cost you conversions, revenue, and reputation.

Many online tutorials offer quick, simplified steps that work in development but fail under real-world conditions. They might skip critical security configurations, ignore caching headers, or assume youre using a basic create-react-app setup. But production applications demand more: CORS policies, HTTP/2 support, CDN integration, automated CI/CD pipelines, and compliance with industry standards like SOC 2 or GDPR.

Trust comes from depth. It comes from understanding how S3s object storage works, how CloudFront caches content, how browser caching interacts with your build artifacts, and how to handle SPA (Single Page Application) routing without server-side rendering. The top 10 methods in this guide have been selected because theyve been tested across hundreds of deployments, documented in official AWS whitepapers, and refined by teams managing applications serving millions of users monthly.

By following these trusted approaches, you eliminate guesswork. You reduce risk. You ensure that your React app loads quickly, securely, and consistently for every user, regardless of their location or device. This isnt about following the easiest pathits about following the right path.

Top 10 How to Deploy React App on AWS S3

1. Use AWS CLI with Proper Bucket Configuration and Static Website Hosting

The most fundamental and widely trusted method involves using the AWS Command Line Interface (CLI) to upload your React build files directly to an S3 bucket configured for static website hosting. This method gives you full control and is recommended for developers who prefer manual deployment or have simple CI/CD needs.

Begin by building your React app using npm run build. This generates a build folder containing all static assets. Next, create an S3 bucket with a unique name (e.g., myapp.example.com) and enable static website hosting in the bucket properties. Set the index document to index.html and the error document to index.html as wellthis is critical for React Router to function properly in client-side routing.

Configure the bucket policy to allow public read access to objects. Heres a sample policy:

{

"Version": "2012-10-17",

"Statement": [

{

"Sid": "PublicReadGetObject",

"Effect": "Allow",

"Principal": "*",

"Action": "s3:GetObject",

"Resource": "arn:aws:s3:::myapp.example.com/*"

}

]

}

Upload the contents of the build folder using the AWS CLI:

aws s3 sync build/ s3://myapp.example.com --delete

The --delete flag ensures that any files removed from your local build are also deleted from the bucket, preventing stale assets from causing issues. Finally, ensure your buckets website endpoint is accessible via HTTPS by setting up CloudFront and ACM (AWS Certificate Manager) for SSL.

This method is trusted because its documented by AWS, requires no third-party tools, and gives you complete visibility into every step. Its ideal for teams with basic deployment needs and those learning the AWS ecosystem.

2. Deploy with AWS Amplify Console (Fully Managed)

AWS Amplify Console is a fully managed continuous deployment and hosting service designed specifically for modern web applications, including React. Its one of the most trusted methods because it automates the entire pipelinefrom code commit to global CDN deliverywith minimal configuration.

To use Amplify Console, connect your React apps GitHub, GitLab, or Bitbucket repository. Amplify automatically detects the React framework, runs npm install and npm run build, and deploys the output to S3 and CloudFront. It also automatically provisions HTTPS via ACM, sets up redirects for SPA routing, and enables caching headers optimized for Reacts asset fingerprints.

Amplify Console includes built-in features like preview deployments for pull requests, rollbacks, custom domain mapping, and performance analyticsall without writing a single line of infrastructure-as-code. Its trusted by startups and enterprises alike because it reduces human error, accelerates release cycles, and ensures consistent environments across staging and production.

For teams prioritizing speed and reliability over granular control, Amplify Console is the most trusted end-to-end solution available on AWS.

3. Use Terraform for Infrastructure-as-Code Deployment

For teams practicing Infrastructure-as-Code (IaC), Terraform is the gold standard. Deploying a React app via Terraform ensures your S3 bucket, CloudFront distribution, bucket policy, and IAM roles are version-controlled, repeatable, and auditable.

Create a Terraform configuration that defines an S3 bucket with static website hosting enabled, a CloudFront distribution with the bucket as the origin, and an ACM certificate for HTTPS. Use the aws_s3_bucket and aws_cloudfront_distribution resources to declare your infrastructure. Include a local-exec provisioner to run npm run build and sync the build folder to S3 using the AWS CLI within the Terraform workflow.

Example snippet:

resource "aws_s3_bucket" "react_app" {

bucket = "myapp.example.com"

}

resource "aws_s3_bucket_website_configuration" "react_app" {

bucket = aws_s3_bucket.react_app.id

index_document {

suffix = "index.html"

}

error_document {

key = "index.html"

}

}

resource "aws_cloudfront_distribution" "react_app" {

origin {

domain_name = aws_s3_bucket.react_app.bucket_regional_domain_name

origin_id = "S3-${aws_s3_bucket.react_app.bucket}"

s3_origin_config {

origin_access_identity_id = aws_cloudfront_origin_access_identity.oai.id

}

}

enabled = true

is_ipv6_enabled = true

default_root_object = "index.html"

default_cache_behavior {

target_origin_id = "S3-${aws_s3_bucket.react_app.bucket}"

viewer_protocol_policy = "redirect-to-https"

forwarded_values {

query_string = false

cookies {

forward = "none"

}

}

compress = true

default_ttl = 86400

max_ttl = 31536000

min_ttl = 0

}

viewer_certificate {

cloudfront_default_certificate = true

}

}

This method is trusted by enterprise DevOps teams because it enforces consistency, enables automated testing of infrastructure, and integrates seamlessly with GitOps workflows. Changes to your deployment architecture are reviewed, tested, and deployed like application code.

4. Automate with GitHub Actions and S3 Sync

GitHub Actions is a powerful, native CI/CD platform that integrates seamlessly with React projects hosted on GitHub. This method is trusted by open-source maintainers and mid-sized teams because its free, fast, and doesnt require external tools.

Create a workflow file at .github/workflows/deploy.yml with the following steps:

  • Check out the repository
  • Set up Node.js
  • Install dependencies with npm ci
  • Build the app with npm run build
  • Use the aws-actions/amazon-s3-sync action to sync the build folder to S3

Example workflow:

name: Deploy to S3

on:

push:

branches: [ main ]

jobs:

deploy:

runs-on: ubuntu-latest

steps:

- uses: actions/checkout@v4

- uses: actions/setup-node@v4

with:

node-version: '20'

- run: npm ci

- run: npm run build

- uses: aws-actions/amazon-s3-sync@v2

with:

aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}

aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

aws-region: us-east-1

args: --recursive --delete build/ s3://myapp.example.com

Store your AWS credentials as GitHub Secrets. This method ensures every push to main triggers an automatic, reproducible deployment. Its trusted because its transparent, auditable, and integrates directly with your code review process. Pull requests can be tested in isolation before merging.

5. Use CircleCI with Custom S3 Deployment Script

CircleCI is another enterprise-grade CI/CD platform trusted for its flexibility and scalability. This method is ideal for teams already using CircleCI for backend or mobile deployments who want to unify their React deployment pipeline.

Configure a job in .circleci/config.yml that installs Node.js, runs the build, and uses the AWS CLI to sync files to S3. Include environment variables for AWS credentials and bucket name. Use the aws s3 sync command with proper headers to set cache-control for optimal performance:

aws s3 sync build/ s3://myapp.example.com --delete --cache-control "max-age=31536000, public" --exclude "*" --include "*.js" --include "*.css" --include "*.png" --include "*.jpg" --include "*.ico"

aws s3 sync build/ s3://myapp.example.com --delete --cache-control "max-age=0, no-cache, no-store, must-revalidate" --include "index.html"

This two-step sync ensures that static assets (JS, CSS, images) are cached aggressively for performance, while index.html is never cached to prevent stale client-side routing issues.

CircleCIs parallel job execution and orb ecosystem make this method scalable for large teams. Its trusted because it allows fine-grained control over caching, permissions, and deployment conditions, and integrates with Slack, Jira, and other enterprise tools.

6. Deploy via AWS CodePipeline with CodeBuild

AWS CodePipeline and CodeBuild provide a native AWS solution for end-to-end CI/CD. This method is trusted by organizations already invested in AWS services and seeking to minimize third-party dependencies.

Create a CodePipeline with three stages: Source (GitHub or CodeCommit), Build (CodeBuild), and Deploy (S3). The CodeBuild project runs a buildspec.yml file that:

  • Installs Node.js
  • Runs npm ci and npm run build
  • Uses the AWS CLI to sync the build folder to S3

Example buildspec.yml:

version: 0.2

phases:

install:

runtime-versions:

nodejs: 20

commands:

- npm ci --only=production

build:

commands:

- npm run build

post_build:

commands:

- aws s3 sync build/ s3://myapp.example.com --delete

artifacts:

files:

- '**/*'

CodePipeline automatically triggers on git commits and provides visual pipelines, rollback capabilities, and integration with AWS CloudWatch for monitoring. Its trusted by regulated industries because it enforces approval gates, audit trails, and compliance controls natively.

7. Use S3 Transfer Acceleration for Global Deployments

For applications targeting users across continents, standard S3 uploads can be slow due to network latency. S3 Transfer Acceleration uses Amazon CloudFronts globally distributed edge locations to speed up uploads to your S3 bucket.

Enable Transfer Acceleration on your S3 bucket via the AWS Console or CLI. Then, modify your deployment script to use the accelerated endpoint:

aws s3 sync build/ s3://myapp.example.com.s3-accelerate.amazonaws.com --delete

This method doesnt change your deployment logicit just makes it faster. Its trusted by global SaaS platforms and media companies where deployment speed directly impacts developer productivity and time-to-market. Combined with CloudFront, it ensures both fast uploads and fast delivery.

Important: Transfer Acceleration incurs additional costs, so its recommended only for teams with high-frequency deployments or large build sizes (>100MB).

8. Implement Zero-Downtime Deployments with S3 Versioning and CloudFront Invalidation

Zero-downtime deployments are essential for mission-critical applications. This trusted method uses S3 versioning and CloudFront invalidation to ensure users always see the latest version without interruption.

Enable versioning on your S3 bucket. Instead of deleting old files, upload new builds alongside them. Use a deployment script that:

  1. Uploads the new build to S3 with a unique prefix (e.g., build-v1.2.3/)
  2. Updates a configuration file (e.g., current-build.txt) with the new version
  3. Uses CloudFront invalidation to clear the cache for /index.html and /*

Then, configure CloudFront to serve content from a specific versioned folder based on the value in current-build.txt using Lambda@Edge or a custom origin request function.

This approach allows you to roll back instantly by changing the version pointer. Its trusted by financial and healthcare platforms where even a 10-second outage is unacceptable. It also prevents cache poisoning and ensures users never see a mixed version of assets.

9. Integrate with AWS CloudFront for Performance and Security

While S3 alone can host your React app, deploying behind CloudFront is non-negotiable for production use. CloudFront is AWSs global CDN and provides caching, DDoS protection, HTTP/2, TLS 1.3, and origin shielding.

Create a CloudFront distribution with your S3 bucket as the origin. Set the origin access identity (OAI) to restrict direct S3 accessthis prevents users from bypassing CloudFront and accessing raw S3 URLs. Configure cache behaviors to set TTLs for different file types: 1 year for hashed assets (static/js/main.*.js), 0 for index.html.

Enable HTTP to HTTPS redirection, and use AWS Certificate Manager to attach a custom domain certificate. Add security headers via Lambda@Edge:

  • Strict-Transport-Security
  • X-Content-Type-Options: nosniff
  • X-Frame-Options: DENY
  • Content-Security-Policy

This method is trusted because its the industry standard for secure, high-performance web hosting. CloudFront reduces latency by up to 60% for international users and protects against common web attacks. Never deploy a React app to S3 without CloudFront in production.

10. Use Serverless Framework with S3 Plugin for Advanced Use Cases

For teams managing complex applications with multiple environments, micro-frontends, or hybrid serverless architectures, the Serverless Framework with the serverless-s3-sync plugin offers a powerful, code-driven deployment solution.

Install the plugin:

npm install serverless-s3-sync --save-dev

Configure serverless.yml:

service: my-react-app

provider:

name: aws

runtime: nodejs20.x

plugins:

- serverless-s3-sync

custom:

s3Sync:

- bucketName: myapp.example.com

localDir: build

deleteRemoved: true

acl: public-read

cacheControl: max-age=31536000, public

include:

- "*.js"

- "*.css"

- "*.png"

- "*.jpg"

exclude:

- "index.html"

- bucketName: myapp.example.com

localDir: build

deleteRemoved: true

acl: public-read

cacheControl: max-age=0, no-cache, no-store, must-revalidate

include:

- "index.html"

functions:

Optional: Add Lambda@Edge for advanced routing

Deploy with serverless deploy. This method is trusted by advanced teams because it treats deployment as code, supports multi-environment configurations (dev/staging/prod), and integrates with other Serverless plugins for API gateways, DynamoDB, or Cognito authentication. Its ideal for React apps that evolve into full-stack applications.

Comparison Table

Method Best For Learning Curve Automation Security Scalability Cost
AWS CLI + Static Hosting Beginners, simple apps Low Manual Medium Low Low
AWS Amplify Console Startups, rapid iteration Very Low Full High High Low-Medium
Terraform Enterprise, IaC teams High Full Very High Very High Low
GitHub Actions GitHub users, open-source Medium Full High High Free
CircleCI Enterprise CI/CD pipelines Medium Full High High Free-Medium
AWS CodePipeline AWS-native teams Medium Full Very High High Low
S3 Transfer Acceleration Global deployments Low Manual/Partial Medium High Medium
Zero-Downtime + Versioning High-availability apps High Full Very High Very High Low
CloudFront Integration All production apps Medium Partial Very High Very High Low-Medium
Serverless Framework Advanced, multi-service apps High Full Very High Very High Low

FAQs

Why does my React app show a blank page when deployed to S3?

This is almost always due to incorrect routing configuration. React apps use client-side routing (e.g., React Router), which requires S3 to serve index.html for all routes. Ensure static website hosting is enabled and both the index document and error document are set to index.html. If youre using CloudFront, verify the origin path and default root object are correctly configured.

How do I fix 403 Forbidden errors on S3?

403 errors usually mean the bucket policy doesnt allow public read access, or youre accessing the bucket via the REST endpoint instead of the website endpoint. Use the website endpoint URL (e.g., http://myapp.example.com.s3-website-us-east-1.amazonaws.com) for testing. Also, ensure your bucket policy includes the s3:GetObject permission for all objects.

Should I use CloudFront with S3 for React apps?

Yes. Always. S3 alone lacks caching, SSL termination, DDoS protection, and global edge delivery. CloudFront reduces latency, improves security, and enables HTTP/2 and compression. Its essential for production performance and reliability.

How do I handle caching for Reacts hashed filenames?

React builds generate filenames with hashes (e.g., main.abc123.js). These files can be cached indefinitely. Set a long Cache-Control header (e.g., 1 year) for these assets. For index.html, set Cache-Control: max-age=0, no-cache so browsers always check for updates.

Can I deploy multiple React apps to the same S3 bucket?

Yes, but its not recommended. Use separate buckets for each app to avoid conflicts, simplify permissions, and enable independent deployments. If you must use one bucket, organize apps under prefixes (e.g., /app1/, /app2/) and configure CloudFront behaviors to route paths accordingly.

Whats the difference between S3 website endpoint and REST endpoint?

The website endpoint (e.g., ...s3-website-region.amazonaws.com) supports static website features like index documents and custom error pages. The REST endpoint (e.g., ...s3.amazonaws.com) is for programmatic access and does not support SPA routing. Always use the website endpoint for React apps.

How do I add SSL to my React app on S3?

Use AWS Certificate Manager (ACM) to request a free SSL certificate for your custom domain. Then, create a CloudFront distribution and associate the certificate with it. CloudFront will serve your app over HTTPS. Never rely on S3s HTTP-only endpoint in production.

Why is my deployment slow?

Large build sizes, slow internet connections, or uploading to a distant S3 region can cause delays. Use S3 Transfer Acceleration for faster uploads, or build locally and upload via a faster connection. Consider splitting assets or using code splitting in React to reduce bundle sizes.

How do I roll back a failed deployment?

Use versioning in S3 and store a pointer to the current version (e.g., current-build.txt). To roll back, update the pointer to a previous version and invalidate CloudFront cache. Alternatively, use CI/CD tools like Amplify or CodePipeline that offer built-in rollback features.

Is deploying to S3 secure?

Yes, if configured properly. Use IAM roles, restrict access with bucket policies, enable versioning, enforce HTTPS via CloudFront, and avoid public bucket policies unless necessary. Never expose AWS credentials in your code. Use secrets management and temporary credentials in CI/CD pipelines.

Conclusion

Deploying a React application to AWS S3 is not a one-size-fits-all task. The methods outlined in this guideranging from manual CLI uploads to fully automated, infrastructure-as-code pipelineseach serve different needs, team sizes, and operational requirements. Trust isnt derived from popularity; its earned through reliability, security, and scalability.

The top 10 methods presented here have been selected not for their novelty, but for their proven track record in real-world production environments. Whether youre a solo developer deploying a personal portfolio or an engineering team managing a high-traffic SaaS platform, theres a trusted approach here that aligns with your goals.

Remember: the goal isnt just to get your app onlineits to ensure it loads instantly, remains secure, and scales effortlessly as your user base grows. By leveraging CloudFront, implementing proper caching, automating deployments, and securing your infrastructure, you transform a simple static host into a robust, enterprise-grade platform.

Choose the method that matches your teams maturity, your applications complexity, and your long-term vision. Then, document it, test it, and monitor it. The most trusted deployments arent the ones that happen oncetheyre the ones that happen perfectly, every time.