The whole portfolio is created with Astro, using statically generated pages with a pinch of web components.
The whole tech stack:
If you are looking for the former Next.js-based app, it is archived in the
nextjs-deprecatedbranch.
If you are looking for the former Gatsby-based app, it is archived in the
gatsby-deprecatedbranch.
All displayed project content is powered by one YAML file where all the portfolio's projects are defined. The project description itself is transformed from Markdown written inside the YAML file into HTML on build time.
Astro automatically creates pages from each item in that file in the [slug].astro page template. Utilizing the get-projects.ts script which validates, transforms and enhances the data.
All project images live under src/_content/images and are automatically attached to each project based on the inclusion of the project's slug in their filenames during the above mentioned get-projects.ts pipeline.
During production build, the dominant color for each image is extracted with sharp, and then used for the initial loading state for each image. Astro generates all required image sizes for delivering responsible, responsive images to visitors.
The open source section at the bottom of the front page shows selected GitHub repositories, sourced from GitHub.
On build time, all my public repositories are fetched from GitHub, then filtered against the ones defined in repos.json, sorted by the last push date.
If you want to know how, have a look at the respective components:
On client-side, my current and, if known, my next physical location on a city level is fetched from my (private) lugara.me profile and displayed in the header.
If you want to know how, have a look at the respective components:
Includes a theme switcher which allows user to toggle between a light and a dark theme. Done without any dependencies:
- before document renders, the theme is set based on system preference or session storage user preference in the
<head> - the theme switch component then listens/dispatches a custom event to sync its UI
If you want to know how this works in detail, have a look at the respective files:
The Add to addressbook link in the footer automatically creates a downloadable vCard file on the client-side, based on data defined in src/_content/meta.json.
If you want to know how, have a look at the respective component:
To add a new project, run the following command. This adds a new item to the top of the projects.yml file, creating the title & slug from the argument:
bun run new -- "Hello"Then continue modifying the new entry in src/_content/projects.yml.
Finally, add as many images as needed with the file name format and put into src/_content/images/:
SLUG-01.png
SLUG-02.png
SLUG-03.png
...
This generates all required favicon sizes and puts them in public/ folder. All sourced from:
src/assets/favicon-512.pngsrc/assets/favicon.svg(handcrafted, adaptive based on OS theme)
Also creates a web manifest.
bun run faviconRequires Bun to be installed.
git clone git@github.com:kremalicious/portfolio.git
cd portfolio/
cp .env.example .env
vi .env
bun i
bun run devBiome is setup for all linting and formatting purposes:
bun run lintTest suite is setup with Bun Test Runner for unit tests.
To run all tests:
bun run testMost test files live beside the respective component. Testing setup, fixtures, and mocks can be found in the test/ folder.
Every branch or Pull Request is automatically deployed by Vercel with their GitHub integration, where the main branch is automatically aliased to matthiaskretschmann.com. A link to a preview deployment will appear under each Pull Request.
ยฉ Copyright 2025 Matthias Kretschmann
All images and projects are plain ol' copyright, most displayed projects are subject to the copyright of their respective owners.
Don't care if you fork & play with it, but you're not allowed to publish anything from it as a whole without my written permission. Also please be aware, the combination of typography, colors & layout makes up my brand identity. So please don't just clone everything, but rather do a remix!
All the rest, like all code and documentation, is under:
The MIT License
