"OS" Design System Blog Site

Building a portfolio site had been on my TODO list for a long time. It's one of those things you never have when you need it, and never have time for when you finally do. But between contracts, I finally found a window.
I'd also been inspired by recent a recent discovery of PostHog↗, which uses an OS style design system to structure their site. So with a bit of time on my hands, I thought why not try and make something similar for a portfolio site, something rather nostalgic...
What was so great about XP?
Bright blues, rolling green hills of Bliss, the chunky buttons, the 3D maze screensaver...
Let's be honest though, this was probably the operating system for the first PC we all ever owned, before we became jaded professionals. I wanted to, therefore, to bring back that iconic look. What better place to make a home for a blog and portfolio site!
Getting the styles right
This library was immensley helpful XP.css↗. Its pure CSS and did most of the heavy lifting here. When it comes to the icons, a lot of them are low res and you can tell!
OS as a website
We take for granted how websites are designed. Most sites fall neatly into a set of different, discrete, categories. Normally for good reason, there's no need for a newspaper's website to function like twitter or even to host games. With most websites, pages do not bleed state between each other.
To make the site feel like an OS, we need at minimum: persistent state, movable windows, and multiple “apps”
Requirements
In order to hamfist some operating system quirks into a site, I wanted to retain the following:
- App State - An operating system has a number of apps and an app state. The browser should allow visitors to open new "apps"
- SEO - The site should have multiple pages that are crawlable, therefore SSR + Hydration
Implementing App State
App state can be managed by a react context at the root level
<OSAppStateProvider initialState={props.initialState}><div className='hidden md:block'><WinXP /></div></OSAppStateProvider>
Routes
Each root can then pass initial state to this context, i.e. to pre open blog windows.
export default function BlogPage({ params }: BlogPageProps) {const post = getBlogPost(params.slug);if (!post) return notFound();const blogPostApp = getBlogPostAppConfig(post.title, post.slug)const initialState: State = {...emptyOSState,apps: [{...blogPostApp,appName: "BlogPost",appSlug: post.slug,id: '1',minimized: false,maximized: false,offset: { type: 'center' },},{...appSettings.MattBot,id: '2',minimized: false,maximized: false,offset: { type: 'right', right: 0, bottom: 0 },},],focusing: FOCUSING.WINDOW,icons: defaultIconState,selecting: false,powerState: POWER_STATE.START,};return <WinXPWithProvider initialState={initialState} />;}
How does it look?
Not too bad, quite happy with the look and feel. Judge for yourself!
Next steps
It would be cool if app state persisted in session/local storage and clicking to a new route simply opened a new app. At the moment we have a halfway house, where a route defines exactly what apps can be opened and the user can open more if they want to. Of course navigating to a different route will close your opened apps.

What About Mobile?
This was a tricky one, XP didn't even dream of mobile phones. I figured it was probably enough to include the iconic start bar.
And then shoehorn that into an android-esque looking OS. This way you still get the fun of an OS style app that looks semi-nostalgic.



Final Thoughts
This was pretty fun, and stretched my knowledge of SSR/Hydration + statement management. I've even been inspired to maybe have a go at recreating sheep.exe.↗
Watch this space.



