Skip to content

Repository files navigation

WAOS

WAOS is a deployment-ready, local-first browser OS. It is a static React + TypeScript PWA: there is no application server, account service, or proxy. Files, settings, notes, and installed .wa apps stay in IndexedDB on the current device.

What is included

  • Friendly iOS-inspired interaction design with a rounded, bubbly GNOME-like desktop
  • Responsive desktop and mobile shells
  • Movable, resizable, minimizable, and maximizable app windows
  • Desktop shortcuts, dock, searchable app launcher, clock, connectivity status, toasts, and notification center
  • IndexedDB virtual filesystem with folders, editing, import, export, and persistent notes
  • Built-in Welcome, Files, Notes, Browser, App Store, Settings, and Calculator apps
  • Configurable GitHub-backed app catalog with an offline starter catalog
  • Plain-JavaScript .wa packages with a parsed manifest block
  • Sandboxed .wa runtime using an iframe without same-origin access, plus a small message-based API
  • PWA manifest, service worker, offline caching, version checks, and an update prompt
  • Cloudflare-compatible security headers and a static production build
  • Sample .wa apps and a sample GitHub app-store index

Local development

Requirements: Node.js 22.13 or newer.

npm ci
npm run dev

Open the local address printed by Vite. Production build:

npm run build

The static site is written to dist/static.

Deploy to Cloudflare on a custom domain

WAOS is configured as a static-assets Cloudflare Worker. It does not run application code on a server; Cloudflare only serves the generated files.

  1. Push this folder to a GitHub repository.
  2. In Cloudflare, open Workers & Pages, create or select your Worker, and connect the GitHub repository under Settings → Builds.
  3. Set the production branch to main.
  4. Set the build command to npm run build.
  5. Keep the deploy command as npx wrangler deploy.
  6. Deploy once, then open Settings → Domains & Routes → Add → Custom Domain and enter your chosen hostname, such as os.example.com.
  7. If the parent domain uses Cloudflare DNS, Cloudflare creates the DNS record and certificate automatically.

The committed wrangler.jsonc points Cloudflare to dist/static and supplies the single-page-app fallback. Do not add a catch-all _redirects rule; it duplicates this fallback and Cloudflare rejects it as an infinite loop.

Publishing updates

Bump the version before a release, commit, and push:

npm version patch --no-git-tag-version
npm run build

The build synchronizes version.json, the application version, and the service-worker cache. Once Cloudflare deploys the new static files, open WAOS sessions detect the newer version and offer an update. IndexedDB data is not replaced by a site update.

Link a GitHub app store

WAOS reads a configurable public GitHub repository. Change the owner, repository, and branch in Settings → GitHub app store. The client reads:

https://raw.githubusercontent.com/{owner}/{repo}/{branch}/store/index.json

Copy examples/store/index.json into the store repository. Package URLs may be relative to the repository root or absolute HTTPS URLs.

{
  "formatVersion": 1,
  "name": "My WAOS App Store",
  "updatedAt": "2026-07-26T00:00:00Z",
  "apps": [
    {
      "id": "com.example.my-app",
      "name": "My App",
      "description": "A short description.",
      "version": "1.0.0",
      "icon": "package",
      "color": "#6d5dfc",
      "author": "Example Developer",
      "packageUrl": "apps/my-app.wa",
      "featured": true,
      "permissions": ["storage", "notifications"]
    }
  ]
}

If the configured catalog is offline, private, missing, or invalid, the App Store safely falls back to the bundled sample apps.

.wa package format

A .wa package is a JavaScript file with a machine-readable comment at the top. The main OS parses only the comment; the JavaScript itself runs inside a sandboxed iframe.

/* WA_MANIFEST
{
  "formatVersion": 1,
  "id": "com.example.hello",
  "name": "Hello",
  "version": "1.0.0",
  "description": "My first WAOS app.",
  "icon": "sparkles",
  "color": "#6d5dfc",
  "author": "Example Developer",
  "permissions": ["storage", "notifications"],
  "window": { "width": 600, "height": 480, "resizable": true }
}
WA_MANIFEST */

WA.mount(({ root, notify, storage, openExternal }) => {
  root.innerHTML = `<h1>Hello from WAOS</h1><button id="hello">Say hello</button>`;
  root.querySelector("#hello").addEventListener("click", () => {
    notify("Hello", "This came from a sandboxed app.");
  });
});

Available runtime methods:

  • root: the app's root element
  • notify(title, message): requires notifications
  • storage.get(key) / storage.set(key, value): requires storage; data is namespaced per app
  • openExternal(url): requires external-links; only HTTP(S) URLs are accepted

The sandbox does not get DOM access to WAOS, direct IndexedDB access, filesystem access, or same-origin privileges. For a public store, add package hashes and signature verification before accepting untrusted third-party publishers.

Browser behavior

The built-in Browser uses a standards-compliant sandboxed iframe. Websites that allow embedding can open inside WAOS. Websites that send X-Frame-Options or restrictive CSP headers may refuse to display; WAOS presents an Open externally action for those sites. The project intentionally does not attempt to bypass host-browser cookies, extensions, CORS, CSP, device policy, or other browser security boundaries.

Local data and backups

Browser storage belongs to the site origin and can be cleared by the browser or under storage pressure. Important files can be exported from Files. Hosting WAOS permanently at the same HTTPS origin preserves the same IndexedDB namespace between releases. Changing domains creates a separate empty workspace.

Source layout

src/
  apps/            Built-in apps and sandbox host
  components/      Desktop shell, dock, launcher, windows, notifications
  lib/db.ts        IndexedDB filesystem, settings, and installed apps
  lib/wa.ts        .wa manifest parser, installer, and sandbox document
public/
  apps/            Bundled sample .wa packages
  store/           Offline starter catalog
  sw.js            Offline and update service worker
  version.json     Release manifest
examples/store/    GitHub store example
build/              Version and Cloudflare build helpers

Security notes

  • Keep the provided CSP and Permissions Policy unless a reviewed app feature needs a narrow exception.
  • Do not add allow-same-origin to the .wa runtime iframe.
  • Do not expose generic code execution, operating-system commands, secrets, or unrestricted file APIs through the message bridge.
  • A browser PWA cannot provide a truly independent browser engine. Use a native shell if that requirement changes.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages