Every "portfolio builder" I tried had the same pitch: sign up, drag some blocks around, and then — right when you're happy with it — hit a paywall. Custom domain? Pro plan. Remove the watermark? Pro plan. Export your own HTML? Absolutely not, that's the whole business model.
And even if you pay, you're still locked into their hosting. Your portfolio — the thing meant to represent you — lives on someone else's infrastructure, behind someone else's uptime guarantees, subject to someone else's pricing changes next year.
That's the problem I wanted to kill: trials that convert to fees, lock-in disguised as convenience, and hosting you don't control for a site that's supposed to be the one asset you fully own.
The Core Decision: No Server, No Hosting, No Accounts
So the design constraint I set for myself from day one was blunt: everything runs client-side. No backend, no database, no login, no "your data lives on our servers." You open the page, build your portfolio in the browser, and click download. Out comes a ZIP file with clean, static HTML/CSS/JS — a real website you can drop into GitHub Pages, Netlify, Vercel, or a $2/month shared host. No dependency on my app ever staying online for your site to keep working.
This wasn't just a philosophical stance — it also happens to be the only architecture that fully removes the incentive to gate features behind a subscription. If there's no server cost per user, there's nothing to monetize by throttling you. The tool is either useful enough that people star it and use it, or it isn't. That's the whole business model, and I'm fine with that.
The Block Library
The builder works on a simple mental model: your portfolio is a stack of self-contained blocks, and you arrange, configure, and reorder them visually. The usual suspects are there — Hero, About, Projects, Skills, Contact, Footer — each with enough configuration to not look like a template clone.
The one I'm most proud of is the GitHub Feed block. Point it at your username and it pulls your pinned repos (or most recently active ones) directly at build time, rendering them as project cards with language, stars, and description — no manual copy-pasting your project list every time you ship something new. For a lot of developers, their GitHub activity is their portfolio; this block just stops pretending otherwise.
Under the Hood: Wizard → Schema → HTML → ZIP
The architecture is intentionally boring, because boring is reliable:
The wizard collects a JSON schema. Every choice you make in the UI — block order, content, colors, fonts — gets serialized into a single JSON object. Nothing is hidden in component state that can't be reconstructed; the schema is the source of truth for your entire site.
builder.js compiles the schema into HTML/CSS strings. No frameworks bundled into the output, no virtual DOM shipped to your visitors. Each block type has a corresponding template function that takes its slice of the schema and returns plain markup and scoped styles. The output is what you'd write by hand if you had the patience.
JSZip bundles the result into a downloadable archive. HTML, CSS, any assets, all packaged into a proper folder structure — ready to unzip and deploy, not a single unstyled file you have to untangle.
FileSaver.js triggers the actual download. The moment you click "Export," the browser hands you a .zip and the tool's job is done. You now own a static site with zero runtime dependency on me.
The nice side effect of this pipeline: since the schema is just JSON, saving and loading a project locally, or eventually syncing it, is trivial — it's all just serialization, no format lock-in.
What's Next
A few things on the roadmap:
PDF export — same schema, different renderer, so you can hand a recruiter a resume-style PDF built from the same content you used for your site.
More blocks — a Spotify Now Playing block for people who want a bit of personality on their site, and a blog RSS block so your latest posts show up automatically instead of going stale the day after you publish.
The goal is the same as it's always been: more ways to represent yourself accurately, none of which require anyone's permission or subscription to keep working.
Try It https://portfoliogen-cyan.vercel.app/
The whole thing is open source. If you build a portfolio with it, I'd genuinely like to see it. If something breaks, or a block you want doesn't exist yet, open an issue — and if it's useful to you, a star helps more than you'd think for a solo project like this.
Top comments (0)