Building Portfoliable

An open-source portfolio builder in Markdown.

Building Portfoliable

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]

Screenshot of the portfolio home page on a mobile device using Portfoliable.

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.

Screenshot of a portfolio using Portfoliable.js.

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:

  1. Define the case metadata.
  2. Add or remove language variants, such as npm run add:language -- --code es --name Español --html-lang es-ES.
  3. Write the narrative in Markdown, with support for the full syntax.
  4. Preview the generated app locally with npm run portfoliable.
  5. 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.

flowchart TB subgraph CONTENT["Content"] direction TB cases["Markdown cases<br/>narrative, metadata, and languages"] assets["Case media<br/>images, audio, and video"] cases --> assets end subgraph INFRA["Infrastructure"] direction TB parser["Markdown parser<br/>rendering and validation"] normalized["Normalized data<br/>locale, order, and display options"] parser --> normalized end subgraph INTERFACE["Interface"] direction TB runtime["Runtime<br/>routes, locale, media, and diagnostics"] shell["App shell<br/>reading, navigation, and accessibility"] experience["Reading experience<br/>summary, table of contents, player, and controls"] runtime --> shell --> experience end cli["CLI + templates<br/>scaffolding, commands, and defaults"] valence["Valence<br/>components, tokens, and interaction patterns"] assets --> parser normalized --> runtime cli -. creates and configures .-> cases cli -. provides the foundation .-> runtime valence -. enables .-> shell valence -. standardizes .-> experience classDef content fill:#fff4df,stroke:#b7791f,color:#3d2b0b classDef infrastructure fill:#e8f1ff,stroke:#3b6ea8,color:#102a43 classDef interface fill:#e9f8ef,stroke:#2f855a,color:#143d27 classDef enabler fill:#f1e9ff,stroke:#805ad5,color:#2d1b4e class cases,assets content class parser,normalized,cli infrastructure class runtime,shell,experience interface class valence enabler

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.

Screenshot of a portfolio using Portfoliable.js with accessibility mode.

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

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


  1. Solo project: Lio Schimanko worked as the UX Designer and Developer. ↩︎

  2. Portfoliable evolved from a pre-release version to version 1.6.1, its latest release. ↩︎