Skip to content

Repository files navigation

Web OS Portfolio

Next.js React TypeScript Tailwind CSS

A portfolio designed like a desktop operating system.

Local Configuration

For local development, copy .env.example to .env.local and set DISCORD_WEBHOOK_URL to a newly generated Discord webhook URL. For Docker deployment, create .env.discord with the same variable. Do not commit either file or expose the webhook URL in client-side code.

Docker Compose loads .env.discord into the portfolio-os container automatically when you run docker compose up --build.

Contact submissions are rate-limited server-side to 3 accepted messages per client IP every 10 minutes. The Discord webhook URL is never sent to the browser.

If a webhook is ever exposed, revoke it immediately and follow the history-cleanup steps in SECURITY.md. A new environment variable alone does not invalidate a previously leaked webhook.

I wanted to build something more interactive than a traditional scrolling portfolio.

So I built a browser-based desktop environment where projects, certifications, media, and personal information live inside an interactive OS-style interface.

The interesting part isn't just the UI — it's the architecture behind it.


What You Can Do

  • Interact with a desktop-style environment
  • Open folders and applications
  • Move, minimize, maximize, and restore windows
  • Use a persistent sticky note
  • Create and manage files within the browser
  • View images and videos
  • Open certifications through a custom PDF viewer
  • Send messages through the contact application
  • Interact with the trash and file system
  • Persist application state across sessions

System Architecture

The application is structured around a small set of clearly separated layers.

                         ┌─────────────────────┐
                         │     app/page.tsx    │
                         │      App Shell      │
                         └──────────┬──────────┘
                                    │
                                    ▼
                         ┌─────────────────────┐
                         │   Desktop Engine    │
                         │ components/Desktop  │
                         └──────────┬──────────┘
                                    │
                                    ▼
                         ┌─────────────────────┐
                         │    Global State     │
                         │   context/App.tsx   │
                         └──────┬───────┬──────┘
                                │       │
                 ┌──────────────┘       └──────────────┐
                 ▼                                     ▼
        ┌─────────────────┐                   ┌─────────────────┐
        │ Window System   │                   │ Persistence     │
        │ components/*   │                   │ localStorage    │
        │                 │                   │ IndexedDB       │
        └────────┬────────┘                   └─────────────────┘
                 │
                 ▼
        ┌─────────────────┐
        │   API Layer     │
        │   app/api/*     │
        └────────┬────────┘
                 │
                 ▼
        ┌─────────────────┐
        │ External        │
        │ Integrations    │
        │ Discord Webhook │
        └─────────────────┘

Architecture Layers

1. App Shell

app/page.tsx

The entry point of the application.

Responsible for mounting the desktop environment, window layer, and taskbar.


2. Global State

context/App.tsx

Acts as the shared state layer for the desktop.

It manages things such as:

  • Open windows
  • Window state
  • Desktop data
  • User preferences
  • File and folder state
  • Persistence

The goal is to keep state that needs to be shared out of individual UI components.


3. Desktop Engine

components/Desktop/

Responsible for the behavior of the desktop itself.

This includes:

  • Desktop icons
  • Drag and drop
  • Launching applications
  • File interactions
  • Desktop layout
  • Window interactions

4. Window System

components/*Window

Each application is isolated into its own window component.

Examples include:

  • Code Editor
  • File Explorer
  • Media Viewer
  • PDF Viewer
  • Sticky Notes
  • Trash

This keeps individual application logic separate while allowing the global window manager to control their lifecycle.


5. API Layer

app/api/*

Server-side routes handle functionality that should not run directly in the browser.

For example:

Contact Form
     │
     ▼
/api/contact
     │
     ▼
Discord Webhook

This keeps the webhook integration away from the client-side application.


Browser Persistence

One of the design decisions I focused on was choosing the right storage mechanism for different types of data.

localStorage

Used for lightweight persistent data:

  • UI preferences
  • Wallpaper state
  • Folder metadata
  • Document information
  • Sticky notes

IndexedDB

Used for heavier browser-side data:

  • Images
  • Videos
  • Uploaded media blobs

The idea is simple:

Lightweight data  → localStorage
Heavy media       → IndexedDB

This avoids putting large media objects into localStorage while keeping frequently accessed application state simple.


Window Management

The desktop uses a shared window management system rather than treating each application as an isolated page.

The window manager handles:

  • Opening windows
  • Closing windows
  • Minimize / restore
  • Maximize
  • Active window tracking
  • Z-index / focus management
  • Taskbar state
  • Window positioning

Conceptually:

                Window Manager
                      │
       ┌──────────────┼──────────────┐
       ▼              ▼              ▼
   Code Editor    File Explorer   Media Viewer
       │              │              │
       └──────────────┼──────────────┘
                      ▼
                 Shared State

This allows multiple applications to behave consistently without duplicating window-management logic.


Key Engineering Decisions

Client / Server Separation

Interactive desktop functionality runs on the client while server-side integrations are handled through Next.js API routes.

Component Isolation

Individual applications are separated into their own components instead of placing the entire desktop inside one large component.

Centralized State

State that affects multiple parts of the application is managed centrally rather than being duplicated across components.

Storage by Data Type

Different browser storage technologies are used depending on the size and purpose of the data.

Extendable Architecture

New applications can be added as independent window components without having to redesign the entire desktop.


Tech Stack

Framework & Language

Next.js React TypeScript

Styling

Tailwind CSS

UI & Animation

Framer Motion Radix UI Lucide Lottie

Media

Cloudinary


Project Structure

.
├── app/
│   ├── api/
│   │   ├── contact/
│   │   └── certifications/
│   │
│   └── page.tsx
│
├── components/
│   ├── Desktop/
│   ├── *Window/
│   └── ...
│
├── context/
│   └── App.tsx
│
├── lib/
│   └── certifications.ts
│
└── public/

The structure keeps application logic, shared state, server-side routes, and UI surfaces separated.


Running Locally

Clone the repository:

git clone https://github.com/Sahal054/MyWebiste.git
cd MyWebiste

Install dependencies:

npm install

Start the development server:

npm run dev

Open:

http://localhost:3000

Production Build

npm run build
npm run start

Configuration

Before deploying, configure:

Contact API

Set the Discord webhook through an environment variable rather than committing it to the repository.

Certifications

Update:

lib/certifications.ts

with the certification records you want to display.


Screenshots

Desktop

image

Window Management

image

File Explorer / Applications

image

👨‍💻 About Me

I'm Sahal, a Software Engineer interested in backend systems, APIs, automation, and building reliable software.

I enjoy learning by building things — especially projects where I have to figure out the architecture rather than simply follow a tutorial.

📧 Email: sahalmsachu@gmail.com
💼 LinkedIn: https://linkedin.com/in/Sahal054
💻 GitHub: https://github.com/Sahal054

About

Interactive desktop portfolio and web OS built with Next.js, React, TypeScript, and Framer Motion. Features custom window management, state management, drag-and-drop, IndexedDB, localStorage, and API integration.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages