OWD is a federation of packages: core and kits live in the client monorepo; themes and apps often live in separate Git repositories; engine modules such as @owdproject/module-fs are optional npm packages, not vendored inside packages/ anymore.
Choosing the wrong dependency specifier is the most common source of pnpm install failures during local development. This page explains the three linking models and when to use each.
{
"dependencies": {
"@owdproject/core": "^3.3.0",
"@owdproject/theme-nova": "^0.0.2"
}
}
Use when:
npm create owd or consume published packages only.Pros: semver, lockfile stability, no monorepo required.
Cons: you must publish (or wait for) a core release before themes can declare new APIs; patch locally with pnpm patch or temporary overrides if you are blocked.
workspace:* (pnpm monorepo){
"devDependencies": {
"@owdproject/core": "workspace:*"
}
}
Use when:
pnpm-workspace.yaml (typically packages/*, themes/*, apps/*, desktop/).themes/my-theme or apps/my-app and listed in the workspace.Pros: instant feedback — edit core source, reload desktop, no publish step.
Cons: only resolves packages that are in the workspace. If package.json says "@owdproject/module-fs": "workspace:*" but there is no packages/module-fs/ (or cloned module) in the tree, pnpm fails with:
ERR_PNPM_WORKSPACE_PKG_NOT_FOUND
… is in the dependencies but no package named "@owdproject/module-fs" is present in the workspace
That error means: switch to npm semver, add the package via desktop add module-fs --dev, or remove the dependency if the feature is optional.
{
"dependencies": {
"@owdproject/theme-gnome": "git+https://github.com/owdproject/theme-gnome.git#main"
}
}
Use when:
--from your-user in the CLI)."git+https://github.com/owdproject/client.git#89f2e6b"
Pros: works outside the monorepo; good for cross-repo PR review.
Cons: slower installs; you must track commit SHAs for reproducibility; some tooling assumes semver in peerDependencies checks.
| You are… | Core | Theme / app | module-fs / persistence |
|---|---|---|---|
| Client monorepo contributor | workspace:* | clone under themes/* → workspace:* | npm ^0.0.x or desktop add … --dev |
| Theme author (separate repo) | npm ^3.3.0 peer | — | npm in playground only if you test explorer |
| App author (separate repo) | npm peer | npm theme in playground | optional npm in playground |
| End user / template project | npm | npm | npm via desktop add |
These packages are not part of the client packages/ tree (by design):
| Package | Role |
|---|---|
@owdproject/module-fs | ZenFS virtual filesystem runtime |
@owdproject/module-persistence | Optional Pinia persistence (IndexedDB) |
Kits in the monorepo depend on them as peers or document them as optional:
| Package | Role |
|---|---|
@owdproject/kit-primevue | PrimeVue module, dialog impl, PV explorer chrome |
| core shell composables | useDesktopShellIdentity, edge drop, overview, session — see Shell identity |
core runtime/explorer/ | useExplorerStore, DnD, menu model (headless) |
kit-theme / kit-fs / kit-explorer | Deprecated — use core + kit-primevue |
Install modules into your desktop project:
desktop add module-fs
desktop add module-persistence
Then list them in desktop.config.ts → modules. Themes that ship an explorer UI typically check nuxt.options.modules.includes('@owdproject/module-fs') before installing @owdproject/kit-explorer.
The client .gitignore excludes /themes and /apps so you can clone theme/app repos locally without committing them to client. Each clone may have its own .git.
Implications:
workspace:* in a theme package.json only works when that theme folder is inside the client workspace and pnpm sees it as a workspace package.workspace:* on kits.pnpm install at the workspace root (client) or in the theme/app repo.pnpm run prepare:stubs (client) or pnpm run dev:prepare (module) so dist/ stubs exist.pnpm run dev — Nuxt does not always pick up new module paths without a restart.