SeptemCore LogoSeptemCore
Getting Started

Quickstart

Go from zero to a running Platform-Kernel module in five steps. Scaffold, connect to the sandbox, and make your first SDK call in under 15 minutes.

This guide takes you from a blank directory to a working module registered in Platform-Kernel in five steps. You will need Node.js 26+ and a running sandbox environment.

Prerequisites

ToolVersionNotes
Node.js≥ 26 LTSUse fnm or nvm for version management
pnpm≥ 10npm install -g pnpm
Docker + Compose≥ 26Required for the sandbox
Go≥ 1.26.1Required only if you extend backend services

No Go installation is needed for pure frontend/SDK module development.


Step 1 — Start the Developer Sandbox

The sandbox is a complete single-machine replica of the production kernel stack. It provides pre-seeded tenants, users, and roles so you can work without any manual setup.

# Clone the kernel repository (or the SDK-only companion repo if provided)
git clone https://github.com/septemcore/platform-kernel.git
cd platform-kernel/.dev/kernel

# Start the full stack (PostgreSQL, ClickHouse, Kafka, RabbitMQ, Valkey, Vault, all services)
docker compose -f docker/docker-compose.yml up -d

# Verify all services are healthy
docker compose -f docker/docker-compose.yml ps

When every service shows healthy, the kernel is ready:

ServiceURLNotes
API Gatewayhttp://localhost:8080Single entry point for all REST API calls
UI Shellhttp://localhost:3000Admin panel (demo tenant pre-seeded)
Audit LogInternal only; query via /api/v1/audit

Seed credentials

The sandbox includes a pre-seeded demo tenant. Log in to the UI Shell with:


Step 2 — Scaffold Your Module

Use the official scaffolding CLI to generate a fully-configured module skeleton:

# Scaffold a new module named "my-crm"
npx @platform/create-module@latest my-crm --description "A simple CRM module"

# The generator creates:
# my-crm/
# ├── module.manifest.json   ← Module contract (see Project Structure)
# ├── federation.config.js   ← Module Federation 2.0 remote config
# ├── package.json
# ├── tsconfig.json
# ├── src/
# │   └── pages/
# │       └── index.tsx      ← Main React entry component
# └── migrations/            ← SQL migration files (goose format)

cd my-crm
pnpm install

The generated module.manifest.json declares your module's identity and capabilities:

{
  "name": "@demo/my-crm",
  "version": "1.0.0",
  "description": "A simple CRM module",
  "kernelSdkVersion": "^1.0.0",
  "entry": "",
  "exposedComponent": "MyCrmModule",
  "route": "/crm",
  "icon": "Users",
  "permissions": ["crm.contacts.read", "crm.contacts.write"],
  "events": {
    "publishes": ["crm.contact.created"],
    "subscribes": ["auth.user.created"]
  },
  "healthCheck": "/health",
  "dependencies": {
    "@platform/sdk-auth": "^1.0.0",
    "@platform/sdk-data": "^1.0.0"
  }
}

Manifest is the source of truth

The kernel reads module.manifest.json at registration time. Every permission, event subscription, and data model your module uses must be declared here — undeclared access is rejected at the API Gateway level.


Step 3 — Install SDK Packages

Install only the primitives your module needs. Each primitive maps to one SDK package:

# Core package (always required — provides types, HTTP client, error handling)
pnpm add @platform/sdk-core

# Add primitives as needed
pnpm add @platform/sdk-auth    # Authentication, RBAC, session management
pnpm add @platform/sdk-data    # CRUD, realtime, analytics
pnpm add @platform/sdk-events  # Kafka/RabbitMQ/browser events
pnpm add @platform/sdk-notify  # Notifications (WebSocket, email, SMS, …)
pnpm add @platform/sdk-files   # File upload, image processing
pnpm add @platform/sdk-money   # Wallets, transactions, holds
pnpm add @platform/sdk-audit   # Audit trail recording

# UI Design System (optional — Tailwind v4 + Radix UI components)
pnpm add @platform/sdk-ui

# Development tools
pnpm add -D @platform/sdk-testing  # Mocks and fixtures for Vitest

Step 4 — Make Your First SDK Call

Open src/pages/index.tsx and replace the scaffold contents with a simple contact list that uses the Data and Auth primitives:

import { useAuth } from '@platform/sdk-auth';
import { useQuery } from '@platform/sdk-data';

interface Contact {
  id: string;
  name: string;
  email: string;
  created_at: string;
}

export default function MyCrmModule() {
  // Access current user and tenant from JWT context
  const { user, tenant } = useAuth();

  // Query the 'contacts' model — auto-generated REST endpoint.
  // Resolves to: GET https://api.septemcore.com/api/v1/data/my-crm/contacts?page_size=20
  const { data: contacts, isLoading } = useQuery<Contact>('my-crm', 'contacts', {
    page_size: 20,
    order: 'created_at.desc',
  });

  if (isLoading) {
    return <div>Loading contacts...</div>;
  }

  return (
    <div>
      <h1>CRM — {tenant.name}</h1>
      <p>Logged in as {user.email}</p>

      <table>
        <thead>
          <tr>
            <th>Name</th>
            <th>Email</th>
          </tr>
        </thead>
        <tbody>
          {contacts?.data.map((c) => (
            <tr key={c.id}>
              <td>{c.name}</td>
              <td>{c.email}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

Data primitive auto-generates your REST API

When you declare a model in module.manifest.json under dataApi.models, the Data Layer automatically creates five REST endpoints (GET, GET /:id, POST, PATCH /:id, DELETE /:id) and enforces RLS so queries only return rows belonging to the current tenant. See Data → CRUD Operations for the full contract.


Step 5 — Register Your Module and See It Live

With the sandbox running, register your module and activate it for the demo tenant:

# Start the dev server (hot-reload, proxied to sandbox API)
pnpm dev
# → Module Federation remote is now available at http://localhost:5173/remoteEntry.js

# In a separate terminal — register the module with the kernel.
# The CLI reads module.manifest.json automatically.
npx @platform/create-module register \
  --gateway http://localhost:8080 \
  --token <admin_jwt_from_sandbox> \
  --entry http://localhost:5173/remoteEntry.js

# Activate the module for the demo tenant
npx @platform/create-module activate \
  --gateway http://localhost:8080 \
  --token <admin_jwt_from_sandbox>

Open the UI Shell at http://localhost:3000 — your module now appears in the sidebar. The Module Federation remote is loaded dynamically; changes you make in src/ hot-reload without restarting the shell.


Development Workflow Summary

Loading diagram...
CommandWhat it does
pnpm devStarts local Module Federation remote + API proxy
pnpm buildProduction bundle (for publishing)
pnpm testRuns Vitest unit tests
pnpm typecheckTypeScript strict check

Next Steps

GuideWhat you will learn
Project StructureAnatomy of a module — every directory and file explained
Module ManifestFull module.manifest.json specification
Dev EnvironmentDocker Compose deep-dive and environment variables
Concepts → PrimitivesHow the seven primitives compose into module features

On this page