Primitree

Local Token Hooks

Use built DTCG artifacts in React without the Figma API.

Build the token files:

npx primitree@next build variables.json

Setup

import { TokensProvider, useToken, useTokens, useTheme } from '@primitree/hooks'
import primitives from './design-tokens/tokens/primitives.tokens.json'
import semantic from './design-tokens/tokens/semantic.tokens.json'
import semanticDark from './design-tokens/tokens/semantic.dark.tokens.json'
import resolver from './design-tokens/tokens/tokens.resolver.json'

export function App() {
  return (
    <TokensProvider
      tokens={{
        'primitives.tokens.json': primitives,
        'semantic.tokens.json': semantic,
        'semantic.dark.tokens.json': semanticDark,
      }}
      resolver={resolver}>
      <Toolbar />
    </TokensProvider>
  )
}

useToken

function BrandButton() {
  const brand = useToken('semantic.color.bg.brand')
  // brand.value  -> resolved DTCG value under active contexts
  // brand.css    -> 'color(srgb 0.2 0.4 1)'
  // brand.cssVar -> 'var(--semantic-color-bg-brand)'

  return <button style={{ background: brand.css ?? undefined }}>Brand</button>
}

Paths use dot notation from the flattened token tree.

useTheme

Use a Resolver context to change theme or density:

function ThemeToggle() {
  const { contexts, availableContexts, setContext } = useTheme()

  return (
    <button
      onClick={() =>
        setContext('semantic', contexts.semantic === 'dark' ? 'light' : 'dark')
      }>
      Theme: {contexts.semantic}
    </button>
  )
}

A Figma collection named Theme with Light and Dark modes maps to setContext('theme', 'dark').

useTokens

useTokens returns the merged document, flattened tokens, resolved values, active contexts, and context setters.

SSR

These hooks make no network requests. Server rendering and static export work when the JSON imports resolve at build time.