npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@smoothie-framework/ui-core

v0.0.2

Published

Smoothie UI Core - Portable design tokens, types, and utilities

Downloads

678

Readme

@smoothie-framework/ui-core

Portable design tokens, types, and utilities for the Smoothie UI ecosystem.

+------------------------------------------------------------------+
|                         CONSUMERS                                 |
|  @smoothie-framework/ui  |  @smoothie-framework/ui-react  |  Zig SDK  |  Berry AI       |
+------------------------------------------------------------------+
                              |
                              v
+------------------------------------------------------------------+
|                      @smoothie-framework/ui-core                            |
|  +-------------+  +-------------+  +-------------+  +-----------+ |
|  | tokens/     |  | theme/      |  | recipes/    |  | protocol/ | |
|  | colors      |  | validation  |  | Button      |  | binary    | |
|  | spacing     |  | extension   |  | Input       |  | JSON      | |
|  | typography  |  | resolution  |  | Stack       |  | Zig       | |
|  +-------------+  +-------------+  +-------------+  +-----------+ |
+------------------------------------------------------------------+

What is ui-core?

@smoothie-framework/ui-core is the design system foundation layer for the Smoothie ecosystem. It defines:

| Layer | Purpose | Consumed By | |-------|---------|-------------| | Tokens | Raw design values (colors, spacing, typography) | All SDKs, all frameworks | | Semantic | Light/dark mode token mappings | Theme providers | | Recipes | Component variant definitions (styling as data) | Component libraries | | Theme | Composition, validation, reference resolution, CSS compilation | Applications | | Protocol | Binary/JSON/Zig exports for cross-SDK sharing | Zig SDK, Rust SDK, Berry AI | | CSS | CSS variable generation, Tailwind preset | DOM-based renderers |

This package has zero runtime dependencies and is framework-agnostic.

Documentation model note:

  • Strategic and requirements docs for the UI toolkit live in docs/spec/ui-toolkit/.
  • Canonical implementation-aware UI docs live in docs/architecture/ui-toolkit/.
  • This README is a package guide, not the primary source for UI toolkit strategy.

Important boundary:

  • @smoothie-framework/ui-core does not include runtime reactivity primitives.
  • Use @smoothie-framework/ui for signal/computed/effect/batch and rendering runtime APIs.

Installation

bun add @smoothie-framework/ui-core
# or
npm install @smoothie-framework/ui-core

Import Paths

The package uses subpath exports for optimal tree-shaking:

// Essential exports (most common)
import { colors, spacing, defaultTheme } from '@smoothie-framework/ui-core';
import type { Theme, UINode } from '@smoothie-framework/ui-core';

// Specialized imports
import { buttonRecipe, textRecipe } from '@smoothie-framework/ui-core/recipes';
import { toCssVariables, toTailwindPreset } from '@smoothie-framework/ui-core/css';
import { exportTokensBinary } from '@smoothie-framework/ui-core/protocol';
import { extendTheme, validateTheme, compileThemeCss } from '@smoothie-framework/ui-core/theme';
import { lightSemanticColors, darkSemanticColors } from '@smoothie-framework/ui-core/semantic';

| Path | Purpose | |------|---------| | @smoothie-framework/ui-core | Essential tokens, types, theme utilities | | @smoothie-framework/ui-core/tokens | Primitive design tokens only | | @smoothie-framework/ui-core/types | Type definitions only | | @smoothie-framework/ui-core/theme | Theme composition and validation | | @smoothie-framework/ui-core/semantic | Light/dark mode semantic tokens | | @smoothie-framework/ui-core/recipes | Component variant recipes | | @smoothie-framework/ui-core/resolve | Token resolution primitives | | @smoothie-framework/ui-core/css | CSS variable generation, Tailwind | | @smoothie-framework/ui-core/protocol | Cross-SDK binary/JSON exports | | @smoothie-framework/ui-core/schemas/component-contracts | Canonical component ids, aliases, variants, and styling support | | @smoothie-framework/ui-core/utils | Utility functions |

