npm package: @strata-ds/core
Description: The runtime component library for Strata — design once, sync everywhere.
Author: Charisol
Latest version: 2.1.0

# @strata-ds/core

> The runtime component library for [Strata](https://strata.charisol.io) — connect your React app to your design system and ship updates live.

`@strata-ds/core` is a dynamic React component library and stylesheet runtime. It enables teams to consume design tokens and components directly from a centralised Strata design system, ensuring that what designers create is exactly what developers ship — consistently, across platforms, and in real time.

> Design once in Strata. Ship everywhere.

## Why @strata-ds/core?

### The Problem

Design and engineering teams often drift apart:

- Designers update Figma files
- Developers re-implement styles manually
- Components slowly diverge from the original design
- Consistency breaks across products and platforms

This results in duplicate work, inconsistent UI, broken design intent, and slow iteration.

### The Solution

`@strata-ds/core` bridges this gap by acting as:

- A component library
- A stylesheet generator runtime
- A live consumer of design tokens and components

All powered by your **Strata** project.

Instead of hardcoding styles, **components dynamically reference design tokens** fetched from the design system. This establishes a single **source of truth** for design.

## Core Principles

### 1. Separation of Concerns

`@strata-ds/core` strictly separates:

- **Variables (Design Tokens)** — Colors, spacing, typography, radii, shadows, etc.
- **Components** — Buttons, Cards, Forms, Navbars, etc.

Components never own styles directly — they reference tokens.

### 2. Single Source of Truth

Design tokens live in your Strata project, not inside applications.

- Tokens are defined once
- Components reference them dynamically
- Updates propagate automatically

### 3. Dynamic & Real-Time Sync

`@strata-ds/core` can:

- Fetch updated tokens and components from the Strata backend
- Detect changes via checksum
- Rebuild styles automatically
- Fall back to cached data when offline

## Architecture Overview

```
Figma / Style Dictionary
        ↓
Strata Design System
        ↓
Machine-parseable JSON
        ↓
@strata-ds/core Component Library
        ↓
Your React Application
```

## Quick Start

### 1. Create a Strata project

Go to [strata.charisol.io](https://strata.charisol.io), create a project, and import your design tokens (Style Dictionary JSON or Figma).

### 2. Get your sync URL

Once your tokens are imported, your project's sync URL is shown on the project page:

```
https://api-production-charisol-design-system-be.aws.charisol.io/v1/project/YOUR_PROJECT_ID/data
```

Copy it — you'll need it in step 4.

### 3. Install

```bash
npm install @strata-ds/core
# or
yarn add @strata-ds/core
```

### 4. Wrap your app

**CDN Snapshot Sync (recommended — 1 request per poll, edge-cached):**

```tsx
"use client"; // Next.js App Router only
import { StrataProvider } from "@strata-ds/core";

export default function RootLayout({
	children,
}: {
	children: React.ReactNode;
}) {
	return (
		<StrataProvider
			syncEnabled={true}
			projectId="YOUR_PROJECT_ID"
			snapshotCdnBase="https://cdn.strata.charisol.io"
			syncToken="pt_live_your_token_here"
			syncInterval={5000}
		>
			{children}
		</StrataProvider>
	);
}
```

> 💡 Get your `projectId` and `syncToken` from the **Publish & Sync** tab on your Strata project dashboard.

### Legacy sync (syncUrl — still supported, not recommended for new projects)

```tsx
"use client"; // Next.js App Router only
import { StrataProvider } from "@strata-ds/core";

export default function RootLayout({
	children,
}: {
	children: React.ReactNode;
}) {
	return (
		<StrataProvider
			syncEnabled={true}
			syncUrl="https://api-production-charisol-design-system-be.aws.charisol.io/v1/project/YOUR_PROJECT_ID/data"
			syncToken="pt_live_your_token_here"
			syncInterval={3000}
		>
			{children}
		</StrataProvider>
	);
}
```

> 💡 Replace `YOUR_PROJECT_ID` with the ID from your Strata project dashboard. Get your `syncToken` from the **Publish & Sync** tab — it starts with `pt_live_`.

### 5. Use your components

```tsx
"use client";
import { useComponents } from "@strata-ds/core";

function App() {
	// Components you created in your Strata project
	const { Button, Navbar } = useComponents();

	return (
		<>
			{Button && (
				<Button onClick={() => console.log("clicked")}>Click me</Button>
			)}
			{Navbar && <Navbar />}
		</>
	);
}
```

## Installation

```bash
npm install @strata-ds/core
# or
yarn add @strata-ds/core
```

## Project Setup (React)

`@strata-ds/core` works with React 18+, Next.js (App Router or Pages Router), and any standard React setup.

### 1. Create a new project

```bash
npx create-next-app@latest my-strata-app --typescript
cd my-strata-app
npm install @strata-ds/core
```

### 2. Integrate the StrataProvider

Wrap your application's root component with `StrataProvider`. This provider manages the connection to the Strata backend.

| Prop               |                                 Type                                 | Description                                                                                                                                                                                                                                                  |
| :----------------- | :------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `syncEnabled`      |                              `boolean`                               | If `true`, the library will fetch and sync tokens/components from the server.                                                                                                                                                                                |
| `snapshotCdnBase`  |                               `string`                               | **Recommended.** Base CDN URL for snapshot files (e.g. `"https://cdn.strata.charisol.io"`). When set together with `projectId`, the provider fetches a single `strata.json` snapshot per poll cycle instead of 3 API calls. Takes precedence over `syncUrl`. |
| `projectId`        |                               `string`                               | Your Strata project ID (shown in the dashboard URL and project settings). Required when using `snapshotCdnBase`.                                                                                                                                             |
| `syncUrl`          |                               `string`                               | Legacy base sync URL. `StrataProvider` will append `/variables`, `/components`, and `/custom` to this URL. Ignored when `snapshotCdnBase` + `projectId` are provided.                                                                                        |
| `syncInterval`     |                               `number`                               | Polling interval in milliseconds to check for design system updates. Default: `3000`.                                                                                                                                                                        |
| `syncToken`        |                               `string`                               | Sync token from your project dashboard. When set, all sync requests carry `Authorization: Bearer <token>`. Required if your project is not fully public.                                                                                                     |
| `initialData`      |                          `DesignSystemData`                          | Initial design system data to use before the first sync.                                                                                                                                                                                                     |
| `userDesignSystem` |                          `DesignSystemData`                          | Override design system data — useful for storybook, testing, or static mode. Takes precedence over `initialData`.                                                                                                                                            |
| `onSyncError`      | `(error: { code: number; message: string; source: string }) => void` | Callback invoked when a sync cycle fails. `code` is the HTTP status (0 for non-HTTP errors), `message` is a human-readable description, and `source` is `"cdn"` or `"sync"`.                                                                                 |
| `onSyncSuccess`    |                  `(data: DesignSystemData) => void`                  | Callback invoked whenever a sync cycle succeeds with new data.                                                                                                                                                                                               |

```tsx
// app/layout.tsx (Next.js App Router)
"use client";
import { StrataProvider } from "@strata-ds/core";

export default function RootLayout({
	children,
}: {
	children: React.ReactNode;
}) {
	return (
		<html lang="en">
			<body>
				<StrataProvider
					syncEnabled={true}
					projectId="YOUR_PROJECT_ID"
					snapshotCdnBase="https://cdn.strata.charisol.io"
					syncInterval={5000}
				>
					{children}
				</StrataProvider>
			</body>
		</html>
	);
}
```

> 💡 Replace `YOUR_PROJECT_ID` with the ID from your Strata project dashboard. For private projects, add `syncToken="pt_live_your_token_here"` (get it from the **Publish & Sync** tab).

### Sync token authentication

If your project has a sync token set in the Strata dashboard, pass it as `syncToken`. Every polling request will automatically include `Authorization: Bearer <token>`.

Projects with `syncToken` set are only readable by clients that present the correct token. This is the recommended way to gate read access to your design system without managing user accounts.

```tsx
<StrataProvider
	syncEnabled={true}
	projectId="YOUR_PROJECT_ID"
	snapshotCdnBase="https://cdn.strata.charisol.io"
	syncToken="pt_live_your_token_here"
	syncInterval={5000}
>
	{children}
</StrataProvider>
```

## Using Design System Components

`@strata-ds/core` provides dynamic access to your components defined in Strata.

### Accessing Components with `useComponents`

```tsx
"use client";
import { useComponents } from "@strata-ds/core";

function AppContent() {
	// Components are named exactly as you defined them in your Strata project
	const { Button, Navbar, Card } = useComponents();

	return (
		<>
			{/* Render conditionally while components are loading */}
			{Button && (
				<Button onClick={() => console.log("clicked")}>Click me</Button>
			)}

			{Card && <Card style={{ padding: "20px" }}>Card content here</Card>}
		</>
	);
}
```

### Accessing Design System Context with `useStrata`

```tsx
"use client";
import { useStrata } from "@strata-ds/core";

function StatusBar() {
	const { designSystem, syncStatus, lastSynced } = useStrata();

	return (
		<div>
			<p>Sync status: {syncStatus}</p>
			<p>Last synced: {lastSynced?.toLocaleTimeString() || "Never"}</p>
			<p>Components: {Object.keys(designSystem.components).join(", ")}</p>
		</div>
	);
}
```

### Customisation and Overrides

**Token-Driven Styling (Default)**

By default, all components are styled based on the latest tokens fetched from your Strata project. This ensures perfect design-to-code fidelity.

**Local Overrides**

Override any style locally using standard React props:

```tsx
<Button
	style={{ backgroundColor: "#007bff", color: "white" }}
	className="my-custom-class"
>
	Custom styled button
</Button>
```

### Dynamic Updates (Hot-Reloading)

`@strata-ds/core` intelligently handles design updates:

1. A designer makes a change in Strata (e.g., updates a colour token or modifies a component).
2. Strata generates a new checksum.
3. Your `StrataProvider` (via `syncInterval`) polls the `syncUrl`.
4. If the checksum has changed, the library fetches new design tokens and component configurations, and your app's components are dynamically restyled — without a page refresh.

## Debugging & Inspection

### `StrataDebug`

The `<StrataDebug />` component renders a debug panel showing the active sync mode, connection details, and the component registry. Useful during development to verify that tokens and components have loaded correctly.

```tsx
import { StrataDebug } from "@strata-ds/core";

// Place anywhere inside StrataProvider
<StrataDebug />;
```

The panel automatically displays the relevant fields for the active sync mode:

- **CDN mode** (`snapshotCdnBase` + `projectId` set): shows `✅ CDN Snapshot`, Project ID, resolved Snapshot URL, token presence, and sync interval.
- **Legacy mode** (`syncUrl` set): shows `⚠️ Legacy (3 requests/poll)`, Sync URL, token presence, and sync interval.
- **Disabled**: shows `❌ Disabled`.

> 🔒 The `syncToken` value is **never** rendered — the panel only shows `✅ Present` or `❌ None`.

### Programmatic inspection

```tsx
import { useStrata, useDynamicComponents } from "@strata-ds/core";

function DebugPanel() {
	const { designSystem, syncStatus, syncUrl, syncEnabled } = useStrata();
	const dynamicComponents = useDynamicComponents();

	return (
		<pre>
			{JSON.stringify(
				{
					syncStatus,
					syncEnabled,
					syncUrl,
					designSystemComponents: Object.keys(designSystem.components),
					registryComponents: Object.keys(dynamicComponents),
				},
				null,
				2,
			)}
		</pre>
	);
}
```

### Hooks reference

| Hook / Property          | Description                                                                                                                              |
| :----------------------- | :--------------------------------------------------------------------------------------------------------------------------------------- |
| `useStrata()`            | Returns full context: `designSystem`, `syncStatus`, `lastSynced`, `syncUrl`, `snapshotCdnBase`, `projectId`, `syncEnabled`, `forceSync`. |
| `useComponents()`        | Returns ready-to-use React components by PascalCase name.                                                                                |
| `useDynamicComponents()` | Returns the raw component registry map.                                                                                                  |

## Network Debugging

If components are not loading, check your browser's Network tab:

- **CDN pattern:** When `snapshotCdnBase` and `projectId` are set, the provider makes a single request to `${snapshotCdnBase}/snapshots/${projectId}/strata.json` per poll cycle. Verify the response is a JSON object with `variables`, `components`, and `custom` keys.
- **Legacy pattern:** When `syncUrl` is set, the provider makes 3 requests per poll cycle: `${syncUrl}/variables`, `${syncUrl}/components`, and `${syncUrl}/custom`. Each should return the corresponding JSON object.
- **Errors:** Check the console for `❌ Sync failed:` messages.

## Registry API

`strataRegistry` is the underlying singleton registry that stores all registered components.

```tsx
import { strataRegistry } from "@strata-ds/core";

// Check if a component is registered
strataRegistry.hasComponent("Button");

// Get a component by name
const ButtonComponent = strataRegistry.getComponent("Button");
```

## Component Factory

`StrataComponentFactory` creates React components from Strata component definitions.

```tsx
import { StrataComponentFactory } from "@strata-ds/core";

const MyComponent = StrataComponentFactory.createComponent(
	"MyComponent",
	componentData,
	designSystem,
);
```

## Key Features

- 🔁 Live sync with Strata backend
- 🧠 Token-driven styling
- 🧩 Dynamic component registry
- 🛠 Inline style overrides supported
- 📦 Installable via npm
- 📴 Offline-first fallback
- 🧪 Debug tools included (`StrataDebug`)

## License

MIT © [Charisol](https://strata.charisol.io)