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.
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 inmemory,session, orlocalStorage. 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