@phcdevworks/spectre-shell is the application shell responsible for
orchestrating app-level composition. It coordinates routing, global styling,
providers, layout scaffolding, and runtime initialization so downstream
applications can boot with a consistent structure and predictable behavior.
Maintained by PHCDevworks, this is the application orchestration layer in the
Spectre suite. It sits above
@phcdevworks/spectre-ui and
adapter packages, taking visual and component primitives and wiring them into a
working app frame without taking ownership of token contracts, styling
internals, or application-specific business logic.
Contributing | Changelog | Security Policy
- Bootstraps Spectre applications through a shared
bootstrapApp()entry point - Coordinates global stylesheet loading for downstream app startup
- Integrates routing setup with app initialization instead of embedding router internals directly into apps
- Provides a consistent shell contract for root mounting and startup flow
- Establishes the shared application frame that downstream apps build within
- Keeps orchestration concerns separate from tokens, styling primitives, and business logic
npm install @phcdevworks/spectre-shellBootstrap a Spectre application from a single entry point:
import { bootstrapApp } from '@phcdevworks/spectre-shell'
import { defineRoutes } from '@phcdevworks/spectre-shell-router'
bootstrapApp({
root: document.getElementById('app')!,
routes: () => {
defineRoutes([
{ path: '/', loader: () => import('./pages/home') },
{ path: '/settings', loader: () => import('./pages/settings') }
])
}
})The shell coordinates startup concerns so applications do not repeat the same boot logic across projects:
import { bootstrapApp } from '@phcdevworks/spectre-shell'
const root = document.getElementById('app')
if (!root) {
throw new Error('Application root not found')
}
bootstrapApp({
root,
routes: () => {
// Register application routes before the router starts
}
})The default shell flow is:
- load shared Spectre styling for the application frame
- register application routes
- start the runtime shell against the provided root element
Routing can remain externalized while the shell coordinates its startup. Layout composition stays at the application boundary instead of being embedded into the router itself.
import { bootstrapApp } from '@phcdevworks/spectre-shell'
import { defineRoutes } from '@phcdevworks/spectre-shell-router'
function withAppLayout(content: string) {
return `
<div class="app-shell">
<header class="app-shell__header">Spectre App</header>
<main class="app-shell__content">${content}</main>
</div>
`
}
bootstrapApp({
root: document.getElementById('app')!,
routes: () => {
defineRoutes([
{
path: '/',
loader: async () => ({
render(ctx) {
ctx.root.innerHTML = withAppLayout('<h1>Home</h1>')
}
})
}
])
}
})If routing is delegated to
@phcdevworks/spectre-shell-router,
@phcdevworks/spectre-shell coordinates that router as part of app startup
rather than owning router behavior itself.
- Application bootstrapping through a shared shell entry point
- Coordination of routing startup for downstream applications
- Global styling initialization needed for the Spectre app frame
- Shell-level composition concerns such as root mounting, providers, and layout scaffolding
- Runtime initialization flow that gives downstream apps a predictable startup contract
Golden rule: orchestrate shared app composition, do not redefine lower-layer contracts.
- Design values or semantic meaning That belongs to
@phcdevworks/spectre-tokens. - Primitive styling contracts or reusable CSS implementation That belongs to
@phcdevworks/spectre-ui. - Router internals If routing is externalized, packages such as
@phcdevworks/spectre-shell-routerown path matching, navigation behavior, and page lifecycle implementation. - App-specific business logic, feature state, and domain concerns Downstream applications own those responsibilities.
@phcdevworks/spectre-shell currently exports:
bootstrapApp
Example:
import { bootstrapApp } from '@phcdevworks/spectre-shell'
bootstrapApp({
root: document.getElementById('app')!,
routes: () => {
// register routes here
}
})The bootstrap contract is intentionally small:
type BootstrapOptions = {
root: HTMLElement
routes: () => void
}Applications provide the root mount node and route registration function. The shell handles shared startup flow from there.
Spectre keeps responsibilities separate:
@phcdevworks/spectre-tokensdefines design values and semantic meaning@phcdevworks/spectre-uiturns those tokens into reusable CSS, Tailwind tooling, and shared styling behavior@phcdevworks/spectre-shellcoordinates those lower layers into a shared application frame and runtime bootstrap contract- Router and adapter packages extend that frame with specialized capability or framework-specific delivery
That separation keeps application structure predictable while avoiding overlap between design tokens, styling implementation, routing capability, and app logic.
Build the package:
npm run buildKey source areas:
src/bootstrap.tsfor application bootstrap orchestrationsrc/styles.tsfor shell-managed style importssrc/index.tsfor package exports
PHCDevworks maintains this package as part of the Spectre suite.
When contributing:
- keep the shell focused on orchestration, not visual definition
- keep routing coordination separate from router internals
- avoid introducing app-specific behavior into the shared shell
- run
npm run buildbefore opening a pull request
See CONTRIBUTING.md for the full workflow.
MIT © PHCDevworks. See LICENSE.