Export Strategy

  • Root (@smoothie-framework/ui-core): ergonomic defaults and high-frequency APIs (tokens, Theme, defaultTheme, core helpers).
  • Subpaths: canonical source for specialized features (/recipes, /theme, /resolve, /css, /protocol).
  • Deep paths (/protocol/infer, /schemas/component-schemas): narrow allowlist for advanced/infra usage; prefer subpath indexes for app code.
  • No compatibility aliases in new API: import specialized protocol/resolve helpers from their canonical subpaths.

Quick Start

1. Use Design Tokens

import { colors, spacing, typography, radii, shadows } from '@smoothie-framework/ui-core';

const styles = {
  backgroundColor: colors.blue[500],     // '#3b82f6'
  padding: spacing.md,                   // 16
  borderRadius: radii.md,                // 6
  boxShadow: shadows.md,                 // '0 4px 6px -1px ...'
  fontSize: typography.fontSize.md.size, // 16
};

2. Create a Theme

import { defaultTheme, extendTheme } from '@smoothie-framework/ui-core';

// Use default theme
console.log(defaultTheme.colors.blue[500]); // '#3b82f6'

// Extend with custom values
const { theme } = extendTheme({
  colors: {
    brand: '{colors.blue.600}', // Token reference
  },
});

3. Apply to DOM

import { toCssVariables } from '@smoothie-framework/ui-core/css';

const cssVars = toCssVariables(defaultTheme);
Object.assign(document.documentElement.style, cssVars);

// Now use in CSS:
// background: var(--smoothie-colors-blue-500);

4. Use Component Recipes

import { buttonRecipe, resolveRecipe } from '@smoothie-framework/ui-core/recipes';
import { defaultTheme } from '@smoothie-framework/ui-core/theme';

const styles = resolveRecipe(
  buttonRecipe,
  { variant: 'primary', size: 'md' },
  defaultTheme,
  // mode defaults to 'css-variables'
);
// { background: 'var(--smoothie-button-primary-bg)', ... }

Common Consumer Paths

Using ui-core inside another framework

Use @smoothie-framework/ui-core when you want Smoothie tokens, recipes, and theme helpers without adopting the full @smoothie-framework/ui runtime.

Useful imports:

| Import | Purpose | | --- | --- | | @smoothie-framework/ui-core | tokens and core types | | @smoothie-framework/ui-core/recipes | recipe definitions such as buttonRecipe | | @smoothie-framework/ui-core/theme | theme extension and validation | | @smoothie-framework/ui-core/css | CSS variable generation and Tailwind preset | | @smoothie-framework/ui-core/resolve | token resolution helpers |

Typical recipe usage:

import { buttonRecipe, resolveRecipe } from '@smoothie-framework/ui-core/recipes';
import { defaultTheme } from '@smoothie-framework/ui-core/theme';

const styles = resolveRecipe(buttonRecipe, { variant: 'primary', size: 'md' }, defaultTheme);

Exporting tokens for cross-SDK consumers

Use the protocol exports when another SDK or runtime needs the same token graph.

import { defaultTheme } from '@smoothie-framework/ui-core';
import { exportTokensBinary, exportTokensZig } from '@smoothie-framework/ui-core/protocol';

const tokensBin = exportTokensBinary(defaultTheme);
const tokensZig = exportTokensZig(defaultTheme);

Exporting component schema for Berry and tools

Use component schema exports when tools or AI systems need the canonical UI contract.

import { exportComponentSchema, exportComponentSchemaJSON } from '@smoothie-framework/ui-core/protocol';

const schema = exportComponentSchema();
const json = exportComponentSchemaJSON(true);

These exports are the canonical bridge from ui-core into Berry, editor tooling, and future cross-SDK consumers.

Use @smoothie-framework/ui-core/schemas/component-contracts when adapters, styling tooling, or conformance tests need canonical runtime component ids, schema aliases, recipe variants, or styling-support metadata.


Architecture

Package Structure

