- Static compiler with STRC pattern (Static Template Resolution with
Compartmentalized Layers)
- Template syntax: { } interpolation, { s-for }, { s-if/s-elif/s-else
}
- File types: .strata, .compiler.sts, .service.sts, .api.sts, .sts,
.scss
- CLI tools: strata-compile dev, strata-compile build, strata-compile
g (generators)
- create-strata-compile scaffolding CLI with Pokemon API example
- Dev server with WebSocket HMR (Hot Module Replacement)
- Documentation: README, ARCHITECTURE, CHANGELOG, CONTRIBUTING,
LICENSE
60 KiB
60 KiB
Strata Framework Architecture
Strata = Static Template Rendering Architecture
A compile-time web framework that resolves templates to pure HTML at build time.
╔═══════════════════════════════════════════════════════════════════╗
║ ║
║ Code Faster. Load Quick. Deploy ASAP. ║
║ ║
╚═══════════════════════════════════════════════════════════════════╝
Table of Contents
- Core Principles
- Design Pattern: STRC
- Compilation Flow
- File Types & Layers
- Template Syntax
- Import Hierarchy
- Runtime Architecture
- Dev Server Architecture
- Future: Shared Worker
- Future: Smart Fetch
- Future: Encrypted Store
- Performance Targets
Core Principles
| # | Principle | Description |
|---|---|---|
| 1 | Static First | All templates resolved at build time, not runtime |
| 2 | Zero Runtime Overhead | Output is pure HTML with no framework code |
| 3 | Strict Separation | Each file type has exactly one responsibility |
| 4 | Go Compiler | Fast builds with native performance |
| 5 | Compartmentalized Layers | Clear boundaries between template, data, and logic |
Design Pattern: STRC
STRC = Static Template Resolution with Compartmentalized Layers
Pattern Overview
┌─────────────────────────────────────────────────────────────────────┐
│ BUILD TIME │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ SOURCE FILES STATIC COMPILER │
│ ════════════ ═══════════════ │
│ │
│ ┌─────────────┐ │
│ │ .strata │─────┐ │
│ │ (Template) │ │ │
│ └─────────────┘ │ ┌────────────────────────────────┐ │
│ │ │ │ │
│ ┌─────────────┐ ├─────────▶│ STRATA STATIC COMPILER │ │
│ │ .compiler │─────┤ │ │ │
│ │ .sts │ │ │ 1. Parse .strata to AST │ │
│ │ (Variables) │ │ │ 2. Load .compiler.sts exports │ │
│ └─────────────┘ │ │ 3. Resolve { variables } │ │
│ │ │ 4. Expand { s-for } loops │ │
│ ┌─────────────┐ │ │ 5. Evaluate { s-if } blocks │ │
│ │ .service │─────┘ │ 6. Output pure HTML │ │
│ │ .sts │ │ │ │
│ │ (Logic) │ └──────────────┬─────────────────┘ │
│ └─────────────┘ │ │
│ │ │
│ ┌─────────────┐ │ │
│ │ .scss │───────────────────────────────┤ │
│ │ (Styles) │ │ │
│ └─────────────┘ │ │
│ │ │
└─────────────────────────────────────────────────┼────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ RUNTIME │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ OUTPUT │
│ ══════ │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ PURE HTML │ │
│ │ │ │
│ │ • No { } syntax │ │
│ │ • No s-for directives │ │
│ │ • No s-if conditionals │ │
│ │ • No framework JavaScript (unless .service.sts defines) │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Optional: Runtime JavaScript from .service.sts │ │
│ │ (Event handlers, interactivity, etc.) │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
Layer Responsibilities
┌─────────────────────────────────────────────────────────────────────┐
│ STRC LAYERS │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ LAYER 1: TEMPLATE (.strata) │
│ ═══════════════════════════ │
│ • Pure HTML structure │
│ • Strata directives ({ }, s-for, s-if) │
│ • No logic, no JavaScript │
│ • Variables injected from compiler layer │
│ │
│ ──────────────────────────────────────────────────────────────── │
│ │
│ LAYER 2: COMPILER (.compiler.sts) │
│ ═════════════════════════════════ │
│ • Variable definitions │
│ • Data structures (arrays, objects) │
│ • Build-time constants │
│ • Executed during compilation │
│ │
│ ──────────────────────────────────────────────────────────────── │
│ │
│ LAYER 3: SERVICE (.service.sts) │
│ ════════════════════════════════ │
│ • Business logic │
│ • API calls (build-time or runtime) │
│ • Event handlers │
│ • Optional browser interactivity │
│ │
│ ──────────────────────────────────────────────────────────────── │
│ │
│ LAYER 4: API CONTRACT (.api.sts) │
│ ════════════════════════════════ │
│ • Declarative endpoint definitions │
│ • Request/response schemas │
│ • Cache policies │
│ │
│ ──────────────────────────────────────────────────────────────── │
│ │
│ LAYER 5: UTILITIES (.sts) │
│ ═════════════════════════ │
│ • Pure functions │
│ • No side effects │
│ • Shared helpers │
│ │
└─────────────────────────────────────────────────────────────────────┘
Compilation Flow
Step-by-Step Process
┌─────────────────────────────────────────────────────────────────────┐
│ COMPILATION PIPELINE │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ STEP 1: PARSE TEMPLATE │
│ ══════════════════════ │
│ │
│ Input: Output: │
│ ┌──────────────────────┐ ┌──────────────────────┐ │
│ │ <template> │ │ AST │ │
│ │ <h1>{ title }</h1> │ ────▶ │ ├─ TemplateNode │ │
│ │ { s-for ... } │ │ │ └─ ElementNode │ │
│ │ </template> │ │ │ └─ Interp... │ │
│ └──────────────────────┘ └──────────────────────┘ │
│ │
│ ──────────────────────────────────────────────────────────────── │
│ │
│ STEP 2: LOAD COMPILER SCOPE │
│ ═══════════════════════════ │
│ │
│ Input: Output: │
│ ┌──────────────────────┐ ┌──────────────────────┐ │
│ │ export const title │ │ scope = { │ │
│ │ = 'Hello'; │ ────▶ │ title: 'Hello', │ │
│ │ export const items │ │ items: [...] │ │
│ │ = [...]; │ │ } │ │
│ └──────────────────────┘ └──────────────────────┘ │
│ │
│ ──────────────────────────────────────────────────────────────── │
│ │
│ STEP 3: RESOLVE TEMPLATE │
│ ════════════════════════ │
│ │
│ Process: │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ For each AST node: │ │
│ │ │ │
│ │ • InterpolationNode { var } → Look up in scope, output │ │
│ │ • ForBlockNode { s-for } → Iterate, create loop scope │ │
│ │ • IfBlockNode { s-if } → Evaluate, include/exclude │ │
│ │ • ElementNode <div> → Output tag + recurse │ │
│ │ • TextNode → Output as-is │ │
│ │ │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
│ ──────────────────────────────────────────────────────────────── │
│ │
│ STEP 4: OUTPUT │
│ ══════════════ │
│ │
│ Result: │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ <h1>Hello</h1> │ │
│ │ <div class="item">Item 1</div> │ │
│ │ <div class="item">Item 2</div> │ │
│ │ <div class="item">Item 3</div> │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
│ Pure HTML. No framework syntax. No runtime overhead. │
│ │
└─────────────────────────────────────────────────────────────────────┘
Expression Resolution
┌─────────────────────────────────────────────────────────────────────┐
│ EXPRESSION RESOLUTION │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ SIMPLE VARIABLE │
│ ─────────────── │
│ Template: { title } │
│ Scope: { title: "Hello World" } │
│ Output: Hello World │
│ │
│ ──────────────────────────────────────────────────────────────── │
│ │
│ PROPERTY ACCESS │
│ ─────────────── │
│ Template: { user.name } │
│ Scope: { user: { name: "Alice", age: 30 } } │
│ Output: Alice │
│ │
│ ──────────────────────────────────────────────────────────────── │
│ │
│ NESTED ACCESS │
│ ───────────── │
│ Template: { config.api.baseUrl } │
│ Scope: { config: { api: { baseUrl: "https://..." } } } │
│ Output: https://... │
│ │
│ ──────────────────────────────────────────────────────────────── │
│ │
│ LOOP VARIABLE │
│ ───────────── │
│ Template: { s-for item in items } │
│ { item.name } │
│ { /s-for } │
│ │
│ Scope: { items: [{ name: "A" }, { name: "B" }] } │
│ │
│ Loop 1: loopScope = { ...scope, item: { name: "A" } } │
│ Output: A │
│ │
│ Loop 2: loopScope = { ...scope, item: { name: "B" } } │
│ Output: B │
│ │
└─────────────────────────────────────────────────────────────────────┘
File Types & Layers
File Extension Matrix
| Extension | Layer | Execution | Can Import | Purpose |
|---|---|---|---|---|
.strata |
Template | Build | .strata |
HTML structure |
.compiler.sts |
Compiler | Build | .service.sts, .api.sts, .sts |
Variables |
.service.sts |
Service | Build + Runtime | .api.sts, .sts |
Logic |
.api.sts |
API | Build | .sts |
Endpoints |
.sts |
Utility | Both | .sts |
Pure functions |
.scss |
Style | Build | - | Styles |
Component/Page Structure
src/pages/index/
├── index.strata # Template (what to render)
├── index.compiler.sts # Data (what values to use)
├── index.service.sts # Logic (how it behaves)
└── index.scss # Styles (how it looks)
File Content Examples
┌─────────────────────────────────────────────────────────────────────┐
│ index.strata │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ <template> │
│ <main class="page"> │
│ <h1>{ title }</h1> │
│ { s-for item in items } │
│ <div>{ item.name }</div> │
│ { /s-for } │
│ </main> │
│ </template> │
│ │
└─────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────┐
│ index.compiler.sts │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ export const title = 'My Page'; │
│ │
│ export const items = [ │
│ { name: 'Item 1' }, │
│ { name: 'Item 2' }, │
│ { name: 'Item 3' }, │
│ ]; │
│ │
└─────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────┐
│ index.service.sts │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ // Runtime interactivity (optional) │
│ const mount = function() { │
│ document.getElementById('btn') │
│ .addEventListener('click', handleClick); │
│ }; │
│ │
│ return { mount }; │
│ │
└─────────────────────────────────────────────────────────────────────┘
Template Syntax
Interpolation
┌─────────────────────────────────────────────────────────────────────┐
│ SYNTAX: { expression } │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Simple: { title } │
│ Property: { user.name } │
│ Nested: { config.api.url } │
│ │
│ Note: Single braces, not double {{ }} │
│ │
└─────────────────────────────────────────────────────────────────────┘
Loop Directive
┌─────────────────────────────────────────────────────────────────────┐
│ SYNTAX: { s-for item in collection } ... { /s-for } │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Basic: │
│ { s-for user in users } │
│ <div>{ user.name }</div> │
│ { /s-for } │
│ │
│ With Index: │
│ { s-for user, index in users } │
│ <div>#{ index }: { user.name }</div> │
│ { /s-for } │
│ │
│ Nested: │
│ { s-for category in categories } │
│ <h2>{ category.name }</h2> │
│ { s-for item in category.items } │
│ <div>{ item.name }</div> │
│ { /s-for } │
│ { /s-for } │
│ │
└─────────────────────────────────────────────────────────────────────┘
Conditional Directives
┌─────────────────────────────────────────────────────────────────────┐
│ SYNTAX: { s-if } / { s-elif } / { s-else } / { /s-if } │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Simple If: │
│ { s-if isLoggedIn } │
│ <div>Welcome back!</div> │
│ { /s-if } │
│ │
│ If-Else: │
│ { s-if isAdmin } │
│ <div>Admin Panel</div> │
│ { s-else } │
│ <div>User Dashboard</div> │
│ { /s-if } │
│ │
│ If-Elif-Else: │
│ { s-if role === 'admin' } │
│ <div>Admin</div> │
│ { s-elif role === 'mod' } │
│ <div>Moderator</div> │
│ { s-else } │
│ <div>User</div> │
│ { /s-if } │
│ │
│ Negation: │
│ { s-if !isLoggedIn } │
│ <a href="/login">Log In</a> │
│ { /s-if } │
│ │
│ Comparison Operators: │
│ === == !== != > < >= <= │
│ │
└─────────────────────────────────────────────────────────────────────┘
Import Hierarchy
Strict Layer Enforcement
┌─────────────────────────────────────────────────────────────────────┐
│ IMPORT HIERARCHY │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ │
│ │ .strata │ │
│ │ (Template) │ │
│ └──────┬──────┘ │
│ │ │
│ │ can import │
│ ▼ │
│ ┌─────────────┐ │
│ │ .strata │ (other templates only) │
│ └─────────────┘ │
│ │
│ ════════════════════════════════════════════════════════════════ │
│ │
│ ┌─────────────────┐ │
│ │ .compiler.sts │ │
│ │ (Variables) │ │
│ └────────┬────────┘ │
│ │ │
│ │ can import │
│ ▼ │
│ ┌──────────────┼──────────────┐ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌───────────┐ ┌───────────┐ ┌───────────┐ │
│ │ .service │ │ .api.sts │ │ .sts │ │
│ │ .sts │ │ │ │ │ │
│ └───────────┘ └───────────┘ └───────────┘ │
│ │
│ ════════════════════════════════════════════════════════════════ │
│ │
│ ┌─────────────────┐ │
│ │ .service.sts │ │
│ │ (Logic) │ │
│ └────────┬────────┘ │
│ │ │
│ │ can import │
│ ▼ │
│ ┌────────┴────────┐ │
│ │ │ │
│ ▼ ▼ │
│ ┌───────────┐ ┌───────────┐ │
│ │ .api.sts │ │ .sts │ │
│ └───────────┘ └───────────┘ │
│ │
│ ════════════════════════════════════════════════════════════════ │
│ │
│ ┌─────────────────┐ │
│ │ .api.sts │ │
│ │ (API Contract) │ │
│ └────────┬────────┘ │
│ │ │
│ │ can import │
│ ▼ │
│ ┌───────────┐ │
│ │ .sts │ │
│ └───────────┘ │
│ │
│ ════════════════════════════════════════════════════════════════ │
│ │
│ ┌─────────────────┐ │
│ │ .sts │ │
│ │ (Utilities) │ │
│ └────────┬────────┘ │
│ │ │
│ │ can import │
│ ▼ │
│ ┌───────────┐ │
│ │ .sts │ (other utilities only) │
│ └───────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
VIOLATION = BUILD ERROR
Runtime Architecture
Minimal Runtime
┌─────────────────────────────────────────────────────────────────────┐
│ RUNTIME OUTPUT │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ index.html │
│ ══════════ │
│ │
│ <!DOCTYPE html> │
│ <html> │
│ <head> │
│ <link rel="stylesheet" href="/assets/css/app.css"> │
│ </head> │
│ <body> │
│ <div id="app"></div> │
│ <script type="module" src="/assets/js/app.js"></script> │
│ </body> │
│ </html> │
│ │
│ ──────────────────────────────────────────────────────────────── │
│ │
│ app.js │
│ ══════ │
│ │
│ // Pages registry with pre-compiled HTML │
│ const pages = { │
│ '/': { │
│ render() { │
│ return `<main>...</main>`; // Pure HTML, no framework │
│ }, │
│ mount() { │
│ // Optional: runtime interactivity from .service.sts │
│ } │
│ } │
│ }; │
│ │
│ // Simple router │
│ function mount() { │
│ const page = pages[location.pathname] || pages['/']; │
│ document.getElementById('app').innerHTML = page.render(); │
│ page.mount(); │
│ } │
│ │
│ mount(); │
│ │
└─────────────────────────────────────────────────────────────────────┘
Dev Server Architecture
Built-in Go Server with HMR
┌─────────────────────────────────────────────────────────────────────┐
│ strata-compile dev │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌───────────────┐ │
│ │ File System │ │
│ └───────┬───────┘ │
│ │ │
│ │ fsnotify │
│ ▼ │
│ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │
│ │ Watcher │────▶│ Compiler │────▶│ Dev Server │ │
│ │ (Go) │ │ (Go) │ │ (Go) │ │
│ └───────────────┘ └───────────────┘ └───────┬───────┘ │
│ │ │
│ ┌────────┴────────┐ │
│ │ │ │
│ ▼ ▼ │
│ ┌──────────┐ ┌──────────┐│
│ │ HTTP │ │WebSocket ││
│ │ :3000 │ │ HMR ││
│ └──────────┘ └──────────┘│
│ │
│ ──────────────────────────────────────────────────────────────── │
│ │
│ WATCH TARGETS: │
│ │
│ src/ │
│ ├── pages/**/*.strata → Recompile page │
│ ├── pages/**/*.compiler.sts → Recompile page │
│ ├── pages/**/*.service.sts → Recompile page │
│ ├── pages/**/*.scss → Hot reload CSS │
│ ├── components/**/* → Recompile dependents │
│ └── ... │
│ │
│ strataconfig.ts → Full rebuild │
│ │
│ ──────────────────────────────────────────────────────────────── │
│ │
│ HMR MESSAGES: │
│ │
│ { type: "reload" } → Full page reload │
│ { type: "css", path: "..." } → CSS hot swap │
│ { type: "component" } → Component reload │
│ │
└─────────────────────────────────────────────────────────────────────┘
Future: Shared Worker Architecture
Status: Planned
┌─────────────────────────────────────────────────────────────────────┐
│ Strata Shared Worker │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Tab 1 │ │ Tab 2 │ │ Tab 3 │ │ Tab N │ │
│ │ tabId:a1 │ │ tabId:b2 │ │ tabId:c3 │ │ tabId:xx │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ │ │ │ │ │
│ └─────────────┴──────┬──────┴─────────────┘ │
│ │ │
│ ┌────────▼────────┐ │
│ │ Shared Worker │ │
│ │ │ │
│ │ ┌───────────┐ │ │
│ │ │ Store │ │ ◄── Encrypted State │
│ │ └───────────┘ │ │
│ │ ┌───────────┐ │ │
│ │ │ Cache │ │ ◄── API Response Cache │
│ │ └───────────┘ │ │
│ │ ┌───────────┐ │ │
│ │ │ TabSync │ │ ◄── Tab Registry │
│ │ └───────────┘ │ │
│ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
Tab Management (Planned)
// Auto-generated tabId for each browser tab
const tabId = strata.tabId; // e.g., "tab_a1b2c3"
// Tab-specific state
strata.store.setForTab(tabId, { draft: formData });
// Shared state (all tabs)
strata.store.setShared({ user: currentUser });
// Broadcast to specific tabs
strata.broadcast('logout', { reason: 'session_expired' }, ['tab_a1b2c3']);
// Broadcast to all tabs
strata.broadcast('refresh', { entity: 'users' });
Future: Smart Fetch System
Status: Planned
Request Deduplication
// These calls are deduplicated - only ONE request is made
const [users1, users2, users3] = await Promise.all([
strata.fetch('/api/users'),
strata.fetch('/api/users'),
strata.fetch('/api/users'),
]);
// All three resolve with the same data from single request
Caching Strategy
strata.fetch('/api/users', {
cache: 'smart', // Default: cache until data changes
cache: 'none', // No caching
cache: '5m', // Cache for 5 minutes
cache: 'permanent', // Cache until manual invalidation
// Stale-while-revalidate pattern
stale: '1m', // Serve stale for 1 min while fetching fresh
});
Future: Encrypted Store
Status: Planned
Build-Time Encryption
┌─────────────────────────────────────────────────────────────────────┐
│ Build Process │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 1. Generate encryption key at build time │
│ key = crypto.randomBytes(32) │
│ │
│ 2. Embed key in compiled runtime (obfuscated) │
│ const _k = [0x2f, 0xa1, ...]; // Split & scattered │
│ │
│ 3. Store data encrypted in SharedWorker │
│ encrypted = AES256(JSON.stringify(state), key) │
│ │
│ 4. Browser can't read state even with DevTools │
│ localStorage: "encrypted:a1b2c3d4e5f6..." │
│ │
└─────────────────────────────────────────────────────────────────────┘
Store Definition (Planned)
// stores/user.sts
import { createStore } from 'strata';
export const userStore = createStore('user', {
state: {
currentUser: null,
preferences: {},
token: null,
},
actions: {
login(user, token) {
this.currentUser = user;
this.token = token;
},
logout() {
this.currentUser = null;
this.token = null;
},
},
encrypt: true, // Encrypt entire store
persist: true, // Persist to SharedWorker storage
shared: true, // Share across all tabs
});
Performance Targets
| Metric | Target | Typical React |
|---|---|---|
| Build Memory | < 512MB | 8GB+ |
| Bundle Size | < 50KB | 2MB+ |
| Runtime | < 5KB | 40KB+ |
| Cold Start | < 500ms | 3s+ |
| HMR | < 100ms | 1s+ |
| TTFB | < 50ms | 200ms+ |
Project Structure
strata/
├── cli/
│ └── create-strata/ # Project scaffolding
│ └── index.js
│
├── compiler/
│ ├── cmd/
│ │ └── strata/ # CLI entry point
│ │ ├── main.go
│ │ ├── dev.go
│ │ └── build.go
│ │
│ └── internal/
│ ├── ast/ # Abstract Syntax Tree
│ │ └── nodes.go
│ │
│ ├── compiler/ # Static compiler
│ │ └── static.go
│ │
│ ├── parser/ # Template parser
│ │ └── strata.go
│ │
│ ├── server/ # Dev server
│ │ └── dev.go
│ │
│ └── watcher/ # File watcher
│ └── watcher.go
│
├── runtime/ # Browser runtime
│ └── strata.js
│
├── templates/ # Project templates
│ └── default/
│
├── examples/ # Example projects
│ └── pokemon/
│
├── Makefile # Build commands
├── README.md # User documentation
├── ARCHITECTURE.md # This file
├── CHANGELOG.md # Version history
├── CONTRIBUTING.md # Contribution guidelines
└── LICENSE # Proprietary license
Summary
Strata implements the STRC Pattern (Static Template Resolution with Compartmentalized Layers) to achieve:
- Build-time compilation of all template syntax
- Zero runtime overhead in production
- Clear separation between template, data, and logic
- Strict import hierarchy preventing layer violations
- Fast development with Go-powered HMR
The result: websites that are as fast as hand-written HTML, with the developer experience of a modern framework.
Strata - Static Template Rendering Architecture