Chinook Home Sign in

The Chinook SDK

Two surfaces, documented separately, because they are used by different people solving different problems and mixing them is how the wrong one gets called.

GuidePackageRuns inRead it if you are
[Server — ChinookBE](server.md)@chinook/serverThe tenant's own backendWriting server code: reading rows, running jobs, sending notifications
[Frontend — ChinookFE](client.md)@chinook/clientThe browserWriting screens: binding entities, calling AI, uploading files
How it fits togetherNew here, and want the shape of the whole thing first
[Getting started](getting-started.md)New to Chinook and want the whole path once
[Recipes](recipes/)After a specific task

The one thing to know before either

Both surfaces use the same method names for the same capability (ADR-069 D1). saveEntity is saveEntity on both; chat is chat on both. What differs is what happens underneath:

ChinookFE.data.create(…)   ─▶  the app's own backend
                                 └▶ ChinookBE.data.create(…)  ─▶  Postgres, with RLS armed
ChinookFE.ai.chat(…)       ─▶  either its own backend or the Chinook API directly,
                               depending on the capability's route (ADR-068 D2)

That is deliberate. Which surface a call goes to is a kernel decision made from the capability catalogue, not a property of how the call was written, so a capability can move between routes without a single generated app changing.

Where a name comes from

Namespaces are the spec's services — SERVICE_KEYS in @chinook/spec — plus three roots that are not services because they cannot be switched off: data, spec, health (ADR-069 D2).

No namespace spells a provider. payments.charge(), never adyen.charge(). A provider's name is data, never API (ADR-056), so the same call works whichever processor or model the spec routes it to, and neither guide will teach you a vendor's vocabulary.

Three ways a namespace can answer

AnswerMeansWhat to do
It worksConfigured and implemented
not_configuredImplemented; this process was not given its dependencyPass it to createKernel()
not_builtThe spec declares it; the kernel has not implemented itNothing — see HANDOFF §3

All three exist as objects. A missing namespace would fail as undefined is not a function, which names your call site and nothing about the cause.