Windows 95-inspired personal portfolio built with React, Vite, Tailwind, Framer Motion, and Zustand.
Live site: https://tonyos.vercel.app/
TonyOS presents portfolio content as a retro desktop operating system:
- draggable desktop icons
- Win95-style window manager and taskbar
- file explorer metaphor for projects and content
- terminal app with portfolio-aware commands
- public Spotify playlist explorer rendered like folders and files
The app is intentionally nostalgic in presentation, but the implementation is modern React.
- Windows 95 desktop shell with boot sequence
- draggable desktop icons
- resizable, focusable, minimizable, maximizable windows
- taskbar with per-window tabs and icons
- terminal app backed by a custom command parser
- markdown/text/project viewers
- recruiter-friendly traditional portfolio view
- Spotify playlist explorer with cached public playlist data
- React 19
- TypeScript
- Vite
- Tailwind CSS
- Framer Motion
- Zustand
src/
components/
desktop/ Desktop shell and boot flow
windows/ Window frame and chrome
taskbar/ Taskbar and clock
terminal/ Terminal app
explorer/ Filesystem explorer
spotify/ Win95 Spotify playlist explorer UI
apps/ Portfolio app windows
data/ Portfolio content and mock filesystem
store/ Zustand state stores
types/ Shared TypeScript types
utils/ Window, terminal, and filesystem helpers
public/
spotify-playlists.json Cached Spotify playlist snapshot served to visitors
scripts/
sync-spotify-playlists.mjs Exports public playlist snapshot using your user token
Install dependencies:
npm installStart the dev server:
npm run devBuild for production:
npm run buildPreview the production build locally:
npm run previewVisitors do not authenticate with Spotify.
Instead, the site reads from a cached snapshot file:
That snapshot is generated from your Spotify account by running:
npm run sync:spotifyThe sync script:
- fetches your own playlists via your user token
- filters to your public playlists
- fetches playlist tracks
- writes a static JSON snapshot for the frontend
This avoids depending on brittle public Spotify Web API access for anonymous visitors.
Create a .env file in the repo root.
Required:
SPOTIFY_CLIENT_ID=your_spotify_app_client_id
SPOTIFY_CLIENT_SECRET=your_spotify_app_client_secret
SPOTIFY_USER_ID=your_spotify_user_id
SPOTIFY_REFRESH_TOKEN=your_spotify_user_refresh_tokenOptional for one-off syncs:
SPOTIFY_ACCESS_TOKEN=temporary_user_access_tokenReference template:
When your playlists change:
- refresh the snapshot
npm run sync:spotify- redeploy
vercel deploy --prod --yesThis repo is linked to Vercel.
Deploy the current state:
vercel deploy --prod --yesCurrent deployment flow:
- update code or content
- run
npm run sync:spotifyif playlist data changed - run
npm run buildif you want a local verification step - deploy with Vercel
SPOTIFY_ACCESS_TOKENis short-lived and should not be relied on long term.SPOTIFY_REFRESH_TOKENis the durable value used to generate fresh access tokens for the sync script.- The frontend never exposes
SPOTIFY_CLIENT_SECRET. - Browser visitors only consume static playlist JSON.