Thin, framework-agnostic app shell for the Spectre platform. Provides routing, styling, and application bootstrapping for vanilla TypeScript apps.
🤝 Contributing Guide | 📝 Changelog
@phcdevworks/spectre-shell is a lightweight application shell that combines routing, styling, and initialization into a single bootstrap function. It's designed for building modern web apps without heavy frameworks.
- ✅ Built-in client-side routing via
@phcdevworks/spectre-shell-router - ✅ Pre-configured Spectre UI styling and design tokens
- ✅ Simple
bootstrapApp()initialization - ✅ Framework-agnostic and TypeScript-first
- ✅ Zero configuration required to get started
- ✅ Minimal surface area—easy to understand and extend
npm install @phcdevworks/spectre-shellimport { bootstrapApp } from '@phcdevworks/spectre-shell'
import { defineRoutes } from '@phcdevworks/spectre-shell-router'
// Define your routes
const routes = () => {
defineRoutes([
{ path: '/', loader: () => import('./pages/home') },
{ path: '/about', loader: () => import('./pages/about') },
{ path: '/users/:id', loader: () => import('./pages/user') },
])
}
// Bootstrap your app
bootstrapApp({
root: document.getElementById('app')!,
routes,
})Each page module must export a render function:
// pages/home.ts
export function render(ctx: RouteContext) {
ctx.root.innerHTML = `
<div class="container">
<h1>Welcome to Spectre Shell</h1>
<a href="/about">About</a>
</div>
`
}
export function destroy() {
// Optional cleanup
console.log('Leaving home page')
}<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>My Spectre App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>The Spectre Shell bundles and configures:
- @phcdevworks/spectre-shell-router - Client-side routing with path parameters and lifecycle hooks
- @phcdevworks/spectre-ui - Core styling layer with utility classes
- @phcdevworks/spectre-tokens - Design tokens for consistent theming
All styles are pre-imported and ready to use—no additional configuration needed.
✅ Client-side routing with path parameters (/users/:id)
✅ Spectre UI styling automatically loaded
✅ Design tokens for consistent theming
✅ Page lifecycle hooks (render, destroy)
✅ TypeScript-first with full type definitions
✅ Framework-agnostic - works with vanilla JS/TS
✅ Minimal bundle size - only what you need
Initializes your application with routing and styling.
type BootstrapOptions = {
root: HTMLElement // Container element for your app
routes: () => void // Function that defines your routes
}
bootstrapApp(options: BootstrapOptions): voidExample:
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: '/about', loader: () => import('./pages/about') },
])
},
})Each page module must export a render function:
export function render(ctx: RouteContext): void
export function destroy?(): void // optional cleanupRouteContext provides:
path– The matched URL pathparams– Route parameters (e.g.,{ id: '123' })query– URLSearchParams objectroot– The DOM element where the page renders
Example page:
// pages/user.ts
export function render(ctx: RouteContext) {
const userId = ctx.params.id
ctx.root.innerHTML = `
<div class="container">
<h1>User ${userId}</h1>
<a href="/">Back to Home</a>
</div>
`
}
export function destroy() {
// Clean up event listeners, timers, etc.
console.log('Cleaning up user page')
}All Spectre UI styles are automatically loaded. Use utility classes in your pages:
export function render(ctx: RouteContext) {
ctx.root.innerHTML = `
<div class="container mx-auto p-4">
<h1 class="text-3xl font-bold text-primary">Hello Spectre</h1>
<button class="btn btn-primary mt-4">Click Me</button>
</div>
`
}For complete documentation on available styles, see @phcdevworks/spectre-ui.
Spectre Shell follows a thin shell approach:
Purpose: Minimal glue between routing, styling, and initialization
Rules:
- Keep the API surface tiny—just
bootstrapApp() - Bundle only essential dependencies
- No magic or hidden configuration
- TypeScript strict mode with full type exports
Contains:
- Router for navigation
- UI framework for styling
- Bootstrap function for initialization
Rules:
- Each layer is independent and replaceable
- No tight coupling between components
- Clear separation of concerns
The shell should be boring, transparent, and easy to delete.
Spectre Shell exists to wire up routing and styling with minimal ceremony, not to impose framework patterns.
- Thin by design - Minimal API surface, maximum flexibility
- Framework-agnostic - Works with vanilla JS/TS, no heavy dependencies
- Type-safe - Full TypeScript support throughout
- Batteries included - Routing + styling pre-configured
- Easily replaceable - Simple enough to swap out if needs change
Full TypeScript definitions are included:
import { bootstrapApp } from '@phcdevworks/spectre-shell'
import type { RouteContext } from '@phcdevworks/spectre-shell-router'Recommended project structure:
my-app/
├── src/
│ ├── pages/
│ │ ├── home.ts # Page modules
│ │ ├── about.ts
│ │ └── user.ts
│ └── main.ts # App entry point
├── index.html
├── package.json
└── tsconfig.json
main.ts:
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: '/about', loader: () => import('./pages/about') },
{ path: '/users/:id', loader: () => import('./pages/user') },
])
},
})- Spectre Tokens - Design token foundation
- Spectre UI - Core styling layer
- Spectre Shell - Application shell framework (this package)
- Spectre Shell Router - Client-side routing
- Spectre Blocks - WordPress block library
- Spectre Astro - Astro integration
Issues and pull requests are welcome. For detailed contribution guidelines, see CONTRIBUTING.md.
MIT © PHCDevworks — See LICENSE for details.
If Spectre Shell helps your workflow, consider sponsoring: