Deploying React to S3 manually gets old fast. If you are still dragging and dropping folders into the AWS Console, it's time to stop.
Today, I built a GitHub Actions pipeline that builds my React app, syncs it to S3, and clears the CloudFront cache automatically. Best part? Zero static AWS credentials.
The Workflow
Assuming you already have an OIDC Identity Provider set up in AWS IAM (which you should, to avoid storing Access Keys in GitHub Secrets), here is the workflow I wrote today:
YAML
name: Deploy Frontend
on:
push:
branches: [ main ]
paths: [ 'src/**', 'App.tsx', 'package.json' ]
permissions:
id-token: write
contents: read
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
env:
VITE_AWS_REGION: "eu-north-1"
VITE_USER_POOL_ID: "your-pool-id"
- name: Configure AWS Credentials via OIDC
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::1234567890:role/GitHubDeployRole
aws-region: eu-north-1
- name: Sync to S3
run: aws s3 sync dist/ s3://my-react-bucket --delete
- name: Invalidate CloudFront
run: aws cloudfront create-invalidation --distribution-id E1ABCD2345 --paths "/*"
Why the --delete flag?
Using aws s3 sync with --delete is crucial. It removes old JavaScript chunks from S3 that were generated in previous builds, preventing your bucket from growing infinitely with dead code.
My deployments now take 45 seconds and require zero clicks in the AWS console. Automate everything!

Top comments (0)