@omen.foundation/node-microservice-runtime
v0.1.123
Published
Beamable microservice runtime for Node.js/TypeScript services.
Readme
@omen.foundation/node-microservice-runtime
TypeScript/Node.js runtime for Beamable microservices: WebSocket gateway integration, dependency injection, OpenAPI generation, MongoDB storage helpers, optional federation, logging (OpenTelemetry / collector), and a beamo-node CLI for validate/publish workflows.
Requirements
- Node.js
>= 22.14.0(seeenginesinpackage.json). - ESM projects:
"type": "module"in your servicepackage.json. reflect-metadataimported once before any decorated classes load (required for decorators / DI).
Install
npm install @omen.foundation/node-microservice-runtime reflect-metadataThe package ships:
- Library — decorators,
runMicroservice(), DI tokens, storage/federation helpers. - CLI —
beamo-node(login, scaffold, validate, publish, …).
Minimal service shape
package.json— declare the Beamable service id (must match@Microservicename):
{
"name": "my-game-service",
"type": "module",
"main": "dist/main.js",
"scripts": {
"dev": "tsx --env-file .env src/main.ts",
"build": "tsc -p tsconfig.json",
"validate": "npx beamo-node validate --env-file .env",
"publish": "npx beamo-node publish --env-file .env"
},
"beamable": {
"beamoId": "MyGameService",
"projectType": "service"
}
}- Entry file — load metadata, import the class that carries
@Microservice, then start:
import 'reflect-metadata';
import './MyGameService.js';
import { runMicroservice } from '@omen.foundation/node-microservice-runtime';
void runMicroservice();- Service class — exactly one class decorated with
@Microservice('Name')(name must matchbeamable.beamoId).
Decorators and HTTP access
| Decorator | Typical use |
|-----------|-------------|
| @Microservice('ServiceName') | Registers the service (required, one per process). |
| @Callable | General callable; access via access option or use a specialized decorator below. |
| @ClientCallable | Game/client calls; expects authenticated user. |
| @ServerCallable | Trusted server-to-server style routes. |
| @AdminCallable | Admin-scoped routes. |
| @ConfigureServices | Static method receiving DependencyBuilder — register singletons, factories. |
| @InitializeServices | Static method receiving scope — run after container is built. |
| @SwaggerCategory / @SwaggerTags | OpenAPI grouping. |
| @StorageObject('StorageName') | Registers a named Beamable storage binding (MongoDB). |
| @FederatedInventory | Optional federation hook for inventory-style flows. |
Handlers receive RequestContext (userId, cid, pid, logger, provider for DI resolution, etc.).
Environment: Beamable vs beam.env
Required for a running service
The runtime calls loadEnvironmentConfig(), which requires:
CID— customer idPID— project / realm idHOST— WebSocket host (e.g.wss://api.beamable.com/socket)SECRET— signing secret (when used by your deployment; local CLI may use tokens instead)
Optional common variables include REFRESH_TOKEN, NAME_PREFIX / ROUTING_KEY, LOG_LEVEL, HEALTH_PORT (defaults to 6565 when not set or invalid).
Developer file: beam.env
The runtime loads beam.env (or .beam.env) from, in order:
process.cwd()/beam.envor.beam.env/beam/service/beam.envor.beam.env(typical container layout)
Rules:
- Format:
KEY=value,#comments, optional quotes for values. - Does not override variables already in
process.env.
See the published beam.env.example in this package for a starting template.
Beamable Config API
Config from the portal can be merged in asynchronously (with a short timeout). Keys are exposed as BEAM_CONFIG_*. Details are summarized in AGENTS.md and ai/RUNTIME_FOR_AI.md.
OpenAPI / validate / publish without starting the server
Tools set:
BEAMABLE_SKIP_RUNTIME=trueso runMicroservice() returns immediately while your module graph still loads for schema generation.
Docker (production-oriented)
Recommended patterns used in production games:
- Working directory — use
/beam/serviceso the defaultbeam.envsearch path matches the runtime. - Copy artifacts —
dist/,package.json, lockfile,beam_openApi.json(if generated), andbeam.env(or inject secrets via orchestrator and skip copying secrets into images where policy forbids it). - Health checks — expose the HTTP health port (default 6565, overridable with
HEALTH_PORT). - Collector startup — pre-installing the Beamable OpenTelemetry collector under
/opt/beam/collectors/...avoids a multi-second download on cold start. Seeai/RUNTIME_FOR_AI.mdfor an example multi-stageDockerfilefragment.
Your game may use Node 20 images today; the runtime’s declared engine is Node 22+ — align image version with engines before upgrading the dependency.
CLI: beamo-node
Installed as a binary with the package:
npx beamo-node --helpTypical project scripts:
npx beamo-node validate --env-file .env
npx beamo-node publish --env-file .envLogin and scaffolding commands create a local profile under ~/.beamo-node/.
beamo-node scaffold <name> creates a new project that includes AGENTS.md, CLAUDE.md, ai/ (reference docs), .cursor/rules/beamable-node-microservice.mdc, and a short README.md pointing at those files.
TypeScript
Enable decorator metadata in tsconfig.json:
{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"module": "NodeNext",
"moduleResolution": "NodeNext",
"target": "ES2022"
}
}MongoDB / @StorageObject
- Decorate a class with
@StorageObject('MyStorage'). - Connection string env var:
STORAGE_CONNSTR_<MyStorage>(see runtimeStorageService— name is normalized). - Optional pool sizing:
MONGODB_MAX_POOL_SIZE(clamped).
Import storage classes before services that depend on them so decorators register.
AI assistants / agents
This package includes AGENTS.md (short rules), CLAUDE.md (index for AI tools), and ai/RUNTIME_FOR_AI.md (deep reference: Dockerfile, env, pitfalls). Point Cursor, Claude Code, Codex, or other tools at those files when generating or refactoring Beamable Node microservices. Optional Cursor rule text lives in ai/cursor-rule-snippet.md.
License
MIT
