core.js Documentation

A lightweight, dependency-free JavaScript framework for building dynamic, data-driven web interfaces using simple HTML attributes.

Key Features

  • Zero Dependencies - Pure vanilla JavaScript
  • Async-Native - Built on modern async/await patterns
  • Pocket-Based - Component architecture without virtual DOM
  • Template Engine - Powerful data binding with {{rec:field}} syntax
  • Smart Routing - SPA navigation with clean URLs
  • Flexible Storage - DOM, Data Attributes, or Session Storage
  • Built-in Validation - Comprehensive scrubbing and formatting

Installation

🚀 Just add this one line:

<script src="https://cdn.jsdelivr.net/gh/Sitezip/core.sbs/core.js"></script>

That's it. No build step. No dependencies. No npm install.

CDN Options

<!-- Latest version -->
<script src="https://cdn.jsdelivr.net/gh/Sitezip/core.sbs/core.js"></script>

Self-Hosted

Download core.js and serve it yourself:

<script src="/path/to/core.js"></script>

Quick Start

1. Install CLI Tools

Install the development toolkit:

npm install -g @core.sbs/create-core-app

2. Create New Project

Scaffold a new core.js project:

create-core-app my-app
cd my-app

3. Start Development

Launch the development server with hot reload:

core-dev

Open http://localhost:3000 in your browser.

4. Create a Template

Templates are defined in a hidden section with id="cr-data":

<section id="cr-data" style="display:none;">
    <template name="users">
        <div class="core-clone" data-core-data="users">
            <h3>{{rec:name}}</h3>
            <p>{{rec:email}}</p>
            <p>Balance: {{rec:balance:money:$}}</p>
        </div>
    </template>
</section>

5. Create a Pocket

Pockets are containers where templates are rendered:

<div class="core-pocket" 
     data-core-templates="users" 
     data-users-core-source="https://api.example.com/users">
</div>

6. Initialize

core.js initializes automatically on DOMContentLoaded, but you can also call it manually:

core.init();

Architecture Overview

core.js follows a lifecycle-driven approach with distinct phases:

Rendering Lifecycle

  1. SOC (Start of Call) - Initialization begins
  2. getTemplate() - Fetch missing templates
  3. addTemplate() - Inject templates into pockets
  4. getData() - Fetch missing data
  5. addData() - Clone and populate with data
  6. EOC (End of Call) - Hydration, formatting, cleanup

Core Modules

Module Purpose
core.be Backend operations (fetch, cache)
core.cr Registry (data/template storage)
core.pk Pocket lifecycle management
core.hf Helper functions (date, sorting, etc.)
core.sv Validation and scrubbing
core.ux User experience utilities
core.ud User-defined hooks and settings

Pockets

Pockets are container elements that act as dynamic insertion points for components.

Basic Pocket

<div class="core-pocket" data-core-templates="myTemplate"></div>

Pocket with Data Source

<div class="core-pocket" 
     data-core-templates="products" 
     data-products-core-source="/api/products">
</div>

Multiple Templates

<div class="core-pocket" 
     data-core-templates="header,content,footer">
</div>

Templates

Templates use double curly brace syntax for data binding.

Template Syntax

{{type:source:reference:format:clue}}

Template Types

Type Description Example
rec or # Current record data {{rec:name}}
data or @ Global registry data {{data:config:apiKey}}
aug or ! Augmented metadata {{aug:index}}

Complete Example

<template name="userCard">
    <div class="core-clone" data-core-data="users">
        <h3>{{rec:name}}</h3>
        <p>{{rec:address.city}}</p>
        <p>{{rec:email:lower}}</p>
        <p>{{rec:balance:money:$}}</p>
        <span>Item {{aug:count}}</span>
        <img {{rec:avatar:core_pk_attr:src}} alt="Avatar">
    </div>
</template>

Data Binding

Clone Elements

Elements with core-clone class are duplicated for each record:

<div class="core-clone" data-core-data="products">
    <h3>{{rec:name}}</h3>
    <p>{{rec:price:money:$}}</p>
</div>

Nested Data Access

{{rec:user.profile.name}}
{{rec:address.billing.street}}
{{rec:settings.theme.colors.0}}
{{rec:tags.[n]}}

Lifecycle

core.init()
  └─> core.cr.init()
  └─> core.pk.init()
      └─> core.pk.soc()
          ├─> core.be.awaitAll()
          ├─> core.ud.soc()
          ├─> core.pk.getTemplate()
          ├─> core.pk.addTemplate()
          ├─> core.pk.getData()
          ├─> core.pk.addData()
          └─> core.pk.pk_eol()
              ├─> core.hf.hydrateByClass()
              ├─> core.hf.formatByClass()
              └─> core.ud.pk_eol()

