Documentation
Core Utilities
Lazy, Logger, and the non-UI nanolib primitives every project needs.
@alwatr/core is a pure aggregator over the non-UI half of @alwatr/nanolib — utilities with zero DOM assumptions, so they run identically in the browser, Bun, or Node. Two of them are load-bearing enough for the rest of the docs to lean on directly: Lazy and Logger.
Lazy
A generic, memory-efficient deferred-initialization wrapper. The initializer runs on first .instance access, is cached forever, and is then deleted (not nulled) from the object — a strong hint to V8 that the closure can be reclaimed.
import {lazy} from '@alwatr/core';
const db = lazy(() => new DatabaseConnection(config));
db.isInitialized(); // false
const conn = db.instance; // initializer runs here, cached forever
db.isInitialized(); // truelazy(...) is preferred over new Lazy(...) for better type inference. There is deliberately no reset() — Lazy is a permanent-singleton primitive; reach for a StateSignal if you need resettable or reactive state, and @alwatr/flatomise or Signals if you need async support.
Commonly paired with EmbeddedDataCollector for deferred SSR-data extraction (see Storage & Hydration) and with StateSignal subscriptions for lazily initializing a service only once something actually needs it.
Logger
A scoped, colorful console logger whose debug-only methods are stripped entirely in production. createLogger(scopeName) returns an instance with methods grouped by intent:
| Method | Use for |
|---|---|
banner(message) | A prominent startup/version message. Always active. |
logMethod?.(name) / logMethodArgs?.(name, args) | Method-entry tracing — dev-mode only, called with ?.(). |
incident?.(method, code, ...) | An expected, recoverable event — informational, not alarming. |
accident(method, code, ...) | Unexpected but recoverable — console.warn. |
error(method, code, ...) | Critical, unrecoverable — console.error. Never stripped. |
import {createLogger} from '@alwatr/core';
const logger = createLogger('api-service');
logger.banner('API Service Initialized — v2.0');
function fetchData(url: string) {
DEV_MODE && logger.logMethodArgs?.('fetchData', {url});
try {
// ...
} catch (error) {
logger.error('fetchData', 'network_failure', error, {url});
}
}This is exactly the pattern used across every Alwatr app layer: DEV_MODE && this.logger_.logMethodArgs?.(...) — the DEV_MODE && guard lets a bundler dead-code-eliminate the whole call in production, and the optional-chained call keeps it a no-op even when it isn't.
Debug mode
NODE_ENV=developmentauto-enables debug output.- In the browser, override with
localStorage.setItem('ALWATR_DEBUG', '1'). - In Node/Bun, override with the
DEBUG=1environment variable.
The logger preserves accurate call-site file/line attribution in devtools — its own internals never pollute the stack trace.
Other primitives
Everything covered in the Flux family pages — @alwatr/signal, @alwatr/action, @alwatr/directive, @alwatr/bind, @alwatr/embedded-data, @alwatr/local-storage, @alwatr/session-storage — can be installed and used completely standalone, without pulling in the rest of @alwatr/flux. Beyond those, @alwatr/core also bundles smaller utilities worth knowing about:
@alwatr/debounce— a type-safe, framework-agnostic debouncer, used internally by every storage-backed signal for write-debouncing.@alwatr/dedupe— a dev-time helper that detects and warns about duplicate-version imports of the same package across an app.@alwatr/deep-clone,@alwatr/fetch,@alwatr/resolve-url,@alwatr/parse-duration, and a handful of hashing utilities (cyrb53,djb2-hash) round out the bundle.