Client & CLI

desktop.config.ts

defineDesktopConfig, theme, apps, modules, shell keys, extension keys, and runtime merge.

Place desktop.config.ts next to the Nuxt root of your desktop project (alongside nuxt.config.ts). In the client monorepo that is desktop/desktop.config.ts.

Legacy filename:owd.config.ts is still resolved for older projects. New projects should use desktop.config.ts.

Minimal shape

import { defineDesktopConfig } from '@owdproject/core'

export default defineDesktopConfig({
  theme: '@owdproject/theme-nova',
  apps: ['@owdproject/app-about'],
  modules: [],
})

Main fields

FieldMeaning
themeTheme Nuxt module (npm package name). Required for a predictable shell.
modulesExtension modules loaded after the theme, before apps (e.g. @owdproject/module-fs, @owdproject/module-persistence).
appsApp modules; each registers programs via defineDesktopApp.

Shell keys

Shell keys (name, systemBar, dockBar, workspaces, defaultApps, features, explorer, docs, …) merge into:

  • runtimeConfig.public.desktop (full config, including theme, apps, modules, and coreVersion)
  • appConfig.desktop (same reference; runtime overrides via useDesktopManager().setConfig())

They are never spread onto _nuxt.options — put Nuxt options in nuxt.config.ts.

Extension keys

Packages with a Nuxt configKey (e.g. terminal, fs) expose a namespace on desktop.config.ts:

export default defineDesktopConfig({
  theme: '@owdproject/theme-nova',
  modules: ['@owdproject/module-fs'],
  apps: ['@owdproject/app-terminal'],
  terminal: {
    prompt: 'my-desktop$ ',
  },
  fs: {
    mounts: { '/home': 'WebStorage' },
  },
})
  • Core merges the entire export into runtimeConfig.public.desktop.
  • Extension modules should use defineDesktopModule from @owdproject/core with meta.configKey set.
  • Types: augment DesktopConfig in your package via types/desktop.d.ts (see app-terminal / module-fs in the monorepo). Core does not whitelist extension keys.

At runtime (auto-imported by @owdproject/core, not from the main package entry — safe for desktop.config.ts):

APIUse
useDesktopConfig()Full public.desktop
useDesktopExtension('fs')One namespace (typed via your augmentation)
hasDesktopModule('@owdproject/module-fs')desktop.modules?.includes(...)
hasDesktopApp('@owdproject/app-terminal')desktop.apps?.includes(...)
hasDesktopExtension('terminal')Extension namespace present

Warnings

Only keys that look like Nuxt options (ssr, vite, nitro, …) trigger a dev warning. Custom extension keys and manifest fields (modules, apps, fs, terminal) do not.

Merge semantics

Core and themes use defu (UnJS):

  • User / existing desktop.config values win; theme module defaults fill undefined only.
  • useDesktopManager().setConfig() uses the same model so DesktopCore props override at runtime.
  • Themes: prefer defineDesktopTheme (or defineNuxtModule with configKey: 'desktop' and the same defu(public.desktop, options) pattern).

Authoring API (packages)

ExportRole
defineDesktopModuleApps / extension modules (meta.configKey required)
defineDesktopThemeTheme shell defaults merged into public.desktop
setDesktopExtensionConfigUsed by defineDesktopModule after Nuxt merge
mergeDesktopExtensionConfigTheme setup: merge into an extension namespace without importing defu

Validation

@owdproject/core validates the default export after load:

  • theme: string (npm package name) or omitted.
  • apps / modules: arrays of strings when present.

Malformed shapes throw before theme or app modules install.

Errors

Missing or invalid config throws with path + remediation. Syntax errors surface from the bundler or validation step.

Example with filesystem

export default defineDesktopConfig({
  theme: '@owdproject/theme-nova',
  apps: ['@owdproject/app-about'],
  modules: [
    '@owdproject/module-fs',
    '@owdproject/module-persistence',
  ],
  workspaces: { enabled: true },
  terminal: { prompt: 'owd$ ' },
})

Install modules first: desktop add module-fs.