Routing Optional

Routing is completely optional in core.js. Many applications work perfectly without it.

When to Use Routing

✅ Use Routing For:
  • • Multi-view dashboards (admin panels, CRMs)
  • • E-commerce checkout flows
  • • Apps needing bookmarkable/shareable URLs
  • • Complex SPAs with many screens
  • • User profiles with tabbed navigation
🚫 Skip Routing For:
  • • Landing pages & marketing sites
  • • Simple content displays
  • • Single-view dashboards
  • • Forms with simple hide/show logic
  • • Static data displays (tables, lists)

core.init()

Method

Initializes the core.js framework. Called automatically on DOMContentLoaded.

core.init();

core.be - Backend

core.be.getData()

Async Method

Fetches JSON data from a source and stores it in the registry.

Parameter Type Description
dataRef string Unique identifier
dataSrc string URL to fetch from
settings object Optional config
await core.be.getData('users', '/api/users');

await core.be.getData('users', '/api/users', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    data: { filter: 'active' }
});

core.be.getTemplate()

Async Method

await core.be.getTemplate('header', '/templates/header.html');

core.be.awaitAll()

Async Method

Waits for all active backend requests to complete.

core.be.getData('users', '/api/users');
core.be.getData('products', '/api/products');
await core.be.awaitAll();

Cache Configuration Advanced

core.cr - Registry

Storage Tiers

ID Type Description
0 DOM Memory-only
1 Static data-* attributes (default)
2 Session sessionStorage

core.cr.setData() / getData()

core.cr.setData('users', usersArray);
core.cr.setData('token', 'abc123', null, 2);

const users = core.cr.getData('users');
const token = core.cr.getData('token', null, 2);

core.cr.setTemplate() / getTemplate()

core.cr.setTemplate('myTemplate', '<div>{{rec:name}}</div>');
const template = core.cr.getTemplate('myTemplate');

core.pk - Pockets

core.pk.soc()

Async Method

Start of Call - initiates the rendering lifecycle.

await core.pk.soc();

core.pk.cloner()

Clones a template for each record in an array.

const records = [
    { name: 'John', age: 30 },
    { name: 'Jane', age: 25 }
];
const template = '<div>{{rec:name}} is {{rec:age}}</div>';
const html = core.pk.cloner(records, template);

core.hf - Helper Functions

core.hf.date()

Robust date formatting with custom tokens.

Token Output
YYYY 4-digit year
MM Month (01-12)
DD Day (01-31)
HH Hour (00-23)
:MM :Minutes
P AM/PM
core.hf.date();
core.hf.date(null, 'YYYY-MM-DD');
core.hf.date(1738627200, 'M/D/YY H:MM P');

core.hf.digData()

Deep-seek values in nested objects.

const user = {
    name: 'John',
    address: { billing: { street: '123 Main' } },
    tags: ['admin', 'user']
};

core.hf.digData(user, 'name');
core.hf.digData(user, 'address.billing.street');
core.hf.digData(user, 'tags.0');
core.hf.digData(user, 'tags.[n]');

core.hf.sortObj()

const users = [
    { name: 'Charlie', age: 30 },
    { name: 'Alice', age: 25 }
];
core.hf.sortObj(users, 'name');
core.hf.sortObj(users, 'age', 'numeric', 'DESC');

core.hf.uuid()

const id = core.hf.uuid();
const prefixed = core.hf.uuid('user-');

coreInternalObjects - Data Schema

Built-in standardized object definitions for e-commerce/CRM applications.

Available Objects

Object Description
productComplete product data with inventory
itemProduct summary/cart item
orderComplete order with items, contacts, transactions
contactEntity data (customer, vendor, affiliate)
addressShipping/billing address
transactionPayment transaction data
cardCredit card information
categoryProduct/item categories
inventoryStock level tracking
chatCommunication data
discountCoupon/promotion data
subscriptionRecurring billing setup

Auto-Loading

Automatically loaded on initialization from:

Template Usage

// Access schema properties
{{data:coreInternalObjects:product:name}}
{{data:coreInternalObjects:order:total}}
{{data:coreInternalObjects:contact:email}}

coreInternalHit - Analytics Tracking

Built-in session tracking system that captures initialization data.

Data Structure

The coreInternalHit object contains:

Property Description
version Current core.js version
ts Timestamp of initialization
uuid Unique session identifier
YYYY Current year

Template Usage

Access via data binding in templates:

