Getting Started — For Developers

Key concepts, codebase orientation, and entry points for developers extending the platform

Getting Started — For Developers

This guide is for developers who are extending the platform — building custom widgets, writing Action blocks, integrating APIs, or deploying new application types.

Prerequisites

  • Node.js 24+
  • MongoDB (see setup below)
  • Basic familiarity with TypeScript and SvelteKit

Repository structure

The codebase is a Turborepo monorepo with three main packages and four apps:

apps/
  backoffice/      Admin SvelteKit app (localhost:5173)
  applications/    End-user SvelteKit app (localhost:5174)
  docs/            This docs site (localhost:5175)
packages/
  shared/          Types, constants, utils — no UI, no server deps
  client/          Svelte components and widgets
  server/          Backend services and API handlers

Package dependency boundaries (enforced by Turborepo):

  • shared → no dependencies on client or server
  • client → can use shared only
  • server → can use shared only
  • Apps → can use any package

Local setup

npm ci
npm run mongodb            # must be running before dev or tests (uses Docker)
npm run dev                # starts all apps

The first npm run dev takes 5+ minutes to build. Subsequent starts are faster.

Key architectural concepts

Widget system

The core UI primitive is a widget. Every data type gets three companion widgets:

  • InputWidget — the form/edit UI
  • ViewWidget — read-only display
  • FilterWidget — search/filter UI

Widgets are registered at app startup via lazy imports. Their schemas live in packages/shared/src/widgets/widget-schemas.ts.

→ Full guide: Widget System

Local-first / real-time data

The platform uses SignalDB for client-side data management. Data is synced incrementally from the server using updatedAt filtering. The client works offline and syncs when connectivity returns.

→ See: Local-First Architecture

Actions system

The Actions system is a visual workflow engine. Blocks are the building blocks — each block receives inputs via typed sockets and produces outputs. You can add custom blocks and custom triggers.

→ See: Actions Developer Guide

Svelte 5 runes

All reactive state uses Svelte 5 runes — $state, $derived, $effect. Do not use Svelte 4 stores (writable(), readable()).

i18n

All user-facing strings must go through the t() function. Never hardcode text. Run npm run i18n:check-placeholders before committing.

Important conventions

Convention Rule
Imports Use @smallstack/shared, @smallstack/client, @smallstack/server — no relative cross-package imports
Formatting Tabs, double quotes, no trailing commas (enforced by Biome)
Commits Conventional commits format: feat(scope): subject
Tests Always use TZ="Europe/Berlin" prefix. MongoDB must be running.
Icons FontAwesome v6 only

Where to go next