{"id":30697487,"url":"https://github.com/umarsiddique010/resume-craft-react","last_synced_at":"2026-04-27T16:31:39.740Z","repository":{"id":293257980,"uuid":"983307425","full_name":"umarSiddique010/resume-craft-react","owner":"umarSiddique010","description":"Client-side resume builder built with React 19 and Vite. Features 3 professional templates, ATS-friendly PDF export, real-time preview, custom fonts, full Vitest test suite, GitHub Actions CI, and Vercel CD.","archived":false,"fork":false,"pushed_at":"2026-04-03T11:05:08.000Z","size":7589,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-03T16:27:49.320Z","etag":null,"topics":["cv-buider","cv-builder","javascipt","javascript","react","react-hook","react-hooks","responsive-design","resume-builder","resume-creator","resume-template","resume-templates","resume-website","vitejs"],"latest_commit_sha":null,"homepage":"https://resume-craft-react.vercel.app/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/umarSiddique010.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-05-14T07:31:12.000Z","updated_at":"2026-04-03T11:05:16.000Z","dependencies_parsed_at":"2025-08-08T21:45:11.099Z","dependency_job_id":null,"html_url":"https://github.com/umarSiddique010/resume-craft-react","commit_stats":null,"previous_names":["umarsiddique010/cv-builder","umarsiddique010/resume-craft-react"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/umarSiddique010/resume-craft-react","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umarSiddique010%2Fresume-craft-react","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umarSiddique010%2Fresume-craft-react/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umarSiddique010%2Fresume-craft-react/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umarSiddique010%2Fresume-craft-react/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/umarSiddique010","download_url":"https://codeload.github.com/umarSiddique010/resume-craft-react/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umarSiddique010%2Fresume-craft-react/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32345802,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-26T23:26:28.701Z","status":"online","status_checked_at":"2026-04-27T02:00:06.769Z","response_time":128,"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":["cv-buider","cv-builder","javascipt","javascript","react","react-hook","react-hooks","responsive-design","resume-builder","resume-creator","resume-template","resume-templates","resume-website","vitejs"],"created_at":"2025-09-02T09:10:24.861Z","updated_at":"2026-04-27T16:31:39.735Z","avatar_url":"https://github.com/umarSiddique010.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# \u003cimg height=\"50\" src=\"./public/favicon.ico\" alt=\"logo\" style=\"margin-bottom:-15px;\"\u003e Resume Craft\n\n\u003cdiv align=\"center\"\u003e\n\n### Craft Your Perfect Resume.\n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003eA production-grade React 19 resume builder with multiple templates,\n  ATS-friendly output, PDF export, and a fully tested codebase.\u003c/strong\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://resume-craft-react.vercel.app/\"\u003e\u003cstrong\u003eView Live Production Deployment\u003c/strong\u003e\u003c/a\u003e\n  \u0026nbsp;\u0026nbsp;\u0026bull;\u0026nbsp;\u0026nbsp;\n  \u003ca href=\"#local-development\"\u003e\u003cstrong\u003eLocal Setup\u003c/strong\u003e\u003c/a\u003e\n  \u0026nbsp;\u0026nbsp;\u0026bull;\u0026nbsp;\u0026nbsp;\n  \u003ca href=\"https://github.com/umarSiddique010/resume-craft-react\"\u003e\u003cstrong\u003eRepository\u003c/strong\u003e\u003c/a\u003e\n  \u0026nbsp;\u0026nbsp;\u0026bull;\u0026nbsp;\u0026nbsp;\n  \u003ca href=\"https://github.com/umarSiddique010/resume-craft-react/issues\"\u003e\u003cstrong\u003eReport an Issue\u003c/strong\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n[![React](https://img.shields.io/badge/React_19-20232A?style=for-the-badge\u0026logo=react\u0026logoColor=61DAFB)](https://react.dev/)\n[![Vite](https://img.shields.io/badge/Vite-646CFF?style=for-the-badge\u0026logo=vite\u0026logoColor=white)](https://vitejs.dev/)\n[![JavaScript](https://img.shields.io/badge/JavaScript-F7DF1E?style=for-the-badge\u0026logo=javascript\u0026logoColor=black)](https://developer.mozilla.org/en-US/docs/Web/JavaScript)\n[![React Router](https://img.shields.io/badge/React_Router_v7-CA4245?style=for-the-badge\u0026logo=react-router\u0026logoColor=white)](https://reactrouter.com/)\n[![React PDF](https://img.shields.io/badge/@react--pdf-FF0000?style=for-the-badge\u0026logo=adobeacrobatreader\u0026logoColor=white)](https://react-pdf.org/)\n[![Vitest](https://img.shields.io/badge/Vitest-6E9F18?style=for-the-badge\u0026logo=vitest\u0026logoColor=white)](https://vitest.dev/)\n[![Husky](https://img.shields.io/badge/Husky_Hooks-42B983?style=for-the-badge\u0026logo=git\u0026logoColor=white)](https://typicode.github.io/husky/)\n[![Lint-Staged](https://img.shields.io/badge/Lint--Staged-1572B6?style=for-the-badge\u0026logo=git\u0026logoColor=white)](https://github.com/lint-staged/lint-staged)\n[![Vercel](https://img.shields.io/badge/Vercel_Deployment-000000?style=for-the-badge\u0026logo=vercel\u0026logoColor=white)](https://vercel.com/)\n[![CI/CD](https://img.shields.io/badge/CI%2FCD-GitHub_Actions_+_Vercel-2088FF?style=for-the-badge\u0026logo=githubactions\u0026logoColor=white)](https://github.com/umarSiddique010/resume-craft-react/actions)\n\n\u003c/div\u003e\n\n## Overview\n\n**Resume Craft** is a fully client-side resume builder built with **React 19** and **Vite**. Users instantly generate a professional PDF resume — **no backend, no login, and no data storage**. Since **privacy matters**, all data stays in the browser and never leaves the user's device.\n\nThe project is engineered with a focus on code quality: a strict **Context + Reducer** state architecture, strong **Vitest** coverage across components, templates, and reducer logic, an automated **Husky + Lint-Staged** pre-commit pipeline, and a **GitHub Actions CI/CD** pipeline that gates every production deploy behind passing tests and builds.\n\n## Application Preview\n\n![Resume Craft Live](./public/app-screenshot.webp)\n\n## Features \u0026 Architecture\n\n### 1. Four Professional Resume Templates\n\n- **Bold Accent** — Modern two-column layout with a dark navy header, gold accent elements, and skill badges — set as the default template\n- **Standard** — Clean two-column layout with an olive sidebar and profile picture support\n- **Classic** — Traditional single-column design with a centered header\n- **ATS-Friendly** — Text-only, parser-safe layout built with `@react-pdf/renderer` to pass automated applicant tracking systems\n\n### 2. Client-Side PDF Generation\n\nPDF export runs entirely in the browser — no server round-trips, no file uploads.\n\n- **`@react-pdf/renderer`** handles the ATS template as a true PDF document with preserved text layers\n- **`html2pdf.js` + `html2canvas`** captures the live DOM preview for high-fidelity layout export on Bold Accent, Standard, and Classic templates\n- **6 Custom Font Choices** — Roboto, Google Sans Code, Poppins, Playwrite NZ, Delius Swash Caps, Rubik Distressed\n\n### 3. Global State: Context + Reducer\n\nAll resume data lives in a single state tree managed by `useReducer` inside `InputFieldContext`. No Redux, no Zustand — just clean React primitives.\n\n- **Typed Action Constants** — Every section (Work, Education, Skills, Projects, etc.) has its own scoped `ADD / UPDATE / REMOVE / REMOVE_ALL` action types defined in `resumeTypes.js`\n- **Pure Reducer** — `resumeReducer.js` is a single pure function with zero side effects, making it fully deterministic and easy to test\n- **Live Preview** — `DisplayTemplate` consumes context directly, so the resume preview re-renders in real time as the user types\n\n```\nUser types in form\n      ↓\ndispatchField({ type: UPDATE_WORK_EXPERIENCE_FIELD, payload })\n      ↓\nresumeReducer → new state\n      ↓\nInputFieldContext re-renders consumers\n      ↓\n\u003cDisplayTemplate /\u003e updates instantly\n      ↓\nUser clicks Download → PDF generated client-side\n```\n\n### 4. Testing \u0026 Quality Assurance\n\nThis project treats testing as a first-class citizen, not an afterthought.\n\n- **Unit Testing** — All components (WelcomePage, HomePage, all UserInput sections, all four templates) and reducer logic are tested using **Vitest** and **React Testing Library**\n- **Reducer Tests** — Comprehensive test cases validate the `resumeReducer` across core action paths including add, update, remove, and key edge cases.\n- **Mocking Strategy** — External dependencies like `@react-pdf/renderer`, `react-router-dom`, and `html2pdf.js` are mocked to ensure isolated, deterministic tests\n\n### 5. CI/CD Pipeline\n\nEvery push to `main` triggers the full pipeline:\n\n- **Quality** — Runs `npm run check` (ESLint + Prettier) on every push and PR\n- **Test** — Runs `npm run coverage` (Vitest); build job won't start until this passes\n- **Build** — Runs `npm run build` only after tests pass (`needs: test`)\n- **Deploy** — Vercel auto-deploys to production only after all CI jobs pass — no broken build ever reaches production\n- **Git Hooks (Husky + Lint-Staged)** — ESLint and Prettier enforced locally on pre-commit, catching issues before they reach CI\n\n### 6. Performance Optimizations\n\n- **Route-level Code Splitting** — All routes are lazy-loaded via `React.lazy` + `Suspense`, keeping the initial bundle minimal\n- **Manual Chunk Splitting** — `@react-pdf/renderer`, `react-icons`, and vendor libraries are split into separate chunks via Vite's `manualChunks`\n- **Font Preloading** — Critical fonts preloaded in `index.html` via `\u003clink rel=\"preload\"\u003e`\n- **Local Fonts Only** — All fonts are self-hosted `woff2` files; no external CDN dependency\n\n## Tech Stack\n\n| Category             | Technology                    | Usage                                                        |\n| :------------------- | :---------------------------- | :----------------------------------------------------------- |\n| **UI Library**       | **React 19**                  | Component architecture, hooks, context                       |\n| **Build Tool**       | **Vite**                      | Dev server and production bundler                            |\n| **State Management** | **Context + useReducer**      | Global resume state with typed actions                       |\n| **PDF Generation**   | **@react-pdf/renderer**       | ATS-friendly true PDF rendering                              |\n| **PDF Export**       | **html2pdf.js / html2canvas** | High-fidelity DOM-to-PDF download                            |\n| **Routing**          | **React Router v7**           | Client-side page navigation                                  |\n| **Location Data**    | **country-state-city**        | Address field dropdowns                                      |\n| **Testing**          | **Vitest + RTL**              | Unit tests for all components and reducers                   |\n| **Code Quality**     | **ESLint + Prettier**         | Enforced style and lint rules                                |\n| **Git Hooks**        | **Husky + Lint-Staged**       | Pre-commit validation pipeline                               |\n| **CI/CD**            | **GitHub Actions + Vercel**   | Quality → Test → Build → Auto-deploy on every push to `main` |\n\n## Local Development\n\n### Prerequisites\n\n- Node.js 18+ (LTS recommended)\n- npm\n\n### 1. Clone the Repository\n\n```bash\ngit clone https://github.com/umarSiddique010/resume-craft-react.git\n\ncd resume-craft-react\n```\n\n### 2. Install Dependencies\n\n```bash\nnpm install\n```\n\n### 3. Run Development Server\n\n```bash\nnpm run dev\n```\n\nOpen [http://localhost:5173](http://localhost:5173) to view the application.\n\n### 4. Running Tests\n\n```bash\n# Run full test suite\nnpm test\n\n# Run with interactive UI\nnpm run test:ui\n\n# Generate coverage report\nnpm run coverage\n```\n\n### 5. Lint \u0026 Format\n\n```bash\n# Check lint + format together\nnpm run check\n\n# Auto-fix lint issues\nnpm run lint:fix\n\n# Auto-format all files\nnpm run format\n```\n\n---\n\n## Project Structure\n\n```text\nsrc\n├── assets/                     # Images, icons, fonts\n├── components/\n│   ├── DisplayTemplate/       # Resume templates (Bold Accent, Standard, Classic, ATS)\n│   ├── HomePage/              # Main split layout\n│   ├── UserInput/             # Form sections (Personal, Skills, Projects, etc.)\n│   └── WelcomePage/           # Landing page\n├── context/\n│   └── UserInputContext/\n│       ├── InputFieldContext.jsx\n│       └── reducer/\n│           ├── resumeReducer.js\n│           ├── resumeTypes.js\n│           ├── resumeInitialState.js\n│           └── reducerInputUtils.js\n├── App.jsx                     # Application routing \u0026 Lazy load fallback UI\n├── main.jsx                    # React entry point\n└── setupTests.js               # Vitest\n```\n\n---\n\n## Contributing\n\nContributions are welcome. Here's how to get started:\n\n**1. Fork \u0026 Clone**\n\n```bash\ngit clone https://github.com/umarSiddique010/resume-craft-react.git\n\ncd resume-craft-react\n\nnpm install\n```\n\n**2. Create a Branch**\n\n```bash\ngit checkout -b feat/your-feature-name\n```\n\n**3. Make Your Changes**\n\n- Follow existing code style (ESLint + Prettier enforce this automatically on commit)\n- Add or update tests for any changed logic\n- Keep all state changes inside the reducer — no local state for resume data\n\n**4. Open a Pull Request**\n\n- Target the `main` branch\n- Write a clear title and description\n- Reference related issues with `Closes #issue-number`\n\n**Guidelines:** One feature or fix per PR. Don't remove existing tests. If adding a new template, follow the same props structure as existing ones.\n\n---\n\n\u003cdiv align=\"center\"\u003e\n\n### Developer \u0026 Maintainer\n\n**Md Umar Siddique**\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://www.umarsiddique.dev/\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Portfolio-umarsiddique.dev-000000?style=flat-square\u0026logo=googlechrome\u0026logoColor=white\" alt=\"Portfolio Website\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://www.linkedin.com/in/md-umar-siddique-1519b12a4/\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/LinkedIn-0077B5?style=flat-square\u0026logo=linkedin\u0026logoColor=white\" alt=\"LinkedIn\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/umarSiddique010\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/GitHub-181717?style=flat-square\u0026logo=github\u0026logoColor=white\" alt=\"GitHub\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://www.npmjs.com/~umarsiddique010\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/NPM-CB3837?style=flat-square\u0026logo=npm\u0026logoColor=white\" alt=\"NPM\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://dev.to/umarsiddique010\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Dev.to-0A0A0A?style=flat-square\u0026logo=dev.to\u0026logoColor=white\" alt=\"Dev.to\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"mailto:us70763@gmail.com\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Email-D14836?style=flat-square\u0026logo=gmail\u0026logoColor=white\" alt=\"Email\" /\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u0026copy; 2024 - Present. Released under the MIT License.\n\n\u003c/div\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fumarsiddique010%2Fresume-craft-react","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fumarsiddique010%2Fresume-craft-react","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fumarsiddique010%2Fresume-craft-react/lists"}