Create new applications for ryOS following established patterns and conventions. Use when building a new app, adding an application to the desktop, creating app components, or scaffolding app structures.
Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.
Quelldateien prüfen
Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Ein direkter Befehl überspringt den Prüf-Prompt. Prüfen Sie die Quelle, bevor Sie ihn ausführen.
Create new applications for ryOS following established patterns and conventions. Use when building a new app, adding an application to the desktop, creating app components, or scaffolding app structures.
Creating ryOS Applications
Quick Start Checklist
- [ ] 1. Create app directory: src/apps/[app-name]/
- [ ] 2. Create main component: components/[AppName]AppComponent.tsx
- [ ] 3. Create menu bar: components/[AppName]MenuBar.tsx
- [ ] 4. Create logic hook: hooks/use[AppName]Logic.ts
- [ ] 5. Create metadata: metadata.ts (appMetadata + exactly 6 help items)
- [ ] 6. Create app definition: index.tsx (re-export metadata, declare initialData type)
- [ ] 7. Add icon: choose from existing icons or the resource catalogs, then place active assets under `public/icons/<theme>/[app-name].png`
- [ ] 8. Register the app id: add to appIds + appNames in src/config/appRegistryData.ts
- [ ] 9. Register the app: lazy component + registry entry in src/config/appRegistry.tsx
- [ ] 10. Register help key order in src/hooks/useTranslatedHelpItems.ts
- [ ] 11. Add translation keys to src/lib/locales/en/translation.json
- [ ] 12. Localize (last): add en strings, sync locales; use the localize skill to finish
appRegistry.tsx imports appMetadata/helpItemseagerly so the dock, About/Help dialogs, and search can show app info without loading the (lazy) component bundle. Keep these in a tiny metadata.ts that imports nothing heavy. Most current apps follow this split (@/apps/<id>/metadata). then re-exports from and is the home for types and any app-specific exported types.
If a catalog asset is the right source, copy or adapt it into the active icon tree (public/icons/<theme>/...) instead of referencing public/resources/... directly from app metadata.
Add at least public/icons/default/[app-name].png; add theme-specific variants when the catalog has a better era-matched asset.
Run bun run generate:icons after adding or moving active files under public/icons.
Keep public/resources/*-icon-catalogs as source libraries. Do not replace unrelated active icons just because a catalog contains a historical equivalent.
App Definition (index.tsx)
Re-export the metadata and declare any initialData type. This is what other files import as @/apps/[app-name].
The AppId union type, dock/search ordering, and store lookups all derive from src/config/appRegistryData.ts. Add the id here first — otherwise appRegistry.tsx (and everything typed against AppId) will not compile.
If you ever rename an app's id, add the old id to LEGACY_APP_ID_ALIASES so persisted/bookmarked references still resolve.
6. Register in appRegistry.tsx
createLazyComponent lives in src/config/lazyAppComponent.tsx (already imported at the top of appRegistry.tsx) and registers the chunk for intent-based prefetch. Import metadata from the lightweight metadata.ts, not the component.
// Metadata import (eager, lightweight) — note the /metadata pathimport { appMetadata as [appName]Metadata, helpItems as [appName]HelpItems } from"@/apps/[app-name]/metadata";
// Lazy component (loaded on open). Use your initialData type instead of unknown if you declared one.constLazy[AppName]App = createLazyComponent<unknown>(
() =>import("@/apps/[app-name]/components/[AppName]AppComponent")
.then(m => ({ default: m.[AppName]AppComponent })),
"[app-name]"// cache key = app id, keeps refs stable across HMR + enables prefetch
);
// Add to the appRegistry object
["[app-name]"]: {
id: "[app-name]",
name: "[App Name]",
icon: { type: "image", src: [appName]Metadata.icon },
description: "App description",
component: Lazy[AppName]App,
helpItems: [appName]HelpItems,
metadata: [appName]Metadata,
windowConfig: {
defaultSize: { width: 650, height: 475 },
minSize: { width: 400, height: 300 },
} asWindowConstraints,
},
7. Register help keys
useTranslatedHelpItems("[app-name]", helpItems) needs a matching key list in APP_HELP_I18N_KEYS in src/hooks/useTranslatedHelpItems.ts. Keep the list in the same order as metadata.tshelpItems; the hook preserves the icons and swaps in apps.[app-name].help.[key].title and .description.
For longer help lists, create src/apps/[app-name]/helpKeys.ts and spread that exported list into APP_HELP_I18N_KEYS. Calculator, Maps, and Internet Explorer are good examples.
Run bun test tests/unit/i18n/test-help-i18n-alignment.test.ts after adding the app. It catches missing help keys and row-count drift across every registered app.
AppProps Interface
Prop
Type
Description
isWindowOpen
boolean
Window visibility
onClose
() => void
Close handler
isForeground
boolean
Window is active
instanceId
string
Unique instance ID
skipInitialSound
boolean
Skip open sound
initialData
TInitialData
Optional startup data
Menu Bar Placement
macOS/System7: Render outside WindowFrame when isForeground
After the app is built and wired up, finish by localizing:
Add translation keys for all user-facing strings (menu labels, dialogs, status, help).
Add English entries under apps.[app-name].* in src/lib/locales/en/translation.json.
Sync other locales with bun run i18n:sync:mark-todo.
Validate with bun run i18n:sync:dry-run, bun run i18n:audit, and the help alignment test.
Use the localize skill for the full workflow: extract strings → t() calls → en keys → sync. Do this step last so all UI copy is stable before extracting and syncing.