SDK overview
@symorva/sdk — the community manifest schema, module catalog, validator, deployment planner, templates and CLI.
@symorva/sdk is the source of truth for what a Symorva community is. It defines the manifest schema, holds the module catalog, validates manifests against the schema and the composition rules, resolves a manifest into a deployment plan, and ships the symorva CLI. The website, these docs and the planner all read module metadata from the same catalog.
The SDK is in developer preview, version 0.1.0. It works today but is not published to a public package registry; the Symorva team distributes it to design partners. Contact the team for access.
What is in the package
| Part | Entry point | Purpose |
|---|---|---|
| Manifest schema | manifestSchema, parseManifest, defineCommunity | Shape, defaults, ranges and formats of symorva.config.json |
| JSON Schema | manifestJsonSchema(), schema/community.v1.json | Editor completion and validation for non-TypeScript tooling |
| Module catalog | MODULES, MODULE_IDS, SHARED_SERVICES, PLATFORMS, PLATFORM_DELIVERY | Metadata for every module, shared service and platform target |
| Validator | validateManifest, enabledModules, LARGE_ROOM_THRESHOLD | Two-pass validation with stable diagnostic codes |
| Planner | planDeployment, resolveCommunity | Resolve a manifest into owned components, shared services, clients, navigation and privacy |
| Templates | TEMPLATES, templateManifest, slugify | Starter manifests for dao, creator, team and ecosystem |
| CLI | symorva | init, validate, plan, modules — see the CLI reference |
The package is an ES module with TypeScript types and a single runtime dependency for schema validation.
Validate and plan
resolveCommunity validates and plans in one step. It returns the plan when the manifest is valid and only diagnostics when it is not.
import { readFileSync } from "node:fs";
import { resolveCommunity } from "@symorva/sdk";
const input = JSON.parse(readFileSync("symorva.config.json", "utf8"));
const result = resolveCommunity(input);
if (!result.ok) {
for (const d of result.diagnostics) {
console.error(`${d.level} ${d.code} at ${d.path}: ${d.message}`);
}
process.exit(1);
}
const { plan } = result;
console.log(plan.modules); // ["chat", "meetings", "aiStudio", ...]
console.log(plan.navigation); // ["Community", "Meetings", "AI Studio", ...]
for (const service of plan.shared) {
console.log(service.id, service.usedBy, service.meteredUnits);
}To keep the steps separate — for example to show warnings before planning — call them individually:
import { planDeployment, validateManifest } from "@symorva/sdk";
const result = validateManifest(input);
if (result.ok) {
const plan = planDeployment(result.manifest, result.diagnostics);
}validateManifest returns the manifest with defaults applied. When only the schema pass fails, no manifest is returned; when a composition rule fails, the parsed manifest is returned alongside the diagnostics so tools can still inspect it.
Write a manifest in TypeScript
defineCommunity is a typed identity helper: it returns its input unchanged and gives you completion and type checking while you write. Validation still happens in validateManifest.
import { defineCommunity, validateManifest } from "@symorva/sdk";
export const community = defineCommunity({
schemaVersion: 1,
community: { id: "orbit-collective", name: "Orbit Collective", locales: ["en", "zh-Hans"] },
brand: { primaryColor: "#6E5BFF", theme: "system" },
modules: {
aiStudio: { enabled: true, chatContentAccess: "member-grant" },
},
platforms: ["ios", "android-apk"],
deployment: { mode: "managed", region: "eu-central" },
});
const result = validateManifest(community);The CLI reads JSON only. To use the CLI with a TypeScript manifest, write it out with JSON.stringify(community, null, 2) to symorva.config.json.
Generate a starter manifest
import { templateManifest } from "@symorva/sdk";
const manifest = templateManifest("creator", { name: "Lumen Studio" });
// manifest.community.id === "lumen-studio"templateManifest(id, overrides) accepts name and primaryColor overrides. The name is converted into community.id by slugify: lowercase ASCII letters and digits are kept, every other run of characters becomes a single hyphen, and the result is trimmed to 40 characters; a slug shorter than two characters falls back to my-community. For names with accented or non-Latin characters, check the generated community.id and edit it if needed — the id is the stable identifier and should not change after launch.
Read the catalog
import { MODULES, SHARED_SERVICES } from "@symorva/sdk";
MODULES.meetings.requires; // ["chat"]
MODULES.meetings.sharedServices; // ["media"]
MODULES.meetings.meteredUnits; // ["participant-minutes", "broadcast-viewer-minutes"]
MODULES.wallet.ownedComponent.id; // "wallet-service"
SHARED_SERVICES.ai.name; // "AI inference & generation"Key types
Prop
Type
Prop
Type
The second table is DeploymentPlan. Full field definitions for the manifest are on the Manifest reference.
Versioning
The manifest carries schemaVersion: 1. Changes that would invalidate an existing valid manifest will ship under a new schema version. Within a schema version, new optional fields and new diagnostics with level warning or info may be added during the preview.