{"id":50892835,"url":"https://github.com/nastaso/cloudcertprep","last_synced_at":"2026-06-15T22:00:45.121Z","repository":{"id":339855195,"uuid":"1163607752","full_name":"nastaso/cloudcertprep","owner":"nastaso","description":"Free, open-source AWS certification practice exams. CloudCertPrep ships 1,050+ AWS Cloud Practitioner (CLF-C02) questions, full-length mock exams, domain practice with adaptive spaced repetition, and progress tracking. No ads, no paywalls, no premium tiers. MIT licensed.","archived":false,"fork":false,"pushed_at":"2026-06-11T21:05:13.000Z","size":2270,"stargazers_count":25,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-06-11T23:07:44.265Z","etag":null,"topics":["aws","aws-certification","aws-cloud-practitioner","clf-c02","cloud-certification","exam-prep","free","mock-exam","open-source","practice-exam","react","saa-c03","spaced-repetition","study-tool","supabase","tailwindcss","typescript","vite"],"latest_commit_sha":null,"homepage":"https://www.cloudcertprep.io/","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/nastaso.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"ko_fi":"alexsantonastaso"}},"created_at":"2026-02-21T22:00:22.000Z","updated_at":"2026-06-09T09:58:12.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/nastaso/cloudcertprep","commit_stats":null,"previous_names":["snts42/cloudcertprep","nastaso/cloudcertprep"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/nastaso/cloudcertprep","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nastaso%2Fcloudcertprep","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nastaso%2Fcloudcertprep/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nastaso%2Fcloudcertprep/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nastaso%2Fcloudcertprep/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nastaso","download_url":"https://codeload.github.com/nastaso/cloudcertprep/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nastaso%2Fcloudcertprep/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34381762,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-15T02:00:07.085Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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","aws-certification","aws-cloud-practitioner","clf-c02","cloud-certification","exam-prep","free","mock-exam","open-source","practice-exam","react","saa-c03","spaced-repetition","study-tool","supabase","tailwindcss","typescript","vite"],"created_at":"2026-06-15T22:00:24.449Z","updated_at":"2026-06-15T22:00:45.116Z","avatar_url":"https://github.com/nastaso.png","language":"TypeScript","funding_links":["https://ko-fi.com/alexsantonastaso"],"categories":[],"sub_categories":[],"readme":"# CloudCertPrep\n\n### Free open-source AWS certification practice exams\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/nastaso/cloudcertprep\"\u003e\u003cstrong\u003e⭐ Star CloudCertPrep on GitHub\u003c/strong\u003e\u003c/a\u003e\n  \u0026nbsp;·\u0026nbsp;\n  \u003ca href=\"https://www.cloudcertprep.io\"\u003e\u003cstrong\u003e🚀 Try the live demo\u003c/strong\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n[![CI](https://github.com/nastaso/cloudcertprep/actions/workflows/ci.yml/badge.svg)](https://github.com/nastaso/cloudcertprep/actions/workflows/ci.yml)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)\n[![Live demo](https://img.shields.io/badge/demo-cloudcertprep.io-FF9900)](https://www.cloudcertprep.io)\n[![Last commit](https://img.shields.io/github/last-commit/nastaso/cloudcertprep)](https://github.com/nastaso/cloudcertprep/commits/main)\n[![GitHub stars](https://img.shields.io/github/stars/nastaso/cloudcertprep?style=social)](https://github.com/nastaso/cloudcertprep/stargazers)\n\n1,050+ AWS Cloud Practitioner and 419+ AWS Certified AI Practitioner practice questions. Full-length timed mock exams, domain-by-domain practice with adaptive spaced repetition, and progress tracking. No signup required, no ads. MIT licensed and publicly auditable on GitHub.\n\nNo ads, no paywalls, no premium tiers. MIT licensed.\n\n\u003e If CloudCertPrep helps you pass your AWS exam, a star here costs you nothing and is the strongest signal that this project should keep getting built. **[⭐ Star the repo](https://github.com/nastaso/cloudcertprep)** to follow new certifications as they ship.\n\n\u003e Most paid AWS exam-prep platforms ship a fixed handful of practice exams pulled from a small question bank. CloudCertPrep randomises every exam from a much larger bank, so the practice variations are effectively unlimited.\n\n### Contribute in 60 seconds\n\nThe question banks are plain JSON, one file per exam domain. Spotted a wrong answer or want to add a question?\n\n1. Open the relevant file under [`src/data/\u003ccert\u003e/`](src/data) (e.g. `src/data/clf-c02/domain1.json`). You can edit it right in the GitHub web UI.\n2. Fix or add a question following the [schema in CONTRIBUTING.md](./CONTRIBUTING.md#question-json-schema).\n3. Open a pull request. The validator (`npm run validate`) checks it automatically.\n\nNo local setup needed for question edits. Good first issues are labelled [`good first issue`](https://github.com/nastaso/cloudcertprep/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22): pick one and dive in.\n\n---\n\n## Features\n\n- **Timed mock exams** that match the real AWS format (questions, duration, and passing score read from each cert's config).\n- **Domain practice** with instant per-question feedback and explanations.\n- **Spaced repetition** weighting prioritises questions you've previously got wrong or haven't seen.\n- **Answer randomisation** shuffles option order per attempt (correct-answer mapping preserved server-side).\n- **Progress tracking** for domain mastery, full exam history, and per-question review.\n- **Community stats page** with pass rates, average scores, and domain difficulty rankings.\n- **Multi-certification architecture** that supports any number of domains per cert with no code or schema changes.\n- **Guest mode** for the full exam without an account; sign in only when you want progress saved.\n- **Google, GitHub, and email/password sign-in** via Supabase Auth, with Cloudflare Turnstile bot protection on the auth flow.\n\nCurrent certifications:\n\n| Cert | Status | Questions |\n|---|---|---|\n| AWS Cloud Practitioner (CLF-C02) | Active | ~1,050 |\n| AWS Certified AI Practitioner (AIF-C01) | Active | 419 |\n| AWS Solutions Architect Associate (SAA-C03) | Coming soon | Placeholder |\n\n---\n\n## Roadmap\n\n- AWS Solutions Architect Associate (SAA-C03) — question bank in progress, target Q3 2026\n- AWS Developer Associate (DVA-C02) — planned for late 2026\n- AWS SysOps Administrator Associate (SOA-C02) — planned for 2027\n- Per-cert programmatic SEO landing pages (`/aws/clf-c02/security-questions`, etc.)\n- Per-cert OG share images\n- Community-contributed questions via PR review\n\nNew certification proposals and contributors are welcome via the [add-certification issue template](https://github.com/nastaso/cloudcertprep/issues/new?template=add-certification.yml).\n\n---\n\n## Quick Start\n\n```bash\ngit clone https://github.com/nastaso/cloudcertprep.git\ncd cloudcertprep\nnpm install\ncp .env.example .env   # fill in VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY\nnpm run dev\n```\n\nYou'll need your own [Supabase](https://supabase.com) project to test authenticated flows. The anon key and project URL are safe to expose (security is enforced server-side via Row Level Security). The service role key is private and never appears in client code.\n\nOpen \u003chttp://localhost:4321\u003e (the Astro dev server's default port). Sign-up flows require a working Supabase backend; everything else (guest exams, domain practice) works offline against the bundled question JSON.\n\nSign-in offers three options (**Google, GitHub, and email/password**), brokered by Supabase Auth, with Cloudflare Turnstile bot protection on the auth forms. None of these are needed to develop the guest-mode experience. Maintainer setup for the OAuth providers (Google and GitHub) and Turnstile lives in [CONTRIBUTING.md, Deployment and auth setup](./CONTRIBUTING.md#deployment--auth-setup-maintainer).\n\n---\n\n\n## Architecture\n\nCloudCertPrep is an **Astro hybrid** site. Astro prerenders the public SEO\nsurface to static HTML at build time, and the interactive flows hydrate as\n**React islands** on top of that static shell.\n\n```\n+-------------------------------------------------------------+\n|                       Netlify CDN                           |\n|                 (static hosting, global edge)               |\n+-------------------------------------------------------------+\n|                                                             |\n|  Astro static output (output: 'static') — one HTML file     |\n|  per route, prerendered at build time:                      |\n|    /  /about  /blog  /blog/:slug  /contribute               |\n|    /aws/:cert  /aws/:cert/:domain  /privacy  /terms  /404   |\n|                                                             |\n|  React islands hydrate inside the static shells:            |\n|    Header nav, Footer, DonateButton, CookieConsent,         |\n|    the practice-exam / domain-practice / history / login /  |\n|    reset-password bodies, and the /stats + cert dashboard.  |\n|                                                             |\n|  Question data: static JSON, code-split per cert/domain.    |\n|  Sample questions on domain landings are server-rendered.   |\n|                                                             |\n+-----------------------------+-------------------------------+\n                              | HTTPS (auth + persistence)\n                              v\n+-------------------------------------------------------------+\n|             Supabase (PostgreSQL + Auth, EU/Ireland)        |\n|                                                             |\n|  Auth:  email/password, GitHub OAuth, Google OAuth, JWT     |\n|         Cloudflare Turnstile CAPTCHA on auth requests       |\n|                                                             |\n|  Tables                                                     |\n|    exam_attempts        domain scores stored as JSONB       |\n|                         (supports any number of domains)    |\n|    attempt_questions    per-question results, flagged state |\n|    domain_progress      per-domain mastery percentages      |\n|    platform_stats       aggregate counters                  |\n|    question_mastery     view, SECURITY INVOKER, RLS         |\n|                                                             |\n|  RPC: get_public_exam_stats() returns aggregates only       |\n|                                                             |\n|  Security: RLS on every user-data table                     |\n|            policy: auth.uid() = user_id                     |\n+-------------------------------------------------------------+\n```\n\n**Data flow:** the question bank is static, served from the CDN with zero database cost regardless of traffic. Guest sessions never touch Supabase. Authenticated sessions hit Supabase to sign in, persist exam attempts, and read back history, domain progress, and community stats. This keeps the free tier comfortable even with thousands of concurrent guest exams.\n\n---\n\n## Tech stack\n\n| Layer | Technology |\n|---|---|\n| Framework | Astro 6 (static output) with React 19 islands |\n| Language | TypeScript |\n| Build | Astro + Vite 7 |\n| Styling | Tailwind CSS 3.4 (CSS variable tokens for theming) |\n| Auth and DB | Supabase (PostgreSQL with Row Level Security, JWT auth) |\n| Bot protection | Cloudflare Turnstile (CAPTCHA on Supabase auth) |\n| Hosting | Netlify (auto-deploy from `main`) |\n| Email | Brevo SMTP via Supabase Auth |\n| Analytics | Umami (cookieless, always on) + GA4 (consent-gated) |\n| CI | GitHub Actions: validate, lint, astro check, test, build, citation guard |\n\nThe marketing surface is prerendered static HTML, so crawlers and LLM browse-mode read full content with no JavaScript. Interactive islands are code-split and hydrate on demand. See `npm run build` output for exact sizes against your local build.\n\n---\n\n## Project structure\n\n```\nsrc/\n  pages/          Astro routes. *.astro prerender the static surface (home,\n                  cert/domain landings, about, blog, legal, 404); _*.tsx are\n                  the React island bodies (MockExam, DomainPractice, History,\n                  Login, ResetPassword, Stats) mounted by the .astro shells.\n  layouts/        BaseLayout.astro (head, JSON-LD, chrome) + BlogLayout.astro\n  components/     Astro components (*.astro) for static UI + React (*.tsx) for\n                  islands; shared style recipe in lib/buttonStyles.ts\n  content/        Markdown blog collection (content.config.ts defines the schema)\n  hooks/          useAuth, useCert, useTheme, useTimer, useSpacedRepetition, ...\n  lib/            scoring, formatting, analytics, supabase client, citation-content,\n                  seo-data, constants, logger, generated/ (build outputs)\n  data/           Certification registry + question JSON per cert/domain,\n                  keyword-clusters for per-domain SEO targeting\n  types/          TypeScript interfaces (Question, ExamAttempt, OptionKey, DomainId)\n\nscripts/          Build/prebuild + CI checks:\n  validate-questions.mjs    Question-bank validator (`npm run validate`)\n  generate-seo-assets.mjs   Sitemap + question-counts.ts + llms.txt + _redirects\n  generate-og-images.mjs    Per-cert / per-domain / blog OG composites\n  generate-stats-snapshot.mjs   Build-time /stats snapshot\n  validate-blog-frontmatter.mjs, validate-internal-links.mjs,\n  check-citation-phrases.mjs, validate-internal-graph.mjs, diagnose-indexing.mjs,\n  check-free-for-dev-link.mjs, check-staged-files.mjs\n\n.github/\n  workflows/ci.yml          GitHub Actions CI\n  ISSUE_TEMPLATE/           Bug report, question error, new cert templates\n  PULL_REQUEST_TEMPLATE.md  PR checklist\n```\n\n---\n\n## Contributing\n\nQuestion fixes, new certifications, accessibility improvements, and bug fixes are all welcome. See [CONTRIBUTING.md](./CONTRIBUTING.md) for the full guide, including the question JSON schema, the design tokens, and the walkthrough for adding a new cert.\n\nQuick links:\n\n- [Report a question error](https://github.com/nastaso/cloudcertprep/issues/new?template=report-question-error.yml)\n- [Propose a new certification](https://github.com/nastaso/cloudcertprep/issues/new?template=add-certification.yml)\n- [File a bug](https://github.com/nastaso/cloudcertprep/issues/new?template=bug-report.yml)\n\nRun all checks locally before opening a PR (the same checks CI runs on every pull request):\n\n```bash\nnpm run lint\nnpm run validate\nnpm run test\nnpm run build\n```\n\n---\n\n## Contributors\n\nCloudCertPrep is maintained by [Alex Santonastaso](https://santonastaso.me). Question fixes and new certification banks are credited in commit history; project-level contributors will be listed here.\n\n---\n\n## License\n\n[MIT](./LICENSE). Built by [Alex Santonastaso](https://santonastaso.me). If this saved you the cost of a paid practice platform, you can [buy me a coffee](https://ko-fi.com/alexsantonastaso).\n\n\u003e **Disclaimer.** Not affiliated with, endorsed by, or associated with Amazon Web Services, Inc. AWS, Amazon Web Services, and all related marks are trademarks of Amazon.com, Inc. or its affiliates.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnastaso%2Fcloudcertprep","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnastaso%2Fcloudcertprep","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnastaso%2Fcloudcertprep/lists"}