src/
  tokens/              # Primitive design tokens
    colors.ts            7 palettes x 11 shades = 77 colors
    paths.ts             Canonical token path unions (KnownTokenPath)
    spacing.ts           xs(4) sm(8) md(16) lg(24) xl(32) 2xl(48) 3xl(64)
    typography.ts        Font families, sizes (xs-4xl), weights
    radii.ts             none(0) xs(2) sm(4) md(6) lg(8) xl(12) 2xl(16) full(9999)
    shadows.ts           xs, sm, md, lg, xl, 2xl, 3xl

  semantic/            # Mode-aware semantic tokens
    colors.ts            accent, background, foreground, muted, border, etc.
    modes.ts             Light/dark mode utilities

  recipes/             # Component variant definitions
    button.ts            variant: primary|secondary|ghost|outline|danger
    input.ts             variant: outline|filled|flushed
    stack.ts             direction, gap, align, justify, wrap
    text.ts              size, weight, align, truncate
    types.ts             Recipe<V>, StyleObject, VariantSchema

  theme/               # Theme system
    default.ts           Default theme with all tokens
    extend.ts            extendTheme(), createThemeVariant()
    validate.ts          validateTheme(), assertValidTheme()
    errors.ts            ThemeError, ThemeErrors classes

  resolve/             # Token resolution primitives
    token-map.ts         buildTokenMap()
    resolve.ts           resolveToken(), resolveStyleObject(), resolveDeep()
    css-vars.ts          resolveStyleObjectToCssVars(), tokenPathToCssVar()
    patterns.ts          canonical regex + token detection helpers

  css/                 # CSS generation
    variables.ts         toCssVariables(), getCssVariable()
    tailwind.ts          toTailwindPreset()

  protocol/            # Cross-SDK exports
    export-tokens.ts     exportTokensBinary() -> Uint8Array
    export-schema.ts     exportComponentSchema() -> JSON
    export-zig.ts        exportTokensZig() -> string

  types/               # Type definitions
    layout.ts            SizeToken, SpacingValue, Alignment, Justification
    ui-node.ts           UINode, UINodeProps, UIEvent
    theme.ts             Theme, ThemeTokens, TokenKey
    index.ts             Public barrel for cross-domain contracts

  utils/               # Utilities
    token-helpers.ts     resolveColor, resolveSpacing, etc.
    theme-utils.ts       createTheme, mergeTheme
    guards.ts            isSizeToken, isUINode, etc.

Consumer Matrix

| Consumer | What They Import | Format | |----------|------------------|--------| | @smoothie-framework/ui | Direct TypeScript imports | .ts | | @smoothie-framework/ui-react | Direct TypeScript imports | .ts | | Berry AI | Component schema | .json | | Zig SDK | Token constants, schema | .zig, .bin | | Rust SDK | Token constants | .rs, .bin | | Unity C ABI | Token binary | .bin | | DOM Adapter | CSS variables | .css | | Tailwind users | Preset config | .js |

Dependency Graph

@smoothie-framework/ui-core (this package - zero dependencies)
         |
         +---> @smoothie-framework/ui (signals, JSX, components)
         |
         +---> @smoothie-framework/ui-react (React adapter)
         +---> @smoothie-framework/ui-vue (Vue adapter)
         +---> @smoothie-framework/ui-svelte (Svelte adapter)
         |
         +---> Berry AI (component generation)
         +---> Zig SDK (native rendering)

Resolution and Styling Pipeline

The current implementation uses a single token-reference pipeline with two output modes:

  1. Recipe merge: base + selected variants + compound variants (mergeVariants)
  2. Resolution mode:
    • css-variables (default runtime path): rewrites {token.path} -> var(--smoothie-...) without building a token map
    • values (build-time/SSR path): resolves references to concrete values via buildTokenMap
  3. Token precedence in map-based mode: theme.tokens > recipe.tokens > primitive tokens

CSS output options:

  • Inline style path: consumers call resolveRecipe(...) and apply resulting style objects
  • External stylesheet path: generateRecipeCss / generateStylesheet emit .smoothie-* classes
  • Theme variable path: toCssVariables(theme) emits CSS custom properties for primitives and theme.tokens aliases

Token Reference

Colors

5 primitive palettes, each with 11 shades (50-950):

colors.blue[500]      // '#3b82f6' - Blue
colors.green[500]     // '#22c55e' - Green
colors.yellow[500]    // '#f59e0b' - Yellow
colors.red[500]       // '#ef4444' - Red
colors.neutral[500]   // '#737373' - Neutral

// Backward-compatible aliases are still accepted in token references:
// {colors.primary.500} -> {colors.blue.500}

Spacing

4px base unit scale:

