mcpField
M
moostjs

moostjs

github.com/moostjsDevelopment546 installsUpdated today
Repository

About moostjs

Moost is a metadata-driven TypeScript event-processing framework for developers building HTTP, CLI, WebSocket, or workflow applications. Its adapter model lets controllers handle multiple event types while sharing dependency injection, interceptors, and pipes.

Key features

  1. 01Decorator-based event handlers
  2. 02HTTP, CLI, WebSocket, and workflow adapters
  3. 03Shared dependency injection
  4. 04Shared interceptors and pipes

Use cases

  1. 01Building HTTP and CLI applications
  2. 02Serving WebSocket messages alongside HTTP
  3. 03Defining multi-step workflows

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/moostjs/moostjs --skill moostjs

After installing, type/moostjsin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

references/
core.md
custom-adapters.md
decorators.md
di.md
event-cli.md
event-http.md
event-wf.md
event-ws.md
http-auth.md
http-request.md
http-response.md
interceptors.md
otel.md
pipes.md
swagger.md
vite.md
ws-rooms.md
ws-testing.md

Details

From the project README

Moost

Metadata-driven event processing framework for TypeScript. Decorators + composables (via Wooks) handle HTTP, CLI, WebSocket, Workflow events. Each event type = one adapter. No module abstraction — controllers register directly on Moost. DI, interceptors, pipes are shared across all adapters. A single controller can expose @Get, @Cli, @Message methods simultaneously; each adapter binds only its own handler type.

Powered by: @prostojs/mate (metadata), @prostojs/infact (DI), @wooksjs/event-core (async event context), @prostojs/dye (compile-time terminal colors).

Domain map — load only what you need

DomainFileLoad when
Core concepts, Moost class, lifecycle, registration, app init/disposecore.mdNew project, multi-adapter setup, app.init(), @MoostInit/@InjectMoost/app.addInitHook(), boot-time setup, Moost subclass, app.dispose()/@MoostDispose, graceful shutdown, disposeOnSignals() (SIGTERM/SIGINT handler, MaxListenersExceededWarning on dev reload, Ctrl-C disposes the wrong app), resources leaking across hot reloads, duplicate timers/jobs after reload
Decorators, metadata, custom decorators, Matedecorators.mdCreating/using decorators, reading metadata, subclassing controllers / @Inherit / parent routes 404 / diagnostics.inheritance
DI scopes, @Injectable, @Inject, @Provide, @Circulardi.mdServices, scoping, providers, replacements; running code as another controller (withControllerContext, forkEventContext)
Interceptors: priority, @Intercept, guards, class-basedinterceptors.mdAuth/logging/error cross-cutting
Pipes: @Pipe, @Resolve, TRANSFORM/VALIDATEpipes.mdValidation, transformation, custom param decorators
Custom adapter: TMoostAdapter, defineMoostEventHandlercustom-adapters.mdBuild an adapter for a new event source
HTTP setup/routingevent-http.mdMoostHttp, route decorators, handler returns, fetch/SSR, invoke (route inside the current request), withHttpContext, forwardHeaders/DEFAULT_FORWARD_HEADERS, anonymous 127.0.0.1 self-calls
HTTP request datahttp-request.md@Query/@Header/@Cookie/@Body/@Req/@Res/@Ip
HTTP response controlhttp-response.md@SetStatus/@SetHeader/@SetCookie, refs, body limits, HttpError
HTTP auth guardshttp-auth.mddefineAuthGuard, AuthGuard, @Authenticate
CLIevent-cli.mdCliApp, @Cli/@CliOption, help, CLI interceptors
Workflowevent-wf.md@Step/@Workflow/@WorkflowSchema, pause/resume, outlets, state strategies
WebSocket coreevent-ws.mdMoostWs/WsApp, @Message/@Connect/@Disconnect, wire protocol
WebSocket roomsws-rooms.mduseWsRooms, broadcasting, WsBroadcastTransport
WebSocket testingws-testing.mdprepareTestWsMessageContext / prepareTestWsConnectionContext
Vite plugin: dev/build, middleware, SSR/SPA, deployvite.mdmoostVite, vite.config.ts, createSSRServer, ssrEntry/serverEntry, ssr.noExternal/ssr.external, ssrExternalCheck, dev-server split warning / "loaded natively by Node in dev" / instantiate(MoostHttp) fails only under vite serve, dist/server, HMR, "undefined useRequest() in prod", "Cannot read properties of undefined (reading 'headers')", externalized dep calling wooks composables, dev server serves a half-booted app / some API routes return index.html after an edit / app.init() error not showing in dev / "502 Moost app failed to load" / does the plugin wait for init(), SSR render contract / per-page head-SEO / status / ssrHead / TSSRRenderResult / TSSRRenderContext / ssrFetchForwarding (SSR viewer identity)
Swagger/OpenAPIswagger.mdSwaggerController, Swagger* decorators, OpenAPI spec generation, spec.json/UI serving, securitySchemes
OpenTelemetryotel.mdenableOtelForMoost, spans/tracing, @OtelIgnoreSpan/@OtelIgnoreMeter, span processors, useOtelContext/useSpan/withSpan, moost.event.duration metrics
RBAC/ABAC access control@aooth/arbac-moost (aooth docs)auth, roles/scopes, authorize guards — NOT part of this repo; @moostjs/arbac is deprecated, superseded by aooth

