
service/ directory, no Docker image, no Helm chart — just a React component published as an npm package that the shell loads when your pack is installed. pack-settings is the reference implementation for this pattern.
When to pick this shape
Use frontend-only when
- The pack needs no long-running backend process.
- All data comes from the platform (the current user, org-scoped APIs the shell already exposes) or from third-party APIs called straight from the browser.
- You need only one window, with no scheduled or background work.
Go full-stack when
- The pack owns stateful data you don’t want to trust to the browser.
- You need to hold a persistent process (PTY, daemon, subscription).
- You need server-side secrets that must never touch the frontend.
Directory shape
service/. No helm/. No Dockerfile. The pack lives entirely in the browser.
Manifest
backend and services keys are simply absent. The platform infers “frontend-only” from their absence.
Typical SDK usage
Frontend-only packs reach for one hook:useKhalAuth() — exposes the current userId, orgId, role, permissions, and a loading flag. React state handles everything else. Reach for useNats only when you want to broadcast user-visible events to other packs (e.g., “theme changed”).
The SDK does not expose a
signOut method — sign-out is a desktop-shell concern, not a pack concern. The user signs out of KhalOS itself, not out of an individual pack. See useKhalAuth for the full contract.Publishing
Frontend-only packs ship faster than full-stack ones because there is no container image to build and no Helm chart to package. Keep the pack frontend-only unless you need server-side behavior.
What’s next
Full-stack pack pattern
When you need a backend, go here.
Publish your pack
The full publish pipeline (npm → Docker → Helm).