Civitai 发布 civitai-app-starters 起步模板与共享 SDK
civitai/civitai-app-starters
Civitai 开源 civitai-app-starters,提供四套 OAuth 应用模板(Next.js 15、SvelteKit 2、React 19 PWA、Svelte 5 PWA)及 civitai-block-starter,并配套 @civitai/app-sdk、@civitai/blocks-react 等 npm 包。
Starter templates for building on Civitai, plus the shared SDK packages they use. Two product surfaces live here:
- OAuth apps — full apps on your own domain that sign in with Civitai and
call the orchestrator. The four
starters/*templates +@civitai/app-sdk. - Civitai Apps — iframe-embedded UIs that render inside civitai.com pages
(e.g. a generator in a model's sidebar). Built with web components:
starters/civitai-block-starter(@civitai/sdk+ the<civitai-*>elements, no framework). React blocks use@civitai/blocks-react, as thestarters/examples/*do. See Civitai Apps below.
What's in here
packages/civitai-app-sdk— OAuth + PKCE, encrypted-cookie sessions, scope helpers, orchestrator-call helpers, AND the framework-agnostic Civitai Apps contract (/blockssubpath). Published to npm as@civitai/app-sdk.packages/civitai-blocks-react— React hooks + iframe transport for Civitai Apps. Published as@civitai/blocks-react.- Scaffolding + submit for Civitai Apps — handled by the Go
civitaiCLI (github.com/civitai/cli):civitai login→civitai app init/civitai app validate/civitai app submit. (Local dev is the scaffolded project's ownnpm run dev:harness/npm run dev:live.) The old@civitai/blocks-clinpm scaffolder it replaced stays published-but-deprecated on npm but is no longer part of this repo. starters/next-app— Next.js 15 (App Router) + Tailwind. SSR-friendly, SEO-capable. Best OAuth-app default.starters/sveltekit-app— SvelteKit 2 + Tailwind. Same demo surface asnext-app.starters/react-pwa— Vite + React 19 + tiny Hono BFF for OAuth token exchange. SPA/PWA shape.starters/svelte-pwa— Vite + bare Svelte 5 (no Kit) + tiny Hono BFF. SPA/PWA shape.starters/civitai-block-starter— Vite + TypeScript Civitai App scaffold built on web components (@civitai/sdk+@civitai/components, no UI framework).starters/examples/*— eleven minimal, runnable Civitai App examples, one per feature (see Civitai Apps).
The four OAuth starters ship the same minimal demo: log in via Civitai OAuth → show your Buzz balance (read with fetchBuzzAccount() — not from /api/v1/me, which returns none; hidden entirely when BuzzRead was not granted) → preview cost of a generation (whatif) → submit one image generation → display the result.
Pick a starter
| Need | Use |
|---|---|
| Discoverable via search engines | next-app (default) or sveltekit-app |
| Tool, mini-game, focused UI, no SEO | react-pwa or svelte-pwa |
| Don't know / mainstream stack | next-app |
Clone just one starter (recommended)
You almost never want to clone the whole monorepo. Pull just the starter you need:
npx tiged civitai/civitai-app-starters/starters/next-app my-app
cd my-app
cp .env.example .env
pnpm install
pnpm devThen:
- Go to civitai.com/user/account → OAuth Apps → Create.
- For SSR starters (
next-app,sveltekit-app): client type Confidential. - For PWA starters (
react-pwa,svelte-pwa): client type Confidential still — the BFF holds the secret. (Public-client browser-only flow is on the roadmap for a future*-staticvariant.) - Redirect URI:
http://localhost:3000/api/auth/callback/civitai(varies per starter — see each starter's README). - Copy
CIVITAI_CLIENT_IDandCIVITAI_CLIENT_SECRETinto.env. pnpm dev.
Alternative ways to clone
# Next.js CLI native npx create-next-app --example "https://github.com/civitai/civitai-app-starters/tree/main/starters/next-app" my-app # Full repo + sparse-checkout (if you want git history) git clone --filter=blob:none --sparse https://github.com/civitai/civitai-app-starters cd civitai-app-starters && git sparse-checkout set --cone starters/next-app
Civitai Apps
A Civitai App is a small iframe-embedded UI that renders inside a civitai.com
page — for example, a generator in a model's sidebar (model.sidebar_top slot).
Unlike an OAuth app, a block runs inside civitai.com and gets a short-lived,
block-scoped JWT + page context handed to it via postMessage. It's much smaller
than a full app: a single static SPA, no OAuth dance, no BFF.
Starter
starters/civitai-block-starter — Vite +
TypeScript, no UI framework: @civitai/sdk's initialize() for the host
bridge, <civitai-*> custom elements from @civitai/components for the UI.
npx tiged civitai/civitai-app-starters/starters/civitai-block-starter my-block
Prefer React? The Go civitai CLI's civitai app create <name> scaffolds a
Vite + React + TS app from its page-money template, and the examples below
are React too.
Packages
| Package | What |
|---|---|
@civitai/sdk — source |
Framework-agnostic client: initialize() resolves on the host's BLOCK_INIT with the slot context, viewer, theme, app.host (host UI, resize, navigation) and the API clients. What the default starter uses for the bridge. |
@civitai/components — source |
The <civitai-*> custom elements (Lit) and the attribute-driven data-civitai-ui CSS, themed by @civitai/theme. |
@civitai/app-sdk (/blocks subpath) — source |
Framework-agnostic contract: manifest types, scopes, the postMessage protocol. Build-time manifest validation (defineBlock, blockManifestPlugin) lives on the node-only /manifest and /vite subpaths. |
@civitai/blocks-react — source |
React hooks (useBlockContext, useBuzzWorkflow, useAppStorage, …) + iframe transport. Plus /ui (the SettingsForm). |
Go civitai CLI |
civitai login / civitai app init / civitai app validate / civitai app submit — scaffold and ship a block. (Local dev is the project's own npm run dev:harness.) Replaces the deprecated @civitai/blocks-cli. |
Examples
Eleven minimal, runnable blocks under starters/examples/ —
one per feature, each with its own README. They are written in React with
@civitai/blocks-react. Each runs offline against the SDK's mock host
(dev:harness), or against the real backend (dev:live).
| Example | Shows |
|---|---|
hello-world |
lifecycle: useBlockContext, the host trust frame, self-set data-theme |
settings |
manifest settings + the headless SettingsForm, publisher vs viewer scopes |
buzz-workflow |
useBuzzWorkflow estimate→submit→poll, the cost-quote-matches-charge rule |
kv-storage |
useAppStorage get/set/delete/list/getQuota |
scopes-api |
declaring scopes + calling scope-gated REST with the BLOCK_INIT token |
buzz-purchase |
useBuzzPurchase + useBuzzBalance: top up a short wallet (a purchase never lifts the per-generation budget) |
shared-board |
useSharedStorage cross-viewer board beside per-user useAppStorage (flag + approval gated) |
page-app |
the full-page app shape: manifest page, useBlockBreakpoint, sign-in/consent, navigation, BlockGate |
generate-studio |
page-app generation: checkpoint/LoRA pickers, txt2img + img2img, app queue, gated outputs, publish |
generation-kinds |
the other WorkflowBody kinds: customComfy recipes and step chat-completion, plus useWildcardPack |
monetize |
earning: manifest goods + useGoodPurchase/useEntitlements, and tips |
The dev → submit → review → deploy lifecycle
Devs never touch git hosting. The path is:
- Auth + Build —
civitai loginonce, scaffold withcivitai app create(or copystarters/civitai-block-starter), iterate locally withnpm run dev:harness(mock host) — plusnpm run dev:live(live host) where the project has it: the CLI'spage-moneytemplate and the examples do,civitai-block-starterdoes not yet — andvite buildto a staticdist/. Validate the manifest any time withcivitai app validate. - Submit —
civitai app submitvalidates, packages your project (block.manifest.json+src/+index.html+package.json+vite.config.ts+ …), and uploads it for review with your stored token. You don't include aDockerfileornginx.conf— the platform injects its own build recipe at approve. (If you have no token configured,submitwrites the.zipand prints next steps; you can also web-upload at/apps/submit.) Self-run the first-review checklist before submitting. - Review — a moderator reviews the manifest + file diff at
/apps/reviewand approves (or rejects with a reason you see on/apps/build). - Deploy — on approve, the platform builds + serves your
dist/and stamps the block'siframe.srcserver-side, serving it athttps://<blockId>.civit.ai/(root-served). Within ~5 min your block is live in its slot.
→ Build your first App — the
end-to-end guide, from civitai app init to a live block.
Gotchas worth knowing up front
These bit us building the reference block; the examples + the guide bake in the fixes:
- Set
data-themeon your own root — the host can't inject it into your iframe, so any[data-theme="dark"]CSS is dormant until you do. - Your estimate must build params identically to submit (esp. the seed) or the quoted Buzz cost won't match the charge.
- The platform owns the runtime image +
iframe.src— you don't ship aDockerfile/nginx.confor setiframe.src; the platform injects the build and stamps the src (https://<blockId>.civit.ai/, root-served) at approve. Keep Vitebase: '/'so the bundle resolves its own assets at the root. - The dev harness pins the parent origin — serve on the matching origin or
BLOCK_INITis rejected and the block hangs on "Loading…". - 🔴 Host-API access is enabled per ACCOUNT during the preview, separately
from submit/approve — an approved, live block can still get
401on everyuseAppStorage()call because the account was never enrolled, and neither your manifest scopes nor your app's approval has anything to do with it.civitai app doctorreports your account's state in one line. See Preview access is on your ACCOUNT, not on your app — it also explains why App Storage always refuses underdev:live.
Porting an existing app
Already have an app and want to add Sign-in-with-Civitai or swap your image-gen provider for Civitai's orchestrator? See PORTING.md — step-by-step recipe for grafting the SDK into an existing codebase, with notes on both additive ("Civitai as one more provider") and full-replacement integration modes.
For AI coding agents
See AGENTS.md at the root and the per-starter AGENTS.md inside each starters/*. The agent guides document which patterns to keep (auth + SDK lives in @civitai/app-sdk), which to avoid (don't put client_secret in the browser), and how the demo surface is structured.
Working on the monorepo itself
pnpm install pnpm build # build all workspace packages pnpm test # run all package tests pnpm typecheck # type-check everything
Releasing the SDK
@civitai/app-sdk ships via changesets + a GitHub Actions workflow with npm OIDC. After changing the SDK:
pnpm changeset # author a changeset (patch / minor / major) pnpm changeset status # preview pending bumps
Merge the auto-opened Version Packages PR to publish. Full guide: RELEASING.md.
License
来源:GitHub · github.com