Architecture

How Spry packages fit together, where client boundaries belong, and how this repo relates to published consumers.

Packages

SpryInnovation is split so you can depend only on what you need:

  • @spry/tokens — design token values (TypeScript + CSS variables source).
  • @spry/themeSpryProvider, theme application, createSpryTheme, and global styles that map tokens to semantic UI variables.
  • @spry/ui — accessible primitives (Button, Input, Dialog, …) built on CSS variables.
  • @spry/patterns — higher-level layouts and flows composed from UI primitives.
  • @spry/icons — icon set consumed by UI (workspace dependency).

React Server Components

Next.js App Router and other RSC environments require that anything using React context, browser-only APIs, or interactive state is in a client component. Theme and toast providers are client boundaries: import them from leaf modules marked "use client" (or wrap them in a small client shell).

Import UI primitives from @spry/ui in server components only when those modules do not evaluate client-only code at import time. If you see errors about createContext in the server bundle, add "use client" to the consuming file or split the provider into a client wrapper.

app/providers.tsx

Monorepo vs consumers

This repository is a pnpm workspace: apps (for example docs) link to packages via workspace:*. External applications should install published versions from your registry and import only public entry points (@spry/ui, @spry/theme/react, etc.) — not deep paths into the monorepo.

Remote & multi-tenant themes

The type SpryTenantThemeConfig in @spry/theme matches tenant theme JSON: { tenantId?, theme: { colors?, radius?, mode? } } Use parseSpryTenantThemeJson to validate unknown JSON, spryTenantThemeToDefinition to build a SpryThemeDefinition, and pass it to SpryProvider or applySpryThemeDefinition on a root element.

For HTTP loading, fetchSpryTenantTheme(url, init?) runs fetch and validation (use init for auth headers or credentials). createSpryTenantThemeCache() provides an in-memory cache (optional TTL per entry) and getOrFetch to populate from an async loader. In React, useSpryTenantThemeDefinition(url, init?) loads a definition for SpryProvider.

Product concerns such as tenant admin UI, server-side caching, or your own auth layer stay in your app; this repo exposes the parsing, conversion, fetch, and apply helpers only.

Publishing & versions

Releases are expected to follow semantic versioning per package. The root toolchain includes Changesets (pnpm changeset) for changelog generation and coordinated bumps. Until you publish, treat versions as 0.x and expect occasional breaking changes while APIs stabilize.