| Token | Value | Use Case | |-------|-------|----------| | xs | 4px | Icon padding | | sm | 8px | Tight spacing | | md | 16px | Default padding | | lg | 24px | Section gaps | | xl | 32px | Large gaps | | 2xl | 48px | Hero sections | | 3xl | 64px | Page margins |

Typography

typography.fontFamily.sans  // 'Inter, system-ui, ...'
typography.fontFamily.mono  // 'JetBrains Mono, ...'

typography.fontSize.md      // { size: 16, lineHeight: 24 }
typography.fontWeight.bold  // 700

Theme System

Token References

Use {path.to.token} syntax for theme composition:

import { extendTheme } from '@smoothie-framework/ui-core/theme';

const { theme } = extendTheme({
  colors: {
    accent: '{colors.blue.500}',
    background: '{colors.neutral.50}',
  },
}, { resolveRefs: true });

// theme.colors.accent === '#3b82f6' (resolved)

Theme Token Overrides

import { defaultTheme, extendTheme } from '@smoothie-framework/ui-core/theme';

const { theme } = extendTheme({
  tokens: {
    ...defaultTheme.tokens,
    'button.primary.bg': '{colors.blue.600}',
    'button.primary.hover.bg': '{colors.blue.700}',
  },
}, { validate: true });

Theme Validation

import { validateTheme } from '@smoothie-framework/ui-core/theme';

const result = validateTheme(myTheme);
if (!result.valid) {
  console.error(result.errors);
  // [{ severity: 'error', path: 'colors.x', message: '...' }]
}

Recipes

Component recipes define styling as data:

import { buttonRecipe, resolveRecipe, type ButtonVariants } from '@smoothie-framework/ui-core/recipes';
import { defaultTheme } from '@smoothie-framework/ui-core/theme';

// Resolve styles for a specific variant combination (runtime path)
function getButtonStyles(variant: ButtonVariants['variant'], size: ButtonVariants['size']) {
  return resolveRecipe(
    buttonRecipe,
    { variant, size },
    defaultTheme,
  );
}

Available recipes: buttonRecipe, inputRecipe, stackRecipe, rowRecipe, textRecipe, headingRecipe


CSS Generation

CSS Variables

import { toCssVariables, getCssVariable } from '@smoothie-framework/ui-core/css';

const vars = toCssVariables(theme);
// { '--smoothie-colors-blue-500': '#3b82f6', ... }

const ref = getCssVariable('colors.blue.500');
// 'var(--smoothie-colors-blue-500)'

Tailwind Preset

import { toTailwindPreset } from '@smoothie-framework/ui-core/css';

const preset = toTailwindPreset(theme);
// Use in tailwind.config.js: presets: [preset]

Protocol Exports

Binary Export (for native SDKs)

import { exportTokensBinary, getTokenExportMetadata } from '@smoothie-framework/ui-core/protocol';

const metadata = getTokenExportMetadata(theme);
// { version: '1.0', colorCount: 77, spacingCount: 7, sizeBytes: 2847 }

const binary = exportTokensBinary(theme);
await fs.writeFile('tokens.bin', binary);

JSON Schema (for Berry AI)

import { exportComponentSchemaJSON } from '@smoothie-framework/ui-core/protocol';

const json = exportComponentSchemaJSON();
await fs.writeFile('schema.json', json);

Zig Source (for Zig SDK)

import { exportTokensZig } from '@smoothie-framework/ui-core/protocol';

const zigSource = exportTokensZig(theme);
await fs.writeFile('tokens.zig', zigSource);

Design Principles

  1. Zero Runtime Dependencies - Pure TypeScript, no external packages
  2. Framework Agnostic - Works with React, Vue, Svelte, or vanilla JS
  3. Platform Agnostic - Values work on DOM, Canvas, or native
  4. Tree-Shakeable - Subpath exports for minimal bundle size
  5. Type-Safe - Full TypeScript coverage with strict mode
  6. Cross-SDK - Exports to TypeScript, Zig, Rust, JSON

Bundle Size

| Module | Size (gzipped) | |--------|----------------| | tokens | ~1.5KB | | theme | ~2KB | | recipes | ~1KB | | css | ~0.5KB | | protocol | ~1.5KB | | Total | < 8KB |


Documentation


License

MIT