{"id":13455813,"url":"https://github.com/async-labs/saas","last_synced_at":"2025-12-15T21:52:05.591Z","repository":{"id":38614622,"uuid":"128308007","full_name":"async-labs/saas","owner":"async-labs","description":"Build your own SaaS business with SaaS boilerplate. Productive stack: React, Material-UI, Next, MobX, WebSockets, Express, Node, Mongoose, MongoDB. Written with TypeScript.","archived":false,"fork":false,"pushed_at":"2025-03-21T18:07:06.000Z","size":6887,"stargazers_count":4252,"open_issues_count":18,"forks_count":708,"subscribers_count":96,"default_branch":"master","last_synced_at":"2025-04-27T18:21:07.101Z","etag":null,"topics":["aws-s3","aws-ses","boilerplate","express","google-api","mailchimp","material-ui","mobx","mongodb","mongoose","nextjs","passport","react","saas","saas-boilerplate","saas-business","saas-product","typescript"],"latest_commit_sha":null,"homepage":"https://saas-app.async-await.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/async-labs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"custom":["https://builderbook.org/book"]}},"created_at":"2018-04-06T03:39:25.000Z","updated_at":"2025-04-27T13:55:12.000Z","dependencies_parsed_at":"2025-04-02T02:20:59.531Z","dependency_job_id":null,"html_url":"https://github.com/async-labs/saas","commit_stats":{"total_commits":706,"total_committers":11,"mean_commits":64.18181818181819,"dds":"0.39518413597733715","last_synced_commit":"8a97969733e3e6b914fbeb67a444fe96a2ca66d1"},"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/async-labs%2Fsaas","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/async-labs%2Fsaas/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/async-labs%2Fsaas/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/async-labs%2Fsaas/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/async-labs","download_url":"https://codeload.github.com/async-labs/saas/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251300484,"owners_count":21567456,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws-s3","aws-ses","boilerplate","express","google-api","mailchimp","material-ui","mobx","mongodb","mongoose","nextjs","passport","react","saas","saas-boilerplate","saas-business","saas-product","typescript"],"created_at":"2024-07-31T08:01:11.553Z","updated_at":"2025-12-15T21:52:05.530Z","avatar_url":"https://github.com/async-labs.png","language":"TypeScript","readme":"![image](https://user-images.githubusercontent.com/26158226/155850630-137ae3be-aa29-487b-a422-e8fb4db634dc.png)\n\nSupport Ukraine: [link](https://bank.gov.ua/en/news/all/natsionalniy-bank-vidkriv-spetsrahunok-dlya-zboru-koshtiv-na-potrebi-armiyi)\n\n\n## SaaS Boilerplate\n\nOpen source web app that saves you many days of work when building your own SaaS product. The boilerplate comes with many basic SaaS features (see [Features](https://github.com/async-labs/saas#features) below) so that you can focus on features that differentiate your product.\n\nIf you want to learn how to build this project from scratch, check out our book: https://builderbook.org/book\n\nThe open source project is located in the `saas` folder. If you purchased our book, codebases for each of the book's chapters are located in the `book` folder.\n\nWe've used this `saas` project to build:\n- [Builder Book](https://builderbook.org) - learn how to build full-stack web apps from scratch\n- [SaaS Boilerplate](https://github.com/async-labs/saas) - open source web app to build your own SaaS product\n- [Work in biotech](https://workinbiotech.com) - job board for biotech startup companies\n- [AI-cruiter](https://workinbiotech.com/ai-cruiter) - browser extension is built for recruiters managing a high volume of job applicants. AI-cruiter uses LLMs - like ChatGPT and PaLM 2 - to generate succinct and relevant summaries of your job applicants' resumes\n- [Async](https://async-await.com) - open source urgent vs non-urgent team communication tool for small teams\n- [Async Labs](https://async-labs.com) - many custom dev projects\n\n\n## Live demo:\n\n- APP: https://saas-app.async-await.com\n- API: https://saas-api.async-await.com\n\n## Sponsors\n\n[![aws-activate-logo](https://user-images.githubusercontent.com/26158226/138565715-4311ddda-fb77-452a-8755-d53eb18f8645.png)](https://aws.amazon.com/activate/)\n\n![aws-open-source (2)](https://github.com/user-attachments/assets/50f5b67a-0c95-4304-817f-1606adb46c81)\n\n[![1password-logo](https://user-images.githubusercontent.com/26158226/138565841-ad435374-7330-477a-b6f3-2542109c3217.png)](https://1password.com/)\n\n## Showcase\n\nCheck out projects built with the help of this open source app. Feel free to add your own project by creating a pull request.\n\n- [Async](https://async-await.com/): Open source web app for team communication, separate urgent vs. non-urgent conversations.\n- [workinbiotech.com](https://workinbiotech.com): Work in biotech, job board for small and young biotech companies\n- [Retaino](https://retaino.com) by [Earl Lee](https://github.com/earllee): Save, annotate, review, and share great web content. Receive smart email digests to retain key information.\n- [Builder Book](https://github.com/async-labs/builderbook): Open source web app to publish documentation or books.\n\n\n## Contents\n\n- [Features](#features)\n- [Run locally](#running-api-locally)\n- [Deploy](#deploy-to-heroku-aws-elastic-beanstalk-api-gateway-and-aws-lambda)\n- [Built with](#built-with)\n- [Screenshots](#screenshots)\n- [Contributing](#contributing)\n- [Team](#team)\n- [License](#license)\n- [Project structure](#project-structure)\n\n## Features\n\n- Server-side rendering for fast initial load and SEO.\n- User authentication with Google OAuth API and Passwordless, cookie, and session.\n- Production-ready Express server with compression, parser, and helmet.\n- Transactional emails (`AWS SES`): welcome, team invitation, and payment.\n- Adding email addresses to newsletter lists (`Mailchimp`): new users, paying users.\n- File upload, load, and deletion (`AWS S3`) with pre-signed request for: Posts, Team Profile, and User Profile.\n- Websockets with socket.io v3.\n- Team creation, Team Member invitation, and settings for Team and User.\n- Opinionated architecture:\n  - keeping babel and webpack configurations under the hood,\n  - striving to minimize number of configurations,\n  - `withAuth` HOC to pass user prop and control user access to pages,\n  - HOC extensions `MyApp` and `MyDocument`\n  - server-side rendering with `Material-UI`,\n  - model-specific components in addition to common components.\n- Universally-available environmental variables at runtime.\n- Custom logger (configure what _not_ to print in production).\n- Useful components for any web app: `ActiveLink`, `Confirm`, `Notifier`, `MenuWithLinks`, and more.\n- Analytics with `Google Analytics`.\n- Production-ready, scalable architecture:\n  - `app` - user-facing web app with Next/Express server, responsible for rendering pages (either client-side or server-side rendered). `app` sends requests via API methods to `api` Express server.\n  - `api` - server-only code, Express server, responsible for processing requests for internal and external API infrastructures.\n- **Subscriptions with `Stripe`**:\n  - subscribe/unsubscribe Team to plan,\n  - update card information,\n  - verified Stripe webhook for failed payment for subscription.\n\n\n#### Running `api` locally:\n\n- Before running, create a `.env` file inside the `api` folder with the environmental variables as shown below. These variables are also listed in [`.env.example`](https://github.com/async-labs/saas/blob/master/saas/api/.env.example), which you can use as a template to create your own `.env` file inside the `api` foler.\n\n`api/.env`:\n\n  ```\n  # Used in api/server/server.ts\n  MONGO_URL_TEST=\n  MONGO_URL=\n  SESSION_NAME=\n  SESSION_SECRET=\n  COOKIE_DOMAIN=\n  \n  # Used in api/server/google.ts\n  GOOGLE_CLIENTID=\n  GOOGLE_CLIENTSECRET=\n  \n  # Used in api/server/aws-s3.ts and api/server/aws-ses.ts\n  AWS_REGION=\n  AWS_ACCESSKEYID=\n  AWS_SECRETACCESSKEY=\n  \n  # Used in api/server/models/Invitation.ts and api/server/models/User.ts\n  EMAIL_SUPPORT_FROM_ADDRESS=\n  \n  # Used in api/server/mailchimp.ts\n  MAILCHIMP_API_KEY=\n  MAILCHIMP_REGION=\n  MAILCHIMP_SAAS_ALL_LIST_ID=\n  \n  ----------\n  # All env variables above this line are needed for successful user signup\n  \n  # Used in api/server/stripe.ts\n  STRIPE_TEST_SECRETKEY=sk_test_xxxxxx\n  STRIPE_LIVE_SECRETKEY=sk_live_xxxxxx\n  \n  STRIPE_TEST_PLANID=plan_xxxxxx\n  STRIPE_LIVE_PLANID=plan_xxxxxx\n  \n  STRIPE_LIVE_ENDPOINTSECRET=whsec_xxxxxx\n  \n  # Optionally determine the URL\n  URL_APP=\"http://localhost:3000\"\n  URL_API=\"http://localhost:8000\"\n  PRODUCTION_URL_APP=\"https://saas-app.async-await.com\"\n  PRODUCTION_URL_API=\"https://saas-api.async-await.com\"\n  ```\n  \n  - Your `.env` file file _must_ have values for the `required` variables. To use all features and third-party integrations, also add the `optional` variables.\n\n  - IMPORTANT: do not publish your actual values for environmentable variables in `.env.example`; this file is public and only meant to show you how your `.env` should look.\u003cbr/\u003e\n  \n  - IMPORTANT: use your values for `PRODUCTION_URL_APP` and `PRODUCTION_URL_API`. These are values for domain name that you own.\n\n  - IMPORTANT: The above environmental variables are available on the server only. You should add your `.env` file to `.gitignore` inside the `api` folder so that your secret keys are not stored on a remote Github repo.\n\n  - To get value for `MONGO_URL_TEST`, we recommend you use a [free MongoDB at MongoDB Atlas](https://docs.atlas.mongodb.com/) or [$15/month MongoDB at Digital Ocean](https://www.digitalocean.com/products/managed-databases-mongodb/)\n  - Specify your own name and secret keys for Express session: [SESSION_NAME](https://github.com/expressjs/session#name) and [SESSION_SECRET](https://github.com/expressjs/session#express)\n  - Get `GOOGLE_CLIENTID` and `GOOGLE_CLIENTSECRET` by following the [official OAuth tutorial](https://developers.google.com/identity/sign-in/web/sign-in#before_you_begin). \u003cbr/\u003e\n    Important: For Google OAuth app, callback URL is: http://localhost:8000/oauth2callback \u003cbr/\u003e\n    Important: You have to enable Google+ API in your Google Cloud Platform account.\n\n- Once `.env` is created, you can run the `api` app. Navigate to the `api` folder, run `yarn install` to add all packages, then run the command below:\n  ```\n  yarn dev\n  ```\n\n\n#### Running `app` locally:\n\n- Navigate to the `app` folder, run `yarn` to add all packages, then run `yarn dev` and navigate to `http://localhost:3000`:\n\n  - A `.env` file in the `app` folder is not required to run, but you can create one to override the default variables. The environmental variables for `.env` in the `app` folder are shown below. You can also refer [`.env.example`](https://github.com/async-labs/saas/blob/master/saas/app/.env.example) for creating your own `.env` file in the `app` folder.\u003cbr/\u003e\n\n  ```\n    NEXT_PUBLIC_STRIPE_TEST_PUBLISHABLEKEY=\"pk_test_xxxxxxxxxxxxxxx\"\n    NEXT_PUBLIC_STRIPE_LIVE_PUBLISHABLEKEY=\"pk_live_xxxxxxxxxxxxxxx\"\n    \n    NEXT_PUBLIC_BUCKET_FOR_POSTS=\n    NEXT_PUBLIC_BUCKET_FOR_TEAM_AVATARS=\n    NEXT_PUBLIC_BUCKET_FOR_TEAM_LOGOS=\n    \n    NEXT_PUBLIC_URL_APP=\"http://localhost:3000\"\n    NEXT_PUBLIC_URL_API=\"http://localhost:8000\"\n    NEXT_PUBLIC_PRODUCTION_URL_APP=\n    NEXT_PUBLIC_PRODUCTION_URL_API=\n    \n    NEXT_PUBLIC_API_GATEWAY_ENDPOINT=\n    NEXT_PUBLIC_GA_MEASUREMENT_ID=\n  ```\n\n  - IMPORTANT: do not publish your actual values for environmentable variables in `.env.example`; this file is public and only meant to show you how your `.env` should look.\u003cbr/\u003e\n  \n  - IMPORTANT: use your values for `PRODUCTION_URL_APP` and `PRODUCTION_URL_API`. These are values for domain name that you own.\n\n  - To get `NEXT_PUBLIC_GA_MEASUREMENT_ID`, set up Google Analytics and follow [these instructions](https://support.google.com/analytics/answer/1008080?hl=en) to find your tracking ID.\n  - To get `NEXT_PUBLIC_STRIPE_TEST_PUBLISHABLEKEY`, go to your Stripe dashboard, click `Developers`, then click `API keys`.\n\n- For successful file uploading, make sure your buckets have proper CORS configuration. Go to your AWS account, find your bucket, go to `Permissions \u003e CORS configuration`, add:\n\n```\n[\n  {\n    \"AllowedHeaders\":[\n      \"*\"\n    ],\n    \"AllowedMethods\":[\n      \"PUT\",\n      \"POST\",\n      \"GET\",\n      \"HEAD\",\n      \"DELETE\"\n    ],\n    \"AllowedOrigins\":[\n      \"http://localhost:3000\",\n      \"https://saas-app.async-await.com\"\n    ],\n    \"ExposeHeaders\":[\n      \"ETag\",\n      \"x-amz-meta-custom-header\"\n    ]\n  }\n]\n```\n\n- Make sure to update allowed origin with your actual values for `NEXT_PUBLIC_URL_APP` and `NEXT_PUBLIC_PRODUCTION_URL_APP`.\n\n- Once `.env` is created, you can run the `app` app. Navigate to the `app` folder, run `yarn install` to add all packages, then run the command below:\n  ```\n  yarn dev\n  ```\n\n\n#### Symlink `api` in `lambda`:\n\nIn lambda directory we are symlinking api directory. You can run symlink command in lambda folder as mentioned below:\n```\nbash symlink ../api\n```\n\n## Deploy to Heroku, AWS Elastic Beanstalk, API Gateway and AWS Lambda\n\nWe give detailed instructions inside Chapter 9 and 10 of our SaaS Boilerplate book: https://builderbook.org/book\n\n## Built with\n\n- [React](https://github.com/facebook/react)\n- [Material-UI](https://github.com/mui-org/material-ui)\n- [Next](https://github.com/vercel/next.js)\n- [MobX](https://github.com/mobxjs/mobx)\n- [Express](https://github.com/expressjs/express)\n- [Mongoose](https://github.com/Automattic/mongoose)\n- [MongoDB](https://github.com/mongodb/mongo)\n- [Typescript](https://github.com/Microsoft/TypeScript)\n\nFor more detail, check `package.json` files in both `app` and `api` folders and project's root.\n\nTo customize styles, check [this guide](https://github.com/async-labs/builderbook#add-your-own-styles).\n\n\n## Screenshots\n\nGoogle or passwordless login:\n![1_SaaS_login](https://user-images.githubusercontent.com/26158226/61417504-2760b000-a8ac-11e9-8ce6-14fc5947dad0.png)\n\nDropdown menu for settings:\n![2_SaaS_DropdownMenu](https://user-images.githubusercontent.com/26158226/61417505-27f94680-a8ac-11e9-9390-35e17e1626c3.png)\n\nPersonal settings:\n![3_SaaS_PersonalSettings](https://user-images.githubusercontent.com/26158226/61417514-2891dd00-a8ac-11e9-97d4-53944fe8f897.png)\n\nTeam settings:\n![4_SaaS_TeamSettings](https://user-images.githubusercontent.com/26158226/61417515-2891dd00-a8ac-11e9-9c08-0d1adef43c5b.png)\n\nCreating a Discussion:\n![5_SaaS_Discussion_Creation](https://user-images.githubusercontent.com/26158226/61417509-27f94680-a8ac-11e9-889b-19f96b159d21.png)\n\nWriting a Post, Markdown vs. HTML view:\n![6_SaaS_Discussion_Markdown](https://user-images.githubusercontent.com/26158226/61417508-27f94680-a8ac-11e9-93fd-766014132e8d.png)\n\n![7_SaaS_Discussion_HTML](https://user-images.githubusercontent.com/26158226/61417507-27f94680-a8ac-11e9-8058-d3701ef1696d.png)\n\nDiscussion between team members:\n![8_SaaS_Discussion_Dark](https://user-images.githubusercontent.com/26158226/61417506-27f94680-a8ac-11e9-9cba-cc47ba3b51a8.png)\n\nBilling settings:\n![9_SaaS_Billing](https://user-images.githubusercontent.com/26158226/61417513-2891dd00-a8ac-11e9-9e3d-bcbcdfe5b5af.png)\n\nPurchasing a subscription:\n![10_SaaS_BuySubscription](https://user-images.githubusercontent.com/26158226/103588107-6407d900-4e9d-11eb-9159-e85301205739.png)\n\nPayment history:\n![12_SaaS_PaymentHistory](https://user-images.githubusercontent.com/26158226/61417510-27f94680-a8ac-11e9-88d1-1eef120dcc34.png)\n\n\n## Contributing\n\nWant to support this project? Consider buying our [books](https://builderbook.org/).\n\n\n## Team\n\n- [Kelly Burke](https://github.com/klyburke)\n- [Timur Zhiyentayev](https://github.com/tima101)\n\nYou can contact us at team@async-labs.com.\n\nIf you are interested in working with us, check out [Async Labs](https://async-labs.com/).\n\n\n## License\n\nAll code in this repository is provided under the [MIT License](https://github.com/async-labs/saas/blob/master/LICENSE.md).\n\n## Project structure\n\n```\n├── .elasticbeanstalk\n│   └── config.yml\n├── .github\n│   └── FUNDING.yml\n├── .vscode\n│   ├── extensions.json\n│   ├── launch.json\n│   └── settings.json\n├── api\n│   ├── .elasticbeanstalk\n│   │   └── config.yml\n│   ├── server\n│   │   ├── api\n│   │   │   ├── index.ts\n│   │   │   ├── public.ts\n│   │   │   ├── team-leader.ts\n│   │   │   └── team-member.ts\n│   │   ├── models\n│   │   │   ├── Discussion.ts\n│   │   │   ├── EmailTemplate.ts\n│   │   │   ├── Invitation.ts\n│   │   │   ├── Post.ts\n│   │   │   ├── Team.ts\n│   │   │   └── User.ts\n│   │   ├── utils\n│   │   │   ├── slugify.ts\n│   │   │   └── sum.ts\n│   │   ├── aws-s3.ts\n│   │   ├── aws-ses.ts\n│   │   ├── google-auth.ts\n│   │   ├── logger.ts\n│   │   ├── mailchimp.ts\n│   │   ├── passwordless-auth.ts\n│   │   ├── passwordless-token-mongostore.ts\n│   │   ├── server.ts\n│   │   ├── sockets.ts\n│   │   └── stripe.ts\n│   ├── static\n│   │   └── robots.txt\n│   ├── test/server/utils\n│   │   ├── slugify.test.ts\n│   │   └── sum.test.ts\n│   ├── .eslintignore\n│   ├── .eslintrc.js\n│   ├── .gitignore\n│   ├── package.json\n│   ├── tsconfig.json\n│   ├── tsconfig.server.json\n│   └── yarn.lock\n├── app\n│   ├── .elasticbeanstalk\n│   │   └── config.yml\n│   ├── components\n│   │   ├── common\n│   │   │   ├── Confirmer.tsx\n│   │   │   ├── LoginButton.tsx\n│   │   │   ├── MemberChooser.tsx\n│   │   │   ├── MenuWithLinks.tsx\n│   │   │   ├── MenuWithMenuItems.tsx\n│   │   │   └── Notifier.tsx\n│   │   ├── discussions\n│   │   │   ├── CreateDiscussionForm.tsx\n│   │   │   ├── DiscussionActionMenu.tsx\n│   │   │   ├── DiscussionList.tsx\n│   │   │   ├── DiscussionListItem.tsx\n│   │   │   └── EditDiscussionForm.tsx\n│   │   ├── layout\n│   │   │   ├── index.tsx\n│   │   ├── posts\n│   │   │   ├── PostContent.tsx\n│   │   │   ├── PostDetail.tsx\n│   │   │   ├── PostEditor.tsx\n│   │   │   └── PostForm.tsx\n│   │   ├── teams\n│   │   │   └── InviteMember.tsx\n│   ├── lib\n│   │   ├── api\n│   │   │   ├── makeQueryString.ts\n│   │   │   ├── public.ts\n│   │   │   ├── sendRequestAndGetResponse.ts\n│   │   │   ├── team-leader.ts\n│   │   │   └── team-member.ts\n│   │   ├── store\n│   │   │   ├── discussion.ts\n│   │   │   ├── index.ts\n│   │   │   ├── invitation.ts\n│   │   │   ├── post.ts\n│   │   │   ├── team.ts\n│   │   │   └── user.ts\n│   │   ├── confirm.ts\n│   │   ├── isMobile.ts\n│   │   ├── notify.ts\n│   │   ├── resizeImage.ts\n│   │   ├── sharedStyles.ts\n│   │   ├── theme.ts\n│   │   └── withAuth.tsx\n│   ├── pages\n│   │   ├── _app.tsx\n│   │   ├── _document.tsx\n│   │   ├── billing.tsx\n│   │   ├── create-team.tsx\n│   │   ├── discussion.tsx\n│   │   ├── invitation.tsx\n│   │   ├── login-cached.tsx\n│   │   ├── login.tsx\n│   │   ├── team-settings.tsx\n│   │   └── your-settings.tsx\n│   ├── public\n│   │   └── pepe.jpg\n│   ├── server\n│   │   ├── robots.txt\n│   │   ├── routesWithCache.ts\n│   │   ├── server.ts\n│   │   └── setupSitemapAndRobots.ts\n│   ├── .babelrc\n│   ├── .eslintignore\n│   ├── .eslintrc.js\n│   ├── .gitignore\n│   ├── next.env.d.ts\n│   ├── next.config.js\n│   ├── package.json\n│   ├── tsconfig.json\n│   ├── tsconfig.server.json\n│   └── yarn.lock\n├── book\n├── lambda\n│   ├── .estlintignore\n│   ├── .eslintrc.js\n│   ├── .gitignore\n│   ├── api\n│   ├── handler.ts\n│   ├── package.json\n│   ├── serverless.yml\n│   ├── tsconfig.json\n│   └── yarn.lock\n├── .gitignore\n├── LICENSE.md\n├── README.md\n├── package.json\n├── yarn.lock\n```\n","funding_links":["https://builderbook.org/book"],"categories":["TypeScript","JavaScript","Codebase","📦 Legacy \u0026 Inactive Projects","Boilerplates","Node.js","Web Development","boilerplate","Starter Kits \u0026 Templates","Awesome MobX","Applications"],"sub_categories":["Node.js","Examples","Web"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fasync-labs%2Fsaas","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fasync-labs%2Fsaas","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fasync-labs%2Fsaas/lists"}