AWS + React SaaS Template
End-to-end SaaS Template using AWS Amplify, Apollo Client, Chakra, and NextJS.
Tech Stack
? DynamoDB ? AppSync (GraphQL) ? Cognito ? React / NextJS ? Amplify ? Apollo Client ? Chakra ▪️ Pulumi ▪️ GitHub Actions
Prerequisites
Create an account on AWS (https://aws.amazon.com/).
You will need to setup the AWS CLI on your local system, if you haven’t already.
Create an account on Pulumi (https://pulumi.com/).
You will need to setup the Pulumi CLI and configure it with AWS.
Install Amplify CLI.
We need Amplify to set up the Front End, so you need to setup the Amplify CLI on your local system.
ℹ️ Additional info
This repository is a monorepo, but you can split out the front-end and back-end folders into separate repositories.
Setup
Setup the stack in the cloud
Go to the back-end folder:
cd back-end
Install the dependencies:
npm install
Use Pulumi to setup the stack in the cloud:
pulumi up
This command will set up a stack consisting of 18 resources in AWS. They boil down to:
- A DynamoDB table for users
- A Cognito user pool
- An Identity Pool
- AppSync GraphQL API
- A PostConfirmation Lambda which is triggered when a user signs up
- A Resolver Lambda which is used to fetch a user through GraphQL
When the pulumi up
command has finished running, you will get an output that looks similar to this.
Note down this output:
Outputs:
appSyncID : "<APPSYNC-ID>"
dynamoID : "<TABLE-NAME>"
graphQLEndpoint : {
GRAPHQL : "https://<GRAPHQL-ENDPOINT>/graphql"
REALTIME: "wss://<REALTIME-ENDPOINT>/graphql"
}
identityPoolID : "<IDENTITY-POOL-ID>"
userpoolClientID: "<USERPOOL-CLIENT-ID>"
userpoolID : "<USERPOOL-ID>"
ℹ️ Additional info
If Pulumi complains about missing region, use the command:
pulumi config set aws:region eu-west-1
If you want to use another region than eu-west-1
, go to the file back-end/resources/variables/
and change the region here as well.
export const variables = {
region: 'eu-west-1' as const, // <-- change this to your region
dynamoDBTables: {} as Record<string, Output<string>>,
};
Setup the front-end
Go to the front-end folder:
cd front-end
Install the dependencies:
npm install
Use Amplify to link the front-end to the back-end:
amplify init
- ? Enter a name for the project: my-app-name
- ? Choose the environment you would like to use: dev
- ? Choose your default editor: Visual Studio Code
- ? Choose the type of app that you’re building: javascript
- ? What javascript framework are you using: react
- ? Source Directory Path: src
- ? Distribution Directory Path: build
- ? Build Command: npm run build
- ? Start Command: npm run start
- ? Select the authentication method you want to use: AWS profile
- ? Please choose the profile you want to use: <default – or pick the one you use>
This will setup an Amplify project in the cloud for the front-end.
A file called src/aws-exports.js
will be created. You can safely deleted this file.
(In fact, you can delete the src
folder entirely).
Configure the environment
Go to the file front-end/deployment/config/config-development.ts
.
Now, use the Pulumi output from before, to setup the environment:
const configDevelopment = {
...
/**
* Add the details from the Pulumi output here, after running 'pulumi up'
*/
USER_POOL_CLIENT_ID: '<USERPOOL-CLIENT-ID>',
USER_POOL_ID: '<USERPOOL-ID>',
IDENTITY_POOL_ID: '<IDENTITY-POOL-ID>',
GRAPHQL_ENDPOINT: 'https://<GRAPHQL-ENDPOINT>/graphql',
};
Next, run the command:
amplify codegen add -apiId <APPSYNC-ID>
- ? Choose the code generation language target: typescript
- ? Enter the file name pattern of graphql queries, mutations and subscriptions: /graphql/**/*.ts
- ? Do you want to generate/update all possible GraphQL operations – queries, mutations and subscriptions? Y
- ? Enter maximum statement depth [increase from default if your schema is deeply nested]: 4
- ? Enter the file name for the generated code: /graphql/API.ts
- ? Do you want to generate code for your newly created GraphQL API? Y
Add hosting
Finally, setup hosting for the front-end:
amplify hosting add
- ? Select the plugin module to execute: Hosting with Amplify Console
- ? Choose a type: Continuous deployment
Sign into AWS and link your GitHub repository to Amplify Console. When the environment has been set up, go to the Environment variables page from the left menu, and click Manage variables.
Add a new variable called NEXT_PUBLIC_CLOUD_ENV
with the value dev
.
Amplify will create a hosted URL for you.
Go to the file front-end/deployment/config/config-development.ts
again, and add the URL here:
/**
* Add your hosted dev URL here
*/
const HOSTED_URL = '<ADD-YOUR-HOSTED-URL-HERE>';
Finally, run:
amplify push
amplify publish
Let Amplify do it’s thing ?
Start the app locally
Start the app by running npm run dev
.
The app will start locally on http://localhost:3000.
Create a new user by going to the /signup
page.
Sign into the app by going to the /signin
page.
Authentication should work smoothly at this point – now, start building your SaaS ?
ℹ️ Additional info
If you want to use different environments (dev and prod), simply set up Pulumi in a different environment, and paste the output into the front-end/deployment/config/config-production.ts
.
Similarly, create an environment variable in the Amplify Console for the production environment called NEXT_PUBLIC_CLOUD_ENV
with the value prod
.
Get Help
Contribute
PRs are welcome!