Prerequisites
Before working with a Neemata project, check if node_modules/nmtjs exists. If not, install the nmtjs package using the project's package manager (e.g., pnpm add nmtjs).
Do not install internal @nmtjs/* packages directly. The nmtjs umbrella package re-exports everything users need. Transport packages (@nmtjs/ws-transport, @nmtjs/http-transport) are separate dependencies for server-side application definitions only:
pnpm add nmtjs @nmtjs/ws-transport @nmtjs/http-transportFor client-side usage, install:
pnpm add nmtjs @nmtjs/ws-client # or @nmtjs/http-clientFinding Documentation
Search source code in node_modules/nmtjs/:
- Public API:
grep -r "query" node_modules/nmtjs/src/ - Core DI:
grep -r "query" node_modules/@nmtjs/core/src/ - Contract types:
grep -r "query" node_modules/@nmtjs/contract/src/ - Type system:
grep -r "query" node_modules/@nmtjs/type/src/ - Protocol:
grep -r "query" node_modules/@nmtjs/protocol/src/
Key Concepts
Import Convention
All user-facing code should import from nmtjs:
import { n, t, c, Scope, ErrorCode, ProtocolBlob, ConnectionType } from 'nmtjs'n— Namespace with all builder functions (n.procedure,n.router,n.app,n.server, etc.)t— Type system (wraps zod/mini with encode/decode, e.g.,t.string(),t.object(),t.date())c— Contract definitions (c.procedure(),c.router(),c.event(),c.blob())Scope— DI scopes:Global,Connection,Call,Transient
Architecture
Neemata uses a layered architecture:
- Config (
neemata.config.ts) — defines applications and server entry point viadefineConfig() - Server (
n.server()) — orchestrates workers, proxy, store, metrics - Application (
n.app()) — defines transports, router, guards, middleware for one app - Router (
n.rootRouter()/n.router()) — groups procedures - Procedure (
n.procedure()) — individual RPC endpoint with input/output types and handler - Client (
StaticClient/RuntimeClient) — type-safe RPC calls
Dependency Injection Scopes
Scope.Global— Singleton, lives for entire app lifetimeScope.Connection— Per WebSocket/HTTP connection, disposed on disconnectScope.Call— Per RPC call, disposed after handler completesScope.Transient— New instance on every injection
Containers form a hierarchy: Global → Connection → Call. A scope can only depend on same-or-higher scopes.
Streaming
Two streaming mechanisms:
- RPC Streams — Procedure returns
AsyncIterable, setstream: true. Client consumes viaclient.stream.* - Blob Streams — Binary data via
ProtocolBlob.from()(client) andcreateBlobinjectable (server). Usec.blob()in contracts
When Typecheck Fails
- Check the relevant reference for correct usage:
- Check API Quick Reference for correct signatures
- Search
node_modules/nmtjs/src/for current type definitions - Verify you're importing from
nmtjs(not internal@nmtjs/*packages)
Project Structure
A typical Neemata project follows this structure:
project/
neemata.config.ts # defineConfig — app entries + server path
src/
index.ts # n.server({...}) — server configuration
applications/
main/
index.ts # n.app({...}) — application definition
router.ts # n.rootRouter([...]) — route tree
procedures/
example.ts # n.procedure({...}) — RPC handlers
guards/
middleware/
injectables/References
- API Quick Reference — Function signatures and options for
n.*,t.*,c.*APIs - Type System —
t.*encode/decode modes, inference, and Standard Schema (JSON Schema) support - RPC — Procedures, routers, streaming, blobs, contracts, guards, middleware, filters, error handling
- Injectables — DI scopes, injectable builders (value/lazy/factory), built-in
n.inject.* - Server Setup —
n.app(),n.server(),defineConfig(), project structure - Client Usage —
StaticClientsetup, RPC calls, streams, blobs, abort - Jobs — Background jobs, steps, job manager, retry/backoff, progress, job router