Creating a Web Desktop in Vue.js has never been easier
Spend five minutes on GitHub looking for “developer portfolio,” and you will find hundreds of “Web OS” templates. They mimic Windows…
Creating a Web Desktop in Vue.js has never been easier

Win95 theme for Open Web Desktop
Spend five minutes on GitHub looking for “developer portfolio,” and you will find hundreds of “Web OS” templates. They mimic Windows, macOS, or custom sci-fi terminals, complete with dragging windows, retro terminals, and interactive widgets.
As developers, we love them. They make a great first impression.
So, you fork one of these templates, clone it locally, and open the code. That’s when the disappointment sets in.
Most of these repositories are monolithic. The application logic, CSS styles, window coordinates, taskbar mechanics, and state management are tangled together in a single folder. If you want to replace their custom music player with your own, or swap out their CSS theme, you end up hacking through thousands of lines of spaghetti code.
You haven’t cloned a framework; you’ve cloned a maintenance headache.
If we want to build web-based desktops, we need to treat them like professional software. We need a modular framework, not a template. That is why we built Open Web Desktop (OWD).
—
The Monolith Problem: Why Portfolio Templates Rot
When you build on a traditional portfolio template, you face three primary architectural bottlenecks:
- Tight Coupling: The window manager (handling dragging, resizing, z-indexing, snapping, and workspaces) is hardcoded directly alongside individual app views. Changing how a window behaves means changing the app itself.
- Brittle Customization: Adding a third-party app or switching design systems requires copying files directly into core directories, immediately breaking your git upstream and making updates impossible.
- Impermanent State: Most templates rely on simple Vue or React component states wrapped in
<KeepAlive>containers. Minimize three windows, and your browser’s DOM is carrying heavy, inactive nodes, degrading rendering performance.
—
The OWD Architecture: A True Desktop Chassis
Open Web Desktop is designed as a modular framework built on top of Nuxt 4 and Vue 3. It separates the browser operating system into clean, self-contained layers:
┌───────────────────────────────┐
│ desktop.config.ts │
│ (Declarative Registry) │
└───────────────┬───────────────┘
│
┌─────────────────────┼─────────────────────┐
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Theme │ │ Modules │ │ Apps │
│ (Window Chrome, │ │ (File System, │ │ (Vue/TS code, │
│ Taskbar, Dock) │ │ State Persist) │ │ Pinia state) │
│ │ │ │ │ │
└─────────────────┘ └─────────────────┘ └─────────────────┘
The core kernel (@owdproject/core) acts as the engine chassis. It handles:
- Z-Index Layering: Automatically promoting focused windows to the front.
- Multitasking Workspaces: Supporting multiple virtual desktops with dynamic window migration.
- Aero Snaps & Edge Dragging: Standard operating system window layouts out of the box.
- State Encapsulation: Giving every application a dedicated Pinia store. When a window is minimized or closed, the DOM is cleanly unmounted to free up memory, while the active data remains safe in Pinia.
Devs do not touch the kernel. Instead, they write clean, isolated modules.
—
Zero Configuration Fatigue: The Go-Powered CLI
A modular framework is only as good as its build tools. To prevent developers from wasting time configuring complex monorepos, symlinks, or heavy bundlers, OWD features a custom CLI and desktop control panel written entirely in Go.

Control Panel of your Vue.js Web Desktop
By leveraging Go’s raw speed and single-binary efficiency, you can spin up the development environment, link new applications, and scaffold custom themes in milliseconds. Running pnpm desktop fires up a lightning-fast orchestrator that acts as your command center, bridging the gap between your local terminal and your browser-based OS. No boilerplate, no configuration fatigue—just pure development speed.
—
Decoupled Apps and Pluggable Persistence
Because OWD separates the visual windows from the underlying state, state persistence is completely pluggable and protocol-agnostic.
By default, you can include @owdproject/module-persistence to save and restore app states in local IndexedDB. But because the state engine is decoupled, you can script custom modules to sync your desktop workspaces to any endpoint: a standard REST database, a GraphQL server, or a decentralized repository like the AT Protocol (Bluesky ecosystem).
If you build a notes app or a retro game player for OWD, your component looks like standard Vue 3:
<template>
<DesktopWindow :content=”{ padded: true }”>
<div class=”p-4 text-white”>
<h1>Hello from an isolated OWD App!</h1>
<! — The kernel handles the window frame, drag handles, and close buttons automatically →
</div>
</DesktopWindow>
</template>
—
Join the Community: Steer the Roadmap
Open Web Desktop is built for developers who want a beautiful, professional, and maintainable desktop environment. Whether you are building an interactive next-gen portfolio, a personal digital garden, or a window-based SaaS micro-frontend, this framework provides the architecture you need.
Rather than locking down a fixed feature roadmap, we are dedicating our current focus to improving the Developer Experience and build tools. We want to grow a core community of builders who will help decide what features we should prioritize next.
If you are a Vue/Nuxt developer:
- Create a new Vue-based web desktop with
npm create owd@latest. - Run the Control Panel (
pnpm desktop) to manage local packages. - Build your own apps, design unique themes, and help us steer the future of the framework.
👉 GitHub: owdproject/client 👉 Documentation: owdproject.org
메타데이터
- post_id
- 79e8048643fb
- slug
- build-a-modular-web-desktop-79e8048643fb
- url
- https://medium.com/@dxlliv/build-a-modular-web-desktop-79e8048643fb
- canonical_url
- https://medium.com/@dxlliv/build-a-modular-web-desktop-79e8048643fb
- author_url
- https://medium.com/@dxlliv
- status
- ok
- fetched_at
- 2026-07-13 06:23:13