A terminal-inspired portfolio and blog built with SvelteKit. The project combines a retro command-line UI with Markdown and .svx blog support, interactive modal panels, customizable themes, and a virtual filesystem.
Visit the live site at morisjohnson.in.
v1.3.2vim command to the terminal, providing a simple text editor interface for file editing.clear command would fail to properly clear the terminal output in some instances.clear command that caused the subsequent command prompt to become uneditable.cd and ls commands with a configurable directory structure.history to view past commands with timestamps. Use ArrowUp and ArrowDown keys to navigate through command history.| Command | Description |
|---|---|
help |
Show all available commands with descriptions |
ls |
List files and directories in the current path |
cd <path> |
Change directory (supports .. for parent) |
whoami |
Display current username |
username <name> |
Change your username |
clear |
Clear the terminal output |
history |
Show command history with timestamps |
rm |
Easter egg |
vim |
View files in a modal interface |
pwd |
Show current working directory |
echo |
Echo input text back to the terminal |
date |
Display current date and time |
.md format with frontmatter metadata..svx files with Svelte integration.static/blogs/sample.md.src/lib/data/color_schemes.json..svx component with timeline-based resume..svx page with contact links and social information.help command displays available terminal commands.@sveltejs/adapter-static for easy deployment.marked with marked-shiki for syntax highlighting.gray-matter for parsing metadata.terminal-portfolio/
├── src/
│ ├── lib/
│ │ ├── components/
│ │ │ ├── blog/ # Blog rendering components
│ │ │ ├── home/ # Homepage components (Avatar, Title, etc.)
│ │ │ ├── modals/ # Modal dialog components
│ │ │ ├── terminal/ # Terminal UI components
│ │ │ └── ui/ # Reusable UI primitives (Bits UI)
│ │ ├── data/
│ │ │ ├── color_schemes.json # Terminal color themes
│ │ │ ├── commands.json # Command definitions
│ │ │ ├── filesystem.json # Virtual filesystem structure
│ │ │ └── help.json # Help text for commands
│ │ ├── docs/
│ │ │ ├── about.svx # About page content
│ │ │ └── contact.svx # Contact page content
│ │ ├── js/
│ │ │ ├── constants.ts # Application state and stores
│ │ │ ├── displayinfo.ts # System info utilities
│ │ │ ├── markdown.ts # Markdown parsing & highlighting
│ │ │ └── parser/ # Command parser logic
│ │ └── utils/ # Utility functions
│ ├── routes/
│ │ ├── +page.svelte # Homepage
│ │ └── +layout.svelte # Root layout
│ └── css/
│ ├── global.css # Global styles and CSS variables
│ ├── home.css # Homepage-specific styles
│ ├── markdown.css # Markdown content styling
│ ├── modal.css # Modal styles
│ └── terminal.css # Terminal component styles
├── static/
│ ├── blogs/ # Blog posts directory
│ │ └── sample.md # Example blog post
│ └── images/ # Static assets
├── docs/
│ └── website.gif # Homepage animation
├── package.json
├── svelte.config.ts
├── vite.config.js
└── README.md
Create a new file in static/blogs/ with either .md or .svx extension.
Add frontmatter metadata at the top of the file:
---
title: "Your Post Title"
date: 2025-10-05
author: "Your Name"
tags: [tag1, tag2]
draft: false
description: "Brief description"
slug: your-post-slug
layout: post
toc: false
---
Write your content in Markdown (for .md) or use Svelte components (for .svx).
The blog post will be accessible via the terminal's ls command in the ~/home/blogs/ directory.
Edit src/lib/data/commands.json:
{
"yourcommand": {
"returns": "text|component|empty",
"componentName": "ComponentName",
"argRegex": "yourcommand\\s+(.*)",
"defaultArg": "default",
"updateStore": "storeName",
"storeValue": true,
"readStore": "storeName",
"textContent": "Output text",
"parameters": { "key": "value" },
"messageTemplate": "Message with {arg}"
}
}
returns: Determines output type (text for plain text, component for Svelte component, empty for no output).componentName: The Svelte component to render (must be imported in Terminal.svelte).argRegex: Regex pattern to extract arguments from the command.updateStore: Store to update when command runs.parameters: Props passed to the component.Edit src/lib/data/color_schemes.json and follow the existing structure. Each theme needs:
background, foreground, selectionBackground, cursorColor.Themes are automatically loaded and appear in the theme selector.
Edit src/lib/data/filesystem.json to change what ls and cd display:
{
"~/home": {
"about.md": {
"type": "modal",
"doc": "about",
"docPath": "/src/lib/docs/about.svx"
},
"blogs/": {
"type": "directory"
}
},
"~/home/blogs": {
"my-post.md": {
"type": "modal",
"doc": "blogs/my-post.md"
},
"..": {
"type": "directory",
"target": "~/home"
}
}
}
type: "directory" - Shows as a folder in ls.type: "modal" - Clickable entry that opens a modal with content.type: "link" - External hyperlink... entries define parent directory navigation.The command parser lives in src/lib/js/parser/. Key files:
parser.ts - Main parser logic, command validation, cd/ls implementation.terminal.ts - Terminal event handling and command history management.# Install dependencies
npm install
# Start development server
npm run dev
# Build for production
npm run build
# Preview production build
npm run preview
| Script | Description |
|---|---|
npm run dev |
Start Vite dev server at http://localhost:5173 |
npm run build |
Generate static site in build/ |
npm run preview |
Serve the built site locally |
npm run check |
Run Svelte type checking |
npm run lint |
Lint code with ESLint and Prettier |
npm run format |
Format all files with Prettier |
The project outputs a fully static site. Deploy the build/ directory to any static hosting service:
npm run build, output directory build.build/ to gh-pages branch.build/ with any web server (nginx, Apache, Caddy).Feedback and contributions are welcome. Submit pull requests or suggest improvements for:
MIT - see LICENSE for details.