Building Portfoliable
An open-source portfolio builder in Markdown.
Portfoliable.js is an open-source JavaScript portfolio builder for people who need to present complex work without building a publishing system, using only the npm create portfoliable@latest command in their CLI.[1][2]
The opportunity
While tools such as Behance and Wix prioritize publishing pages, Portfoliable.js treats a case study as a complete narrative experience: each project combines versioned Markdown and localized metadata to generate a structured, responsive, and accessible reading experience with support for multiple languages, media, sharing, and future edits.

From a blank folder to a publishable case
The fastest path is deliberately practical: install Portfoliable through the CLI:
npm create portfoliable@latest my-portfolio
cd my-portfolio
npm run portfoliable-create-case -- --name "My first case"
After this command, Portfoliable is installed, the first case is added, and the workflow stays close to how a real team works:
- Define the case metadata.
- Add or remove language variants, such as
npm run add:language -- --code es --name Español --html-lang es-ES. - Write the narrative in Markdown, with support for the full syntax.
- Preview the generated app locally with
npm run portfoliable. - Validate the content and build when it is ready to publish.
The CLI creates the repeatable work, while the author focuses on writing content to share with recruiters or stakeholders. The case configuration remains explicit and easy to review, for example:
{
"id": "checkout-revamp",
"title": {
"en": "Checkout Revamp",
"pt": "Redesign do checkout"
},
"showSummary": true,
"showToc": true,
"showNavigator": true
}
This creates a useful boundary between content and behavior: Markdown explains what happened, while configuration declares how the case should be presented, with or without headings, covers, audio players, and other customization options.
A small system with clear boundaries
Under the interface, Portfoliable is organized around a few focused layers:
| Layer | Responsibility |
|---|---|
| Case Markdown | Narrative, localized sections, and case-specific metadata |
| Runtime | Routing, parsing, reading, media, sharing, and validation |
| CLI and templates | Scaffolding, repeatable commands, and safe defaults |
| Valence Design System | Reusable components, tokens, and accessible interaction patterns |
Valence appears here as an enabling layer, not the protagonist: it gives the runtime a consistent visual and interaction vocabulary. This allows summaries, headers, thumbnails, players, and controls to evolve without each case inventing its own interface.
Localization is also part of the content model rather than a second application. A single file keeps parallel sections while the parser selects the correct version at runtime:
<<-- lang: [language_code] -->>
## The outcome
The new flow reduced friction and made the decision easier to explain.
<<-- lang: [language_code] -->>
## O resultado
O novo fluxo reduziu o atrito e tornou a decisão mais fácil de explicar.
Designed for reading, not just browsing
The reading experience is where the technical decisions become visible. A case can offer a summary for someone who has thirty seconds, a table of contents for a deeper review, and navigation controls for moving from one project to another. Localized routes and metadata keep the same work readable in different languages without duplicating an entire application.
Accessibility is treated as a product requirement: contrast and motion preferences, keyboard-operable controls, a comfortable reading width, semantic headings, and explicit labels are part of the runtime contract.

For a technical reader, the key point is that these features compose rather than compete with one another:
const caseView = {
content: parseMarkdown(caseFile),
locale: resolveLocale(requestedLanguage),
reader: {
summary: true,
tableOfContents: true,
navigator: true
}
};
This composition keeps the experience consistent across cases without preventing each project from telling a different story.
What I learned building it
The most useful decision was to keep the authoring surface small and let the runtime handle consistency. Markdown is approachable, Git makes changes reviewable, and a structured configuration block stores what should not be hidden in prose.
Portfoliable has opinions about structure, naming, and defaults; it is not trying to be a universal CMS. In return, a new case can be created quickly, content can be localized without a second codebase, and the same reading patterns can be improved centrally.
The result
- A faster start: one command creates the project and its conventions.
- A stronger narrative: cases are structured for quick reading and deeper exploration.
- A sustainable implementation: runtime, templates, and documentation have clear responsibilities.
- A more inclusive default: language, accessibility, and reading comfort are considered from the first render.
Portfoliable is both a tool for publishing work and a case study in product thinking applied to infrastructure. It turns a portfolio from a standalone page into a small, versioned product—without requiring the author to become a full-time webmaster.
Explore the Portfoliable website or the open-source repository.
Next steps
- Evaluate agentic navigation: explore how AI agents can navigate, understand, and recommend case studies without compromising the clarity of the human reading experience.
- Review bundle and asset weights: audit JavaScript, CSS, images, fonts, and media to identify what can be reduced, deferred, or loaded on demand.
- Keep the runtime lighter: measure performance on slower devices and networks, then simplify dependencies and interaction layers where possible.
- Improve validation and observability: add clearer checks for localized content, accessibility, broken links, and performance regressions.