Inspiration

Building a personal portfolio feels like a chore. The standard workflow was painful: finding raw templates, digging into the code to manually edit text, fixing broken styles, and wrestling with manual deployments. What should have taken minutes ends up consuming days.

I wanted to change that. I envisioned a tool that transforms the data you already have - your LinkedIn profile, Resume, and GitHub - into a polished, deployable website in seconds.

The "aha!" moment came when a batchmate impressed their interviewers using a portfolio that featured a creative "Chat with me" section.

Midway through, I realized users also needed a better way to manage resume versions. Thanks to Kiro's Spec-Driven Development, what would have been a massive feature creep - a fully functional Resume Builder - became a quick add-on that I completed in just 3-4 hours.

What it does

Portfolioly helps developers stand out by transforming their existing data into a deployable personal website. We’ve currently got 500+ registered users from Reddit posts and the a recent ProductHunt launch.

  • Two-Click Portfolio Creation: You upload a Resume PDF, connect GitHub, or import a LinkedIn PDF. We extract your projects and skills to generate a site instantly.
  • AI-twin chat: The portfolio acts as a ChatGPT-like assistant that answers questions about your specific experience.
  • Resume Builder: A drag-and-drop editor to create ATS-friendly resumes from your LinkedIn/GitHub profile.
  • One-Click Deploy: We integrated Vercel so you can deploy your site to a live URL without touching a CLI.

How we built it

I didn't start by coding; I started by chatting with Kiro’s Spec Agent to treat my spec file as a strict blueprint. I spent a lot of time editing the spec file and making sure it adheres to all the mentioned requirements.

Once the spec was locked, Kiro helped me scaffold a Yarn Workspaces Monorepo:

  • Frontend (apps/main): Built with Next.js 15 (using the new Turbopack and App Router), React 19, Tailwind CSS v4, Shadcn and MagicUI
  • Backend (backend/): A FastAPI (Python 3.11+) service using Pydantic for validation and Upstash Redis for rate limiting.
  • Shared Packages: We created portfolioly-schema to share Zod schemas across the frontend and template-components to share React UI components to make sure we can re-use the code for live preview and portfolio deployments.

The Resume Builder is the highlight of the Kiro workflow. I described the requirements for ResumeEditor.tsx and the useResumeEditor hook (including undo/redo states) to Kiro, and it generated the complex logic for SectionReorder.tsx and the live preview component in a single afternoon.

Challenges we ran into

  • LinkedIn has no public API for profiles
    • Solution: We utilized the user's LinkedIn PDF export. I created a custom Python package (packages/pdf_parser) that parses the PDF into structured JSON in milliseconds using only the PDF heuristics and formatting.
  • Syncing Types Across Languages: Maintaining type safety between a TypeScript frontend and a Python backend is usually brittle.
    • Solution: We adopted a Schema-First pattern. We defined our data structures in portfolioly-schema, ensuring our Zod validators on the client always match the Pydantic models on the backend.
  • Editor vs. Live Consistency: I wanted the editor preview to look exactly like the deployed site without duplicating code.
    • Solution: We architected a shared library, packages/template-components. This allows the deployed Next.js template to consume the exact same React components used in the editor, ensuring 100% visual fidelity.
  • Complex Deployment: Deploying a monorepo with distinct frontend and backend services is a nightmare for non-tech users.
    • Solution: I consulted Kiro on infrastructure strategy. We also built a "One-Click Deploy" flow that triggers a Vercel deployment of the apps/template workspace, injecting the user's data automatically.

Accomplishments that we're proud of

  • 500+ Registered Users: Validating the idea with real users immediately. Got the users' just from reddit posts and ProductHunt launch,
  • One-Click Vercel Deploy: Abstracting away the complex dev-ops so a user can go from PDF to Live Website in 2 minutes.
  • Cross-Platform Data Import: Seamlessly ingesting data from LinkedIn PDFs, GitHub Repos, and Resume PDFs using our custom ResumeTransformer utilities.
  • Rate limiting: As a lot of the API endpoints had to be public (unauthenticated) to serve data, rate limiting was especially important.

What we learned

  • Spec-Driven Development I learned the workflow that made me at least 5x productive with Kiro. For each new feature I am starting, I initially spend time gathering and thinking about all the requirements. Then I have Kiro generate spec files. I spend a lot of time editing and making sure these spec files are adhering to my requirements properly, and then Kiro almost always is able to one-shot almost completely working feature.
  • Working with Next.js and FastAPI backend in monorepo: I learned the intricacies of coupling Next.js 15 (Turbopack) with a Python backend within a monorepo structure.
  • Best practices for production apps I implemented many best practices for deploying the app like IP based rate limits, user based limits and ensuring all operations and endpoints are completely asynchronous.
  • GitHub Actions for auto-syncing: While for development, Portfolioly is completely a mono-repo, however for deployment, we required a separate template repo. I made a GitHub action to automatically sync up this repo with the main repo automatically.
  • Agentic Workflow: Moving from "writing code" to "orchestrating agent" allowed me to build a full-stack SaaS solo.

What's next for Portfolioly - Build personal website/resume from LinkedIn

  • Resume Versioning: I want to use Kiro to add deep version control, so users can maintain different resumes for different job roles.
  • Template Marketplace: Opening up the template-components package so the community can contribute their own designs.

Built With

Share this project:

Updates