Scaffold

npm create moost@latest [name] -- [--http|--cli|--ws|--ssr] [--wf] [--oxc] [--force]

Pass at most ONE project-type flag (--http --ws is the exception: HTTP app + WebSocket add-on). Flags pre-select add-ons and skip the corresponding interactive toggles. Details: core.md.

Quick start

import { Moost } from 'moost'
import { MoostHttp } from '@moostjs/event-http'

const app = new Moost()
app.adapter(new MoostHttp()).listen(3000)
app.registerControllers(AppController)
await app.init()

Other entry points:

  • CLI: new CliApp().controllers(AppController).useHelp({ name: 'my-cli' }).start() — sugar over Moost + MoostCli (event-cli.md)
  • Standalone WS: await new WsApp().controllers(ChatController).start(3000) (event-ws.md)
  • Multi-adapter sharing one HTTP server: capture the adapter first — const http = app.adapter(new MoostHttp()), then http.listen(3000) and app.adapter(new MoostWs({ httpApp: http.getHttpApp() })) (event-ws.md)
  • A Moost subclass is itself a controller — decorate its methods directly (core.md)

Cross-cutting facts

DI scopes — @Injectable() / @Injectable(true) / @Injectable('SINGLETON') = one instance for app lifetime. @Injectable('FOR_EVENT') = fresh instance per event. @Controller() implicitly sets @Injectable(true) (SINGLETON). Use 'FOR_EVENT' when class properties hold per-request state or when using property-level ref/resolver decorators. FOR_EVENT requires an active event context (composables don't work in SINGLETON constructors). Scope lifetime (HTTP response + handler, per-event ownership for workflow runs and WS messages, pre-0.6.42 scope isn't registered bugs): di.md#scopes.

Wooks composables work inside handlers — All @wooksjs/* composables (e.g., useRequest, useResponse, useHeaders) work directly in Moost handlers; they run in the same event context.

Logging — composable: useLogger('topic') (from moost, re-exported from @wooksjs/event-core). Property: @InjectEventLogger() (per-event) / @InjectMoostLogger('topic') (app-level, falls back to @LoggerTopic, then class @Id). Standalone: createLogger({ transports: [loggerConsoleTransport] }) — loggerConsoleTransport is an already-constructed transport constant; pass it, don't call it.

Re-exports — moost re-exports current, useLogger, key, cached, eventTypeKey, createEventContext, run from @wooksjs/event-core, plus createProvideRegistry/createReplaceRegistry from @prostojs/infact. moost also exports its own globalKey(name) — a duplication-safe context-key factory (interns the slot by name via globalThis); use it instead of key for any moost-owned context key so set/get can't desync when moost is loaded more than once (dual ESM/CJS, or a duplicated install). @moostjs/event-http re-exports httpKind, HttpError, useHttpContext, prerenderJson (+ type TPrerenderJsonOptions). @moostjs/event-cli re-exports cliKind, and Param/Controller/Intercept/Description/Optional/defineBeforeInterceptor/defineAfterInterceptor/defineInterceptor from moost (note: defineErrorInterceptor is NOT re-exported — import from moost). @moostjs/event-wf re-exports wfKind, useWfState, StepRetriableError, outlet primitives. @moostjs/event-ws re-exports wsConnectionKind/wsMessageKind, WsError, all useWs* composables, currentConnection, prepareTestWs*.

Architecture pointers

  • Decorator system — all decorators go through getMoostMate() (singleton Mate, 'moost' workspace); metadata read at bind time: decorators.md
  • Interceptor priorities & phases — interceptors.md
  • Pipe priority order & scope levels — pipes.md
  • Event handler lifecycle (defineMoostEventHandler) — custom-adapters.md
  • Adapter pattern — each adapter implements TMoostAdapter<H>, attached via app.adapter(a), filters opts.handlers by its own handler.type: custom-adapters.md

Comments

Markdown supported