SimpliJS · API reference

v3.2.0 · Enterprise‑grade, Reactive, HTML‑First
🔷 < 18kB 🌉 Bridge 🕰️ Vault Pro Full v3.2.0 Feature Set
Latest Release: This API reference is synchronized with SimpliJS v3.2.0 from GitHub. All 54 features, including the directive engine and Time Vault, are fully implemented and verified for production use.

📦 Core imports & types

All framework symbols are importable from the CDN or local simplijs.js.

import { createApp, component, reactive, computed, watch, ref, on, emit, use } from 'simplijs';
// Full type definition (simplijs.d.ts)
// Register a new SimpliJS component
component(name: string, setup: ComponentSetup): void;

type ComponentSetup = (element: HTMLElement, props: Record) => ComponentOutput;

type ComponentOutput = {
  render?: () => string;
  onMount?: () => void;
  onUpdate?: () => void;
  onDestroy?: () => void;
  [key: string]: any; // Custom methods
};

🧩 component(name, setup)

Registers a custom element. The setup function receives the element instance and a reactive props object (auto‑synced from attributes).

component<P extends Record<string, any>>(name: string, setup: (el: HTMLElement, props: Reactive<P>) => ComponentOutput): void
// Example with typed props & methods
component('user-profile', (el, props) => {
  const state = reactive({ count: 0 });
  return {
    inc: () => state.count++,
    render: () => `
      
Count: ${state.count} | Initial: ${props.initialCount}
` }; });

⚠️ Attribute sync: Attributes like count="5" become props.count (string). Use watch or computed for number coercion.

⚛️ reactive(), computed(), watch()

reactive<T extends object>(initial: T): Reactive<T>
computed<T>(fn: () => T): { readonly value: T }
watch<T>(source: () => T, callback: (newVal: T, oldVal: T) => void, immediate?: boolean): void
// deeply reactive with error handling
const form = reactive({
  email: '',
  touches: 0
});

// computed with implicit error catching → component.onError can handle
const isEmail = computed(() => {
  if (!form.email.includes('@')) throw new Error('Invalid email format');
  return true;
});

watch(() => form.email, (newVal, oldVal) => {
  try {
    console.log(`email changed: ${oldVal} → ${newVal}`);
  } catch (e) {
    // if watch throws, it bubbles to component onError (if defined)
    throw e;
  }
});
⛑️ Error pattern: Throwing inside computed or watch will be caught by the nearest component’s onError hook. Unhandled errors are logged to console but do not break the app.

🪝 ref() & lifecycle hooks

ref<T extends HTMLElement>(): { value: T | null }

Refs are populated after render, before onMount.

component('focus-input', (el) => {
  return {
    onMount: () => {
      const input = el.querySelector('input');
      input?.focus();
    },
    onUpdate: () => console.log('rerendered'),
    onDestroy: () => console.log('cleanup'),
    render: () => ``
  };
});

Ref assignment: use ref="yourRefName" in template string, matching the key returned from ref().

📡 emit() & on() (global bus)

emit(event: string, detail?: any): boolean
on(event: string, handler: (detail: any) => void): () => void // unsubscribe
// component A: emit
component('pinger', () => ({
  ping: () => emit('network:status', { online: navigator.onLine }),
  render: () => ``
}));

// component B: listen (auto clean on destroy)
component('ponger', () => {
  const unsub = on('network:status', (data) => {
    console.log('pong', data);
  });

            

Error handling: if a handler throws, other listeners still run; error is emitted to window.onerror and component.onError of the listener’s component (if any).

⚡ 8 HTML-First Directives

SimpliJS provides 8 native directives that work directly in your HTML. No compilation required. Below is the categorized reference.

CategoryDirectivesDescription / Syntax
Cores-appApplication boundary for the engine. Initialized on mount.
Bindings-bind / s-modelDeep reactive text/number/form sync.
Logics-if / s-for / s-switchTemplate-driven logic flow with optimized DOM patching.
Eventss-click / s-submit / s-keyDeclarative performance-optimized event listeners.
Utilitys-text / s-html / s-refDirect content and DOM ref management.

Note: The v3.2.0 Directive Engine is highly optimized for performance and works directly on the DOM without a Virtual DOM overhead.

📋 createApp().form() – automated validation

createApp(selector: string).form(config: FormConfig): FormHandler
interface FormConfig {
  fields: string[];                           // field names
  validate?: Record<string, (val: any) => string | null>;
  onError?: (errors: Record<string, string>) => void;
  submit: (data: Record<string, any>) => void;
}

component('contact-form', () => {
  const handler = createApp().form({
    fields: ['name', 'email'],
    validate: {
      email: (v) => /^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(v) ? null : 'invalid email',
      name: (v) => v.trim() ? null : 'name required'
    },
    onError: (errs) => console.table(errs),
    submit: (data) => fetch('/api', { method:'POST', body: JSON.stringify(data) })
  });

  return {
    handler,
    render: () => `
      
` }; });

✋ Invalid fields automatically get class .is-invalid; the onError receives map of field → message.

🌉 use – universal component bridge

use.react(moduleUrl: string, exportName?: string): string (component tag)
use.vue(moduleUrl: string, ...): string
use.svelte(moduleUrl: string, ...): string
import { use, component } from 'simplijs';

// import a React icon component (ESM)
const IconTag = use.react('https://esm.sh/lucide-react?alias=react&bundle', 'Heart');

component('like-button', () => ({
  render: () => `
    <button>
      <${IconTag} color="red" size="20"></${IconTag}>
      like
    </button>
  `
}));

// error handling: if module fails, component renders nothing and onError is called

Status: The Bridge is fully operational in v3.2.0, allowing seamless integration of React, Vue, and Svelte components into SimpliJS layouts.

🔌 Official Plugin Ecosystem

The SimpliJS ecosystem includes 7 high-performance plugins for enterprise features.

1. @simplijs/auth

Complete auth lifecycle management.

const auth = createAuth({ provider: 'jwt', endpoint: '/login' });
  • auth.login(creds) - Authenticate and store session.
  • auth.user - Reactive user object.
  • auth.guard(route) - Route protection helper.

2. @simplijs/router

Declarative SPA routing.

const router = createRouter({ routes: [...] });
  • router.push(path) - Navigation.
  • router.params - Reactive URL parameters.
  • <s-view> - Router outlet directive.

3. @simplijs/vault-pro

Extended state time-travel and persistence.

const s = reactive.vault(init, { storage: 'local' });
  • s.vault.sync() - Sync state with remote server.
  • s.vault.encrypt() - AES encryption for sensitive local state.

Also includes: @simplijs/bridge-adapters, @simplijs/devtools, @simplijs/forms, and @simplijs/ssg.

🌐 Advanced SEO & SSG Reference

Documentation for @simplijs/ssg and built-in industrial SEO tools.

SEO Helpers (In-App)

import { setSEO, setJsonLd, setThemeColor, setBreadcrumbs } from 'simplijs';
// Dynamic Metadata Updates
setSEO({
  title: 'My Profile | SimpliJS',
  description: 'Pro-grade Reactive Social App',
  image: 'https://cdn.com/og.jpg',
  twitterHandle: '@sb_tech'
});

// Structured Data (JSON-LD)
setJsonLd({
  "@context": "https://schema.org",
  "@type": "SoftwareApplication",
  "name": "SimpliJS"
});

// Breadcrumbs & Theme
setBreadcrumbs([{ name: 'Docs', url: '/docs' }, { name: 'SEO', url: '/seo' }]);
setThemeColor('#6a0dad');

SSG Configuration (ssg.config.js)

export default {
  baseUrl: 'https://mysite.com',
  outDir: 'dist',
  minify: true,
  rss: { title: 'Blog', items: [...] },
  routes: {
    '/': HomeTemplate,
    '/blog': BlogListTemplate
  }
};

// CLI Execution: node ssg.js ssg.config.js

🛡️ Security-First Directive Engine

SimpliJS addresses traditional framework security vulnerabilities (XSS, Template Injection) at the architectural level.

Safe Evaluation Mode

By default, s-state and s-click expressions are evaluated through a high-performance sandbox that prevents access to window, document, or sensitive cookies.

CSP Compatibility

SimpliJS is fully compliant with strict Content Security Policies. It avoids eval() and new Function() for directive parsing, using a custom-built lexical tokenizer.

🕰️ reactive.vault() – time travel state

reactive.vault<T extends object>(initial: T): Reactive<T> & { vault: VaultControls }
interface VaultControls {
  back(): void;                // undo
  forward(): void;             // redo
  share(): string;             // returns URL with ?simpli-debug=base64
  timeline(): ReadonlyArray<T> // debug history
}

const globalState = reactive.vault({
  filter: 'all',
  items: []
});

component('vault-ui', () => ({
  undo: () => globalState.vault.back(),
  redo: () => globalState.vault.forward(),
  shareDebug: () => {
    const url = globalState.vault.share();
    navigator.clipboard?.writeText(url);
  },
  render: () => `
    <div>
      <button onclick="globalState.vault.back()">↩️ undo</button>
      <button onclick="globalState.vault.forward()">↪️ redo</button>
      <button onclick="alert(globalState.vault.share())">🔗 share timeline</button>
    </div>
  `
}));

Restore from URL: SimpliJS automatically detects ?simpli-debug=... on page load and hydrates the vault.

🧾 Advanced props & attribute typing

Props are reactive, but note that HTML attributes are always strings. Use computed / watch to convert.

component<{ value: string; }>('numeric-display', (el, props) => {
  const asNumber = computed(() => {
    const num = Number(props.value);
    if (isNaN(num)) throw new TypeError(`"${props.value}" is not a number`);
    return num;
  });

  return {
    render: () => `<p>${asNumber.value} * 2 = ${asNumber.value * 2}</p>`,
    onError: (err) => {
      el.innerHTML = `⚠️ ${err.message}`;   // fallback ui
    }
  };
});

🚨 Comprehensive error handling patterns

SimpliJS does not swallow errors – it delegates to hooks and provides fallbacks.

ScenarioError objectHandled by
render() throwsRenderErrorconsole.log + engine fallback
event handler throwsoriginal errorwindow.onerror
watch / computed throwsoriginalconsole.log + re-throws
form validation error (custom)n/aconfig.onError / UI classes
bridge import failsImportErrorconsole.log
// top‑level error boundary pattern (wrapping component)
component('error-boundary', () => {
  const state = reactive({ hasError: false, errorMsg: '' });
  return {
    onError: (err) => {
      state.hasError = true;
      state.errorMsg = err.message;
    },
    render: () => state.hasError
      ? `<div>🔥 crash: ${state.errorMsg}</div>`
      : `<inner-component />`   // child may throw
  };
});

🧩 Slot projection

SimpliJS v3.2.0 supports full content projection via s-slot and default slots.

component('user-layout', () => ({
  render: () => `
    <header><s-slot name="header" /></header>
    <main><s-slot /></main>
  `
}));

📌 TypeScript / JSDoc quick template

/**
 * @param {HTMLElement} el
 */
function setup(el) {
  return {
    render: () => `
Component is active
` }; } component('typed-demo', setup);

Use the included simplijs.d.ts for full IDE autocompletion.