Jun 23, 2026
PostSnail Theme Installation Flow — Proposal
14 Jun 2026 · PostSnail · themes · install-flow · signed-publishing · static-sites
PostSnail already has the pieces needed to read themes. This proposal is about making installation explicit, narrow, and safe — not about adding a marketplace or runtime loader.
Summary
PostSnail already has the foundation for themes: validated manifests, a theme registry, a built-in quiet-feed fallback, CSS-token-only admin themes, and route-scoped public assets. What is still missing is a first-class install flow that makes theme registration explicit instead of relying on ad hoc registry wiring.
The safest first step is to add a narrow install/list/resolve path around the current theme registry, keep the built-in fallback behavior unchanged, and prove the result with tests.
Existing State Today
From the repo, the current theme foundation already includes:
validateThemeManifest()insrc/core/themes/themeManifest.jscreateThemeRegistry()insrc/core/themes/themeRegistry.jsresolveFrontendTheme()with a built-inquiet-feedfallbackresolveAdminThemeTokens()that returns CSS variables only- built-in theme definitions in
src/core/themes/builtinThemes.js - route-scoped asset resolution in
src/core/assets/routeAssets.js - theme selection stored in the encrypted Shell under
appearance.frontendTheme,appearance.adminTheme, andappearance.themeSettings - tests that already cover theme validation, fallback resolution, admin token-only behavior, and route-scoped assets
That means the repo already knows how to read themes. It does not yet present installation as a clear, narrow workflow.
Gap This Proposal Fills
The missing piece is a small, explicit theme-install boundary:
- install a validated theme manifest into the registry
- list installed frontend/admin themes
- resolve the selected theme from encrypted Shell appearance state
- preserve built-in fallback behavior for old Shells or missing IDs
- keep admin themes CSS-token-only
- keep public theme assets route-scoped
This should stay declarative. It should not become a marketplace, a runtime loader, or a general plugin system.
Proposed Change
I suggest the first contribution be limited to this shape:
- Add a small install helper to the existing theme registry model, aligned with the existing plugin registry style.
- Keep the registry as the source of truth for validated theme manifests.
- Keep
quiet-feedas the fallback frontend theme. - Keep
defaultas the fallback admin theme. - Keep admin themes token-only; do not allow JavaScript runtime assets.
- Keep route assets scoped per route and filtered to safe public paths.
- Add focused tests that prove install/list/resolve behavior and fallback behavior.
This is the smallest safe first step because it improves the theme path without changing the public export contract or the workspace format.
Files Likely Touched
Primary files:
src/core/themes/themeRegistry.jstests/extension-system.test.js
Possibly, if the install flow needs to be represented in the workspace layer later:
src/workspaceSchema.jssrc/migrations.jstests/workspace.test.js
I do not think the first step needs a schema migration unless the proposal introduces a new persisted theme collection. The current appearance shape already stores selected theme IDs and per-theme settings.
Compatibility Impact
Compatibility should remain intact if we keep the proposal narrow:
- existing .postsnail` Shells keep opening
- existing
appearance.frontendThemeandappearance.adminThemevalues keep working - missing or unknown frontend themes still fall back to
quiet-feed - missing or unknown admin themes still fall back to
default - admin themes remain CSS-token-only
- public assets remain route-scoped and safe-path filtered
- no new required protocol features are introduced
In other words: install becomes explicit, but old Shells should not break.
Testing Plan
Use the repo’s current test runner:
node --test tests/core-foundation.test.js tests/extension-system.test.js
Expected result: pass.
The tests should prove at least:
- valid frontend theme manifests can be registered and resolved
- valid admin theme manifests can be registered and token-resolved
- invalid manifests are rejected
- missing frontend themes still resolve to
quiet-feed - missing admin themes still resolve to
default - route assets stay per-route and do not leak globally
Open Questions
- Should theme installation remain registry-only for the first step, or should it also persist an installed-theme list in the workspace right away?
- Do we want the first contribution to include a new
installTheme()helper, or should it extend the existingcreateThemeRegistry()API with a narrowly named method? - Should
themeSettingsstay as a free-form per-theme object for now, or do we eventually want manifest-driven validation for theme settings? - Should the first issue focus on frontend themes only, or keep admin themes in the same install path as long as they remain token-only?
Suggested Direction
My recommendation is to keep the first contribution focused on registry install plus resolve behavior, with no marketplace and no runtime loader. That gives us a clear, reviewable foundation for later Admin UI or CLI work.
No external sources were used for this proposal.
Post digest d553373bae1172a0fabd1709eba6ccee665627e9010153887fb3114d9cdfaa27ada91fffa60c33c8e73f513e66f3ca8bccf69564500be3897d4f4b5d572d0a66