<!-- Direct template binding -->
<span>{{data:coreInternalHit:version}}</span>
<span>{{data:coreInternalHit:YYYY}}</span>

<!-- CSS class hydration -->
<span class="h--coreInternalHit-version"></span>
<span class="h--coreInternalHit-YYYY"></span>

<!-- Footer example -->
&copy; <span class="h--coreInternalHit-YYYY"></span> CORE_ORCHESTRATOR // version <span class="h--coreInternalHit-version"></span>

core.hf.hydrateByClass()

<span class="h-users-name"></span>
<span class="h-users-email"></span>

<script>
core.hf.hydrateByClass();
</script>

core.hf.formatByClass()

<span class="f-money" data-f-clue="$">1234.56</span>
<span class="f-upper">hello</span>

core.sv - Validation

core.sv.scrub() Simple

The easiest way to validate form inputs:

const result = core.sv.scrub([
    { name: 'email', value: 'user@example.com', scrubs: ['req', 'email'] },
    { name: 'password', value: 'secret123', scrubs: ['req', 'min:8'] }
]);

if (result.success) {
    console.log('Valid!', result.scrubs);
} else {
    console.log('Errors:', result.errors);
}

core.ux - User Experience

core.ux.insertPocket()

Dynamically inserts a pocket into the DOM.

core.ux.insertPocket('#main', 'home');

core.ux.insertPocket('#main', 'products', [
    { name: 'products', url: '/api/products' }
]);

core.ux.insertPocket('#main', 'header,content,footer');

core.ux.formatValue()

core.ux.formatValue('hello', 'upper');
core.ux.formatValue('  hello  ', 'trim|upper');
core.ux.formatValue(1234.56, ['money*$']);

core.ud - User Defined

Configuration

core.ud.defaultDelta = 'N/A';
core.ud.defaultDateFormat = 'YYYY-MM-DD';
core.ud.defaultLoadingTemplate = '<div class="spinner"></div>';

Lifecycle Hooks

Hook When Called
core.ud.init() On framework initialization
core.ud.soc() Start of rendering cycle
core.ud.pk_eol() End of rendering cycle
core.ud.preflight() Before backend requests
core.ud.postflight() After backend responses
core.ud.prepaint() Before template injection
core.ud.postpaint() After data cloning
core.ud.init = () => {
    core.useRouting = true;
    console.log('Framework initialized');
};

core.ud.soc = () => {
    console.log('Rendering started');
};

core.ud.preflight = (dataRef, dataSrc, type) => {
    return {
        headers: { 'Authorization': 'Bearer ' + token }
    };
};

core.ud.postflight = (dataRef, dataObj, type) => {
    if (dataRef === 'users') {
        dataObj = dataObj.filter(u => u.active);
    }
    return dataObj;
};

core.ud.postpaint = (dataRef, dataObj, type) => {
    console.log(`Rendered ${dataRef}`);
};

Formatters Reference

Formatter Input Output
upper "hello" "HELLO"
lower "HELLO" "hello"
upperfirst "hello" "Hello"
money 1234.56 "$1234.56"
date timestamp "2/3/26"
phone "5551234567" "(555) 123-4567"
truncate "Long text" "Long..."
nohtml "<b>text</b>" "text"
linkify "example.com" "<a>...</a>"
boolean "true" true
number "123.45" 123.45
padleft "5" "005"
padright "5" "500"

Validation Rules

Caching Advanced

core.js automatically caches data to improve performance. The default cache lasts 1 hour.

Storage Tiers Advanced

By default, core.js stores data in memory. For most apps, this is all you need.

Rule Usage Description
req ['req'] Field is required
email ['email'] Valid email format
url ['url'] Valid URL format
num ['num'] Must be numeric
alpha ['alpha'] Letters only
alphanum ['alphanum'] Letters and numbers
min ['min:8'] Minimum length
max ['max:100'] Maximum length
gte ['gte:18'] Greater than or equal
lte ['lte:100'] Less than or equal
match ['match:password'] Must match field
ccnum ['ccnum'] Valid credit card
Tier Persistence Visibility Use Case
0 - DOM Page only Hidden Sensitive data, temporary state
1 - Static Page only Visible in HTML Public data, debugging (default)
2 - Session Tab session Hidden User session, auth tokens
// DOM storage (memory only)
core.cr.setData('tempState', { count: 0 }, element, 0);

// Static storage (default, visible in HTML)
core.cr.setData('users', usersArray, null, 1);

// Session storage (persists across page loads)
core.cr.setData('authToken', 'abc123', null, 2);

Example: Basic Usage

<!DOCTYPE html>
<html>
<head>
    <script src="https://cdn.jsdelivr.net/gh/Sitezip/core.sbs/core.js"></script>
</head>
<body>
    <div id="main">
        <div class="core-pocket" data-core-templates="users"></div>
    </div>

    <section id="cr-data" style="display:none;">
        <template name="users">
            <div class="core-clone" data-core-data="users">
                <h3>{{rec:name}}</h3>
                <p>{{rec:email}}</p>
            </div>
        </template>
    </section>

    <script>
        core.ud.init = () => {
            const users = [
                { name: 'John Doe', email: 'john@example.com' },
                { name: 'Jane Smith', email: 'jane@example.com' }
            ];
            core.cr.setData('users', users);
        };
    </script>
</body>
</html>

Example: Form Validation

<form id="signupForm">
    <input type="text" name="username" placeholder="Username">
    <input type="email" name="email" placeholder="Email">
    <input type="password" name="password" placeholder="Password">
    <input type="password" name="confirmPassword" placeholder="Confirm">
    <button type="submit">Sign Up</button>
</form>

<script>
document.getElementById('signupForm').addEventListener('submit', (e) => {
    e.preventDefault();
    
    const formData = new FormData(e.target);
    const result = core.sv.scrub([
        {
            name: 'username',
            value: formData.get('username'),
            scrubs: ['req', 'alphanum', 'min:3', 'max:20']
        },
        {
            name: 'email',
            value: formData.get('email'),
            scrubs: ['req', 'email']
        },
        {
            name: 'password',
            value: formData.get('password'),
            scrubs: ['req', 'min:8']
        },
        {
            name: 'confirmPassword',
            value: formData.get('confirmPassword'),
            scrubs: ['req', 'match:password']
        }
    ]);
    
    if (result.success) {
        console.log('Form valid!', result.scrubs);
        // Submit to server
    } else {
        console.log('Validation errors:', result.errors);
        // Show errors to user
    }
});
</script>

Example: API Integration

Fetch and display data from an API with just HTML:

<div class="core-pocket" 
     data-core-templates="products" 
     data-products-core-source="https://api.example.com/products">
</div>

<template name="products">
    <div class="core-clone" data-core-data="products">
        <img {{rec:image:core_pk_attr:src}} alt="{{rec:name}}">
        <h3>{{rec:name}}</h3>
        <p>{{rec:description:truncate:100}}</p>
        <p class="price">{{rec:price:money:$}}</p>
        <button onclick="addToCart('{{rec:id}}')">Add to Cart</button>
    </div>
</template>

Example: SPA Routing

<nav>
    <a href="#/_main/home">Home</a>
    <a href="#/_main/about">About</a>
    <a href="#/_main/products">Products</a>
    <a href="#/_main/contact">Contact</a>
</nav>

<div id="main">
    <div class="core-pocket" data-core-templates="home"></div>
</div>

<section id="cr-data" style="display:none;">
    <template name="home">
        <h1>Welcome Home</h1>
    </template>
    
    <template name="about">
        <h1>About Us</h1>
    </template>
    
    <template name="products">
        <h1>Our Products</h1>
        <div class="core-clone" data-core-data="products">
            <div>{{rec:name}} - {{rec:price:money:$}}</div>
        </div>
    </template>
    
    <template name="contact">
        <h1>Contact Us</h1>
    </template>
</section>

<script>
core.ud.init = () => {
    core.useRouting = true;
};
</script>

Example: Recursive Cloning

<div class="core-pocket" data-core-templates="users"></div>

<template name="users">
    <div class="core-clone" data-core-data="users">
        <h3>{{rec:name}}</h3>
        <p>{{rec:email}}</p>
        
        <!-- Recursive: render posts for each user -->
        <div class="posts">
            {{rec:posts:core_pk_cloner:postTemplate}}
        </div>
    </div>
</template>

<template name="postTemplate">
    <div class="post">
        <h4>{{rec:title}}</h4>
        <p>{{rec:content:truncate:200}}</p>
        <span>{{rec:date:date:M/D/YY}}</span>
        
        <!-- Nested recursive: render comments for each post -->
        <div class="comments">
            {{rec:comments:core_pk_cloner:commentTemplate}}
        </div>
    </div>
</template>

<template name="commentTemplate">
    <div class="comment">
        <strong>{{rec:author}}</strong>: {{rec:text}}
    </div>
</template>

<script>
core.ud.init = () => {
    const users = [
        {
            name: 'John Doe',
            email: 'john@example.com',
            posts: [
                {
                    title: 'First Post',
                    content: 'This is my first post...',
                    date: 1738627200,
                    comments: [
                        { author: 'Jane', text: 'Great post!' },
                        { author: 'Bob', text: 'Thanks for sharing!' }
                    ]
                }
            ]
        }
    ];
    core.cr.setData('users', users);
};
</script>

VS Code Extension

Accelerate your core.js development with our official VS Code extension featuring 56 intelligent code snippets, custom syntax highlighting, and a dedicated theme.

Features

Snippet Breakdown

HTML (26 snippets)

  • • 5 Pocket variations
  • • 4 Template structures
  • • 4 Clone patterns
  • • 9 Data directives
  • • 3 Anchor shortcuts
  • • 2 Complete examples

JavaScript (30 snippets)

  • • 7 Lifecycle hooks
  • • 5 Backend API calls
  • • 3 Registry operations
  • • 5 Helper functions
  • • 3 Configuration setups
  • • 7 Utilities & handlers

Available Snippets

Core.js Pockets

cpk Basic pocket
cpkd Pocket with data source
cpkt Pocket with template
cpkid Pocket with ID
cpknr Pocket (no routing)

Templates

ctpl Basic template
ctpld Template with data refs
ctplc Template with clone
ctplf Full template structure

Clones

ccl Basic clone
cclr Clone with record refs
cclnest Nested clone (recursive)
cclaug Clone with augmented data

Template Directives

cdata Data reference
crec Record reference
caug Augmented data
cattr Attribute injection
ccloner Recursive cloner
cformat Formatted data
cdateformat Date formatting
cmoneyformat Money formatting

Lifecycle Hooks

cudinit Init hook
cudsoc Start of call hook
cudeoc End of call hook
cudpre Preflight hook
cudpost Postflight hook
cudprepaint Prepaint hook
cudpostpaint Postpaint hook

API Calls

cbeget Get data
cbegetset Get data with settings
cbetpl Get template
cbepost POST data
cpkinit Initialize pockets
ccrset Set data in registry
ccrget Get data from registry
ccrgettpl Get template from registry

Helper Functions

chfdig Deep object access
chfdate Date formatting
chfhydrate Hydrate by class
chfformat Format by class
chfparse Parse JSON

Validation & Utilities

csvscrub Scrub array
csvformat Format value
caget Anchor get data
catpl Anchor get template
capk Anchor reinit pockets
cexample Complete example
cform Form with validation

💡 Pro Tip: Type any snippet prefix (like cpk, ctpl, ccl) and press Tab or Enter to expand!

Installation

📦 Recommended: Download from GitHub Releases

  1. 1. Go to GitHub Releases
  2. 2. Download the latest corejs-snippets-*.vsix file
  3. 3. Open VS Code
  4. 4. Press Ctrl+Shift+P (or Cmd+Shift+P on Mac)
  5. 5. Type "Extensions: Install from VSIX"
  6. 6. Select the downloaded .vsix file
  7. 7. Reload VS Code (Ctrl+Shift+P → "Developer: Reload Window")
Alternative: Build from Source

1. Install vsce

npm install -g @vscode/vsce

2. Navigate to extension directory

cd vscode-extension

3. Package the extension

vsce package

This creates a .vsix file

4. Install in VS Code

  • • Open VS Code
  • • Press Ctrl+Shift+P (or Cmd+Shift+P on Mac)
  • • Type "Extensions: Install from VSIX"
  • • Select the generated .vsix file

5. Reload VS Code

Press Ctrl+Shift+P → "Developer: Reload Window"

Common Snippets

HTML Snippets

cpk Basic pocket
cpkd Pocket with data source
ctpl Basic template
ctplc Template with clone
ccl Basic clone
crec Record reference

JavaScript Snippets

cudinit Init hook
cudsoc Start of call hook
cbeget Get data from API
cpkinit Initialize pockets
ccrset Set data in registry
csvscrub Validate data

Usage Example

Type a snippet prefix and press Tab or Enter to expand:

<!-- Type: cpkd + Tab -->
<div class="core-pocket" 
     data-core-templates="users" 
     data-core-source-users="https://api.example.com/users">
</div>

💡 Pro Tip: Press Ctrl+Space to trigger IntelliSense and see all available snippets.

Verify Installation

  1. Open an HTML file in VS Code
  2. Type cpk and press Tab
  3. The pocket snippet should expand automatically

Additional Resources

GitHub Repository

https://github.com/Sitezip/core.sbs

Official Website

https://core.sbs

VS Code Extension

Located in /vscode-extension directory

Version

Current: 20260125.1