This is a simple portfolio page heavily inspired by shi-gg/portfolio. At least a little bit of knowledge on svelte/html/typescript is required if you want to do extra configuration such as adding extra icons.
Essentially all configuration is managed through the config object in src/lib/config.ts
| Field | Type | Required | Description |
|---|---|---|---|
name |
string |
Yes | Your display name |
title |
string |
No | Custom page title (defaults to name if omitted) |
shortDescription |
string |
No | Brief bio shown in embeds and meta tags |
pronouns |
string |
Yes | Your preferred pronouns |
timezone |
number |
Yes | Hours offset from UTC (e.g., -5 for EST, 1 for CET) |
primaryColor |
string |
Yes | Theme color in any CSS format (#b49068, rgb(180, 144, 104), etc.) |
| Field | Type | Required | Description |
|---|---|---|---|
profilePicture.url |
string |
Yes* | Path or URL to your profile picture (e.g., /pfp.jpg) |
profilePicture.alt |
string |
Yes* | Alt text describing the image |
profilePicture.credits.name |
string |
No | Credit attribution name |
profilePicture.credits.url |
string |
No | Link to credit source or creator |
*The entire profilePicture object is optional.
Array of links. Each entry:
| Field | Type | Required | Description |
|---|---|---|---|
id |
string |
Yes | Unique identifier (determines icon: github, gitea, x, lastfm, email) |
label |
string |
Yes | Display label (e.g., "GitHub") |
url |
string |
Yes | Full URL or mailto: link |
display |
string |
Yes | Username or display text shown to users |
Array of project showcases. Each entry:
| Field | Type | Required | Description |
|---|---|---|---|
id |
string |
Yes | Unique identifier |
title |
string |
Yes | Project name |
description |
string |
Yes | Brief project description |
gitProvider |
string |
No | Git provider for icon (github, gitea, etc.) |
gitUrl |
string |
No | Repository URL |
liveUrl |
string |
No | Production/demo URL |
Your bio/about section is managed in src/lib/AboutMe.svelte as a separate component to allow full customization.
Example from the default component:
<script lang="ts">
const startYear = 2022;
const yearsCoding = new Date().getFullYear() - startYear;
</script>
<p>I've been coding for around {yearsCoding} years...</p>
Edit this file to write your own introduction, experiences, interests, or any other content you want to display.
let config: Configuration = {
name: 'whoswhip',
shortDescription: "I'm a full stack developer, mainly working with C#.",
profilePicture: {
url: '/pfp.jpg',
alt: 'Picture of an orange sunset',
credits: {
name: 'whoswhip',
url: 'https://example.com'
}
},
primaryColor: '#b49068',
pronouns: 'He/Him',
timezone: -5,
links: [
{
id: 'github',
label: 'Github',
url: 'https://github.com/whoswhip',
display: 'whoswhip'
}
],
projects: [
{
id: 'sharpbin',
title: 'Sharpbin',
description: 'A pastebin-esque website with syntax highlighting.',
gitProvider: 'github',
gitUrl: 'https://github.com/whoswhip/sharpbin',
liveUrl: 'https://sharpbin.cc'
}
]
};
git clone https://git.whoswhip.dev/whoswhip/portfolio.git
cd portfolio
bun install
bun run dev
The site will be available at http://localhost:5173.
To test a production build locally:
bun run build
bun run preview
docker compose up -d
The portfolio will be accessible at http://localhost:3000.
Edit docker-compose.yml or use environment variables:
PORT=8080 docker compose up -d
docker compose up -d --build
For manual deployment to any static hosting provider:
bun install
bun run build
.svelte-kit/output folder to your hosting provider:# Build the project
bun run build
# Copy to web root
sudo cp -r .svelte-kit/output/* /var/www/html/
# Configure Nginx (example)
sudo cp nginx.conf /etc/nginx/sites-available/portfolio
sudo ln -s /etc/nginx/sites-available/portfolio /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx