OKALIT

JS

OPINIONATED SPA FRAMEWORK

STYLE
STANDARDS
EVENTBUS
OKALIT

BUILD WITH LIT.
SCALE WITH OKALIT.

Okalit is an opinionated web framework built on top of Lit. It provides a batteries-included architecture for building modern single-page applications.

NO TYPESCRIPT OR JSX REQUIRED!

WEB STANDARDS FIRST

Built on pure, native Web Components. Okalit doesn't need a heavy virtual DOM. Lit's tagged template literals render to the real DOM with terrifying precision and speed.

// NATIVE PERFORMANCE AND COMPONENTS
import { html } from 'lit';
import { Okalit, defineElement } from '@core';
import styles from './spinner-simple.scss?inline';

@defineElement({
  tag: 'spinner-simple',
  styles: [styles],
})
export class SpinnerSimple extends Okalit {
  render() {
    return html`<span class="loader"></span>`;
  }
}

REACTIVE BY DEFAULT

Clean, declarative APIs via TC39 decorators. We use Signals from @lit-labs/signals to unleash a barrage of granular state updates across your entire app!

// GRANULAR REACTIVITY WITH SIGNALS
import { html } from "lit";
import { Okalit, defineElement } from "@core";
import { signal } from "@lit-labs/signals";

@defineElement({ tag: "counter-ui" })
export class CounterUI extends Okalit {
  
  // Signals act as class properties
  count = signal(0);

  render() {
    return html`
      <button @click="${() => this.count.set(this.count.get() + 1)}">
        CLICKS: <span>${this.count.get()}</span>
      </button>
    `;
  }
}

OPINIONATED STRUCTURE

Stop wasting time deciding how to structure folders. Okalit is an opinionated framework featuring modules, pages, sections, components, services, layouts, and guards.

Routing, Dependency Injection, Event Bus, HTTP client, and i18n are all included!

// BUILT-IN ROUTING AND GUARDS
import { authGuard } from './guards/auth.guard.js';

export const routes = [
  {
    path: '/',
    component: () => import('./modules/home.js')
  },
  {
    path: '/dashboard',
    component: () => import('./modules/dashboard.page.js'),
    guards: [authGuard]
  }
];

EVENTBUS COMMUNICATION

The EventBus is Okalit's central communication system. It provides two distinct channels: stateful (persistent) and stateless (ephemeral). Communicate effortlessly between any component.

  • Stateful Channels
    Store values in memory, session, or localStorage. Subscribers receive the current value immediately on subscription, plus all future updates.
  • Stateless Channels
    Fire-and-forget events. No value is stored. Perfect for UI commands like opening modals or showing global spinners.
// LISTENING TO CHANNELS
import { html } from "lit";
import { Okalit, defineElement } from "@core";
import { modalGeoPerm } from '../mocks/modal.mock.js';

@defineElement({ tag: "home-page" })
export class HomePage extends Okalit {
  
  // Stateful channel (Persistent local storage)
  configApp = this.channel("global:config-app", {
    persist: "local",
    initialValue: { geolocationPermission: false },
    onValue: (val) => this.validateConfig(val),
  });

  validateConfig(value) {
    if (!value.geolocationPermission) {
      // Stateless channel (Fire-and-forget)
      this.trigger("global:modal", modalGeoPerm);
    }
  }

  render() {
    return html`<app-layout>...</app-layout>`;
  }
}
┌──────────────────────────────────────────┐
│ EVENTBUS CORE                            │
│                                          │
│ STATEFUL                  STATELESS      │
│ ──────────────            ────────────── │
│ emit() → notifies+stores  trigger() →fire│
│ on()   → subscribes       listen()  →subs│
│ get()  → reads value                     │
│                                          │
│ Storage: memory | session | local        │
└──────────────────────────────────────────┘
// 1. EMIT PERSISTENT DATA
this.emit('user:data', { id: 1 }, { persist: 'local' });

// 2. FIRE EPHEMERAL COMMANDS
this.trigger('global:spinner', true);

// 3. AUTO-CLEANED LISTENERS IN COMPONENTS
okalitConnections() {
  this.listen('data:loaded', (d) => this.data.set(d));
}

SYSTEM DIRECTORY

user@okalit:~# tree ./src
src/
├── main-app.js              // App entry point
├── app.routes.ts            // Root route definitions
├── core/                    // Framework core (Router, EventBus, DI)
├── guards/                  // Route guards
├── layouts/                 // Global layout components
├── components/              // Shared reusable UI elements
├── modules/                 // Feature boundaries
│   ├── auth/
│   │   ├── auth.module.js
│   │   ├── auth.routes.js
│   │   ├── components/
│   │   └── pages/
│   └── home/
│       ├── home.module.js
│       ├── home.routes.js
│       ├── pages/
│       ├── sections/
│       └── services/
├── styles/                  // Global SCSS/CSS
└── public/                  // Static assets

SUPPORT US

Okalit is an MIT-licensed open-source project. Hence, it grows thanks to the sponsors and support by the amazing backers.

Please, consider supporting us!