or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

examples

edge-cases.mdreal-world-scenarios.md
index.md
tile.json

transformers.mddocs/reference/

Code Transformers

Code transformation pipeline for framework compatibility and customization. Transformers modify component source code to match project configuration, handling imports, styles, icons, React Server Components, and more.

Capabilities

transformStyle

Transforms styles with CSS variable substitution and theme mapping. Converts style names to their CSS variable equivalents based on configuration using configurable transformers.

/**
 * Transform styles with CSS variable substitution
 * @param source - Source component code
 * @param options - Transform options including style map and optional transformers
 * @returns Promise resolving to transformed component code
 */
function transformStyle(
  source: string,
  options: {
    styleMap: StyleMap
    transformers?: TransformerStyle<SourceFile>[]
  }
): Promise<string>

Parameters:

  • source: string - Source component code to transform. Required.
  • options.styleMap: StyleMap - Map of style names to CSS variable definitions. Required.
  • options.transformers?: TransformerStyle<SourceFile>[] - Optional array of style transformers (defaults to [transformStyleMap]). Each transformer receives a SourceFile and styleMap.

Returns: Promise<string> - Transformed component code as a string.

Usage Example:

import { transformStyle, createStyleMap } from 'shadcn/utils';

// Create style map from base styles
const styleMap = createStyleMap(`
  :root {
    --background: 0 0% 100%;
    --foreground: 222.2 84% 4.9%;
    --primary: 222.2 47.4% 11.2%;
  }
`);

// Transform component styles
const source = `
  export function Button() {
    return (
      <button className="bg-primary text-foreground">
        Click me
      </button>
    );
  }
`;

const transformed = await transformStyle(source, {
  styleMap
});

// With custom transformers
const transformed = await transformStyle(source, {
  styleMap,
  transformers: [customTransformer, transformStyleMap]
});

Note: This is a string-to-string transformation. For AST-based transformations, use the individual transformer functions.

createStyleMap

Creates a style map from CSS input. Parses CSS and builds a map for style transformations.

/**
 * Create style map from CSS
 * @param input - CSS input string
 * @returns StyleMap for use in transformations
 */
function createStyleMap(input: string): StyleMap

Parameters:

  • input: string - CSS input to parse. Should contain CSS variable definitions in :root or similar selectors.

Returns: StyleMap - Map of style names to CSS variable definitions:

type StyleMap = Record<string, string>
// Example: { "background": "0 0% 100%", "foreground": "222.2 84% 4.9%" }

Usage Example:

import { createStyleMap } from 'shadcn/utils';

const css = `
  :root {
    --background: 0 0% 100%;
    --foreground: 222.2 84% 4.9%;
    --primary: 222.2 47.4% 11.2%;
  }
`;

const styleMap = createStyleMap(css);

// Use styleMap in transformStyle calls

transformIcons

Transforms icon imports between icon libraries. Converts icon imports and usage from one library to another (e.g., lucide to phosphor). This transformer modifies the Abstract Syntax Tree (AST) using ts-morph and returns the modified SourceFile object.

/**
 * Transform icon imports between libraries
 * @param opts - Transform options with config and sourceFile
 * @returns Promise resolving to transformed SourceFile AST
 */
const transformIcons: Transformer

Type: Transformer - A transformer function that operates on ts-morph SourceFile ASTs

Parameters:

  • opts: TransformOpts & { sourceFile: SourceFile } - Options including:
    • filename: string - Component filename. Required.
    • raw: string - Raw source code. Required.
    • config: Config - Configuration with iconLibrary property. Required.
    • sourceFile: SourceFile - ts-morph SourceFile AST to transform. Required.

Returns: Promise<SourceFile> - Transformed SourceFile AST (call .getText() to get string)

Usage Example:

import { transformIcons } from 'shadcn/utils';
import { Project, ScriptKind } from 'ts-morph';

const source = `
import { ChevronRight, Check } from 'lucide-react';

export function Component() {
  return (
    <div>
      <ChevronRight />
      <Check />
    </div>
  );
}
`;

// Create a SourceFile AST using ts-morph
const project = new Project();
const sourceFile = project.createSourceFile('component.tsx', source, {
  scriptKind: ScriptKind.TSX
});

// Transform the SourceFile
await transformIcons({
  filename: 'component.tsx',
  raw: source,
  config: {
    iconLibrary: 'phosphor',
    // ...other config
  },
  sourceFile: sourceFile
});

// Extract the transformed code
const transformedCode = sourceFile.getText();

// Result transforms imports to @phosphor-icons/react
// and updates usage to match phosphor patterns

Supported Icon Libraries:

  • lucide - Lucide React (lucide-react)
  • tabler - Tabler Icons (@tabler/icons-react)
  • hugeicons - HugeIcons (@hugeicons/react, @hugeicons/core-free-icons)
  • phosphor - Phosphor Icons (@phosphor-icons/react)

Note: These transformers work directly on ts-morph SourceFile ASTs, not raw strings. For complete string-to-string transformations with multiple transformers, the shadcn CLI uses an internal transform function that chains these transformers together.

transformMenu

Transforms menu components for different styles and configurations. Adjusts menu component structure based on menuColor and menuAccent settings. This transformer modifies the Abstract Syntax Tree (AST) using ts-morph and returns the modified SourceFile object.

/**
 * Transform menu components
 * @param opts - Transform options with config and sourceFile
 * @returns Promise resolving to transformed SourceFile AST
 */
const transformMenu: Transformer

Type: Transformer - A transformer function that operates on ts-morph SourceFile ASTs

Parameters:

  • opts: TransformOpts & { sourceFile: SourceFile } - Options including:
    • filename: string - Component filename. Required.
    • raw: string - Raw source code. Required.
    • config: Config - Configuration with menu-related properties (menuColor, menuAccent). Required.
    • sourceFile: SourceFile - ts-morph SourceFile AST to transform. Required.

Returns: Promise<SourceFile> - Transformed SourceFile AST (call .getText() to get string)

Usage Example:

import { transformMenu } from 'shadcn/utils';
import { Project, ScriptKind } from 'ts-morph';

const menuCode = `
export function Menu() {
  return (
    <nav>
      <MenuItem>Home</MenuItem>
      <MenuItem>About</MenuItem>
    </nav>
  );
}
`;

// Create a SourceFile AST using ts-morph
const project = new Project();
const sourceFile = project.createSourceFile('menu.tsx', menuCode, {
  scriptKind: ScriptKind.TSX
});

// Transform the SourceFile
await transformMenu({
  filename: 'menu.tsx',
  raw: menuCode,
  config: {
    menuColor: 'inverted',
    menuAccent: 'bold',
    // ...other config
  },
  sourceFile: sourceFile
});

// Extract the transformed code
const transformedCode = sourceFile.getText();

Configuration Options:

  • menuColor: "default" | "inverted" - Menu color scheme
  • menuAccent: "subtle" | "bold" - Menu accent style

transformRender

Transforms render functions for framework compatibility. Adjusts render patterns for different React configurations. This transformer modifies the Abstract Syntax Tree (AST) using ts-morph and returns the modified SourceFile object.

/**
 * Transform render functions
 * @param opts - Transform options with config and sourceFile
 * @returns Promise resolving to transformed SourceFile AST
 */
const transformRender: Transformer

Type: Transformer - A transformer function that operates on ts-morph SourceFile ASTs

Parameters:

  • opts: TransformOpts & { sourceFile: SourceFile } - Options including:
    • filename: string - Component filename. Required.
    • raw: string - Raw source code. Required.
    • config: Config - Configuration object. Required.
    • sourceFile: SourceFile - ts-morph SourceFile AST to transform. Required.

Returns: Promise<SourceFile> - Transformed SourceFile AST (call .getText() to get string)

Usage Example:

import { transformRender } from 'shadcn/utils';
import { Project, ScriptKind } from 'ts-morph';

const sourceCode = `
export function Component() {
  return <div>Hello</div>;
}
`;

// Create a SourceFile AST using ts-morph
const project = new Project();
const sourceFile = project.createSourceFile('component.tsx', sourceCode, {
  scriptKind: ScriptKind.TSX
});

// Transform the SourceFile
await transformRender({
  filename: 'component.tsx',
  raw: sourceCode,
  config: myConfig,
  sourceFile: sourceFile
});

// Extract the transformed code
const transformedCode = sourceFile.getText();

Internal Transformers (Not Exported)

Note: The following transformers are used internally by the shadcn CLI and are NOT exported from the shadcn/utils entry point. They are documented here for reference and understanding of the transformation pipeline, but cannot be directly imported unless you use internal paths (not recommended). For public API usage, use the exported functions above (transformStyle, transformIcons, transformMenu, transformRender, createStyleMap).

transform

Applies multiple transformers to source code. Chains transformers in sequence.

/**
 * Apply multiple transformers to source code
 * @param opts - Transform options
 * @param transformers - Optional array of transformer functions
 * @returns Promise resolving to transformed code
 */
function transform(
  opts: TransformOpts,
  transformers?: Transformer<any>[]
): Promise<string>

Note: Not available via public API. Used internally by the CLI.

Transform Order (when using default transformers):

  1. transformImport - Updates import paths
  2. transformRsc - Adds "use client" if needed
  3. transformCssVars - Converts CSS variables
  4. transformTwPrefixes - Adds Tailwind prefix
  5. transformIcons - Converts icon imports
  6. transformMenu - Adjusts menu components
  7. transformAsChild - Handles asChild prop
  8. transformJsx - Converts to JavaScript if needed

transformImport

Transforms import statements to match project alias configuration. Updates import paths based on configured aliases.

/**
 * Transform import statements
 * @param opts - Transform options with config
 * @returns Promise resolving to transformed code
 */
function transformImport(opts: TransformOpts): Promise<string>

Note: Not available via public API. Used internally by the CLI to transform import paths based on configured aliases.

What it does:

  • Replaces relative imports with alias paths (e.g., @/components)
  • Updates import paths to match config.aliases settings
  • Preserves import structure and named/default imports

transformRsc

Transforms code for React Server Components compatibility. Adds "use client" directive when needed.

/**
 * Transform for React Server Components
 * @param opts - Transform options with config
 * @returns Promise resolving to transformed code
 */
function transformRsc(opts: TransformOpts): Promise<string>

Note: Not available via public API. Used internally by the CLI to add "use client" directive when components use hooks or browser APIs.

What it does:

  • Detects usage of hooks (useState, useEffect, etc.)
  • Detects browser APIs (window, document, etc.)
  • Adds "use client" directive at top of file when needed
  • Only applies when config.rsc is true

transformCssVars

Transforms CSS variables to match theme configuration. Converts CSS variable references based on baseColor and cssVariables settings.

/**
 * Transform CSS variables
 * @param opts - Transform options with config and baseColor
 * @returns Promise resolving to transformed code
 */
function transformCssVars(opts: TransformOpts): Promise<string>

Note: Not available via public API. Used internally by the CLI to transform CSS variable references based on baseColor and cssVariables settings.

What it does:

  • Replaces CSS variable references with theme-specific values
  • Updates HSL color values based on baseColor
  • Handles both light and dark theme variables
  • Only applies when config.tailwind.cssVariables is true

transformTwPrefixes

Transforms Tailwind CSS prefixes. Adds configured prefix to Tailwind utility classes.

/**
 * Transform Tailwind CSS prefixes
 * @param opts - Transform options with config
 * @returns Promise resolving to transformed code
 */
function transformTwPrefixes(opts: TransformOpts): Promise<string>

Note: Not available via public API. Used internally by the CLI to add configured prefix to Tailwind utility classes.

What it does:

  • Adds prefix to Tailwind utility classes (e.g., tw- prefix)
  • Updates className attributes
  • Preserves non-Tailwind classes
  • Only applies when config.tailwind.prefix is set

transformAsChild

Transforms asChild prop pattern. Converts asChild prop usage to match configuration.

/**
 * Transform asChild prop usage
 * @param opts - Transform options with config
 * @returns Promise resolving to transformed code
 */
function transformAsChild(opts: TransformOpts): Promise<string>

Note: Not available via public API. Used internally by the CLI to handle asChild prop pattern transformations.

transformJsx

Transforms JSX to JavaScript when tsx is false. Converts TypeScript React code to plain JavaScript.

/**
 * Transform JSX to JavaScript
 * @param opts - Transform options with config
 * @returns Promise resolving to transformed code
 */
function transformJsx(opts: TransformOpts): Promise<string>

Note: Not available via public API. Used internally by the CLI to convert TypeScript code to JavaScript when tsx is false.

What it does:

  • Removes TypeScript type annotations
  • Converts .tsx syntax to .jsx
  • Preserves JSX structure
  • Only applies when config.tsx is false

transformLegacyIcons

Transforms legacy icon usage patterns. Updates old icon patterns to current standards.

/**
 * Transform legacy icon usage
 * @param opts - Transform options with config
 * @returns Promise resolving to transformed code
 */
function transformLegacyIcons(opts: TransformOpts): Promise<string>

Note: Not available via public API. Used internally by the CLI to handle legacy icon import patterns.

Types

// Transform options type (internal use - not exported)
type TransformOpts = {
  filename: string
  raw: string
  config: Config
  baseColor?: RegistryBaseColor
  transformJsx?: boolean
  isRemote?: boolean
}

// Transformer type (exported from shadcn/utils)
// Used by transformIcons, transformMenu, transformRender
type Transformer<Output = SourceFile> = (
  opts: TransformOpts & {
    sourceFile: SourceFile
  }
) => Promise<Output>

// Style transformer type (not re-exported from shadcn/utils)
// Available for custom transformers, but accessed via direct import from styles/transform
type TransformerStyle<Output = SourceFile> = (opts: {
  sourceFile: SourceFile
  styleMap: StyleMap
}) => Promise<Output>

// Style map type
type StyleMap = Record<string, string>

// Note: SourceFile is from the 'ts-morph' package, an external dependency
// used for Abstract Syntax Tree manipulation during transformations

Transformation Pipeline

The typical transformation pipeline for adding a component:

  1. transformImport - Updates import paths to match aliases
  2. transformRsc - Adds "use client" for RSC if needed
  3. transformCssVars - Converts CSS variables to theme colors
  4. transformTwPrefixes - Adds Tailwind prefix if configured
  5. transformIcons - Converts icon library imports
  6. transformMenu - Adjusts menu components
  7. transformAsChild - Handles asChild prop pattern
  8. transformJsx - Converts to JavaScript if tsx is false

Usage Example: Complete Transformation

Note: The complete transformation pipeline uses internal transformers that are not available through the public API. The exported transformers (transformStyle, transformIcons, transformMenu, transformRender) can be used individually:

import {
  transformStyle,
  transformIcons,
  transformMenu,
  transformRender,
  createStyleMap
} from 'shadcn/utils';
import { Project, ScriptKind } from 'ts-morph';

// Example: Transform styles (string-to-string)
const styleMap = createStyleMap(cssInput);
const styledCode = await transformStyle(componentSource, { styleMap });

// Example: Transform icons (requires SourceFile)
const project = new Project();
const sourceFile = project.createSourceFile('button.tsx', componentSource, {
  scriptKind: ScriptKind.TSX
});

await transformIcons({
  filename: 'button.tsx',
  raw: componentSource,
  config: myConfig,
  sourceFile: sourceFile
});

const iconTransformed = sourceFile.getText();

// Example: Transform menu (requires SourceFile)
const menuSourceFile = project.createSourceFile('menu.tsx', menuSource, {
  scriptKind: ScriptKind.TSX
});

await transformMenu({
  filename: 'menu.tsx',
  raw: menuSource,
  config: myConfig,
  sourceFile: menuSourceFile
});

const menuTransformed = menuSourceFile.getText();

// Example: Transform render (requires SourceFile)
const componentSourceFile = project.createSourceFile('component.tsx', componentSource, {
  scriptKind: ScriptKind.TSX
});

await transformRender({
  filename: 'component.tsx',
  raw: componentSource,
  config: myConfig,
  sourceFile: componentSourceFile
});

const renderTransformed = componentSourceFile.getText();

Custom Style Transformers

You can create custom style transformers for use with transformStyle. Note that TransformerStyle type is not re-exported from shadcn/utils, so you would need to define the type inline or access internal exports:

import { transformStyle } from 'shadcn/utils';
import type { SourceFile } from 'ts-morph';

// Define transformer type inline (recommended for external use)
type StyleTransformer = (opts: {
  sourceFile: SourceFile;
  styleMap: Record<string, string>;
}) => Promise<SourceFile>;

// Custom style transformer
const customStyleTransformer: StyleTransformer = async ({ sourceFile, styleMap }) => {
  // Perform custom transformation on the sourceFile
  // using ts-morph APIs
  
  return sourceFile;
};

// Use with transformStyle
const result = await transformStyle(source, {
  styleMap,
  transformers: [customStyleTransformer]
});

Agent Integration Patterns

Transforming Component Code

import { transformIcons } from 'shadcn/utils';
import { Project, ScriptKind } from 'ts-morph';

async function transformComponentCode(
  sourceCode: string,
  config: Config
): Promise<string> {
  const project = new Project();
  const sourceFile = project.createSourceFile('component.tsx', sourceCode, {
    scriptKind: ScriptKind.TSX
  });

  // Apply icon transformation
  await transformIcons({
    filename: 'component.tsx',
    raw: sourceCode,
    config,
    sourceFile
  });

  return sourceFile.getText();
}

Batch Transformation

import { transformStyle, createStyleMap } from 'shadcn/utils';

async function transformMultipleComponents(
  components: Array<{ name: string; code: string }>,
  cssVars: string
): Promise<Array<{ name: string; code: string }>> {
  const styleMap = createStyleMap(cssVars);
  
  return Promise.all(
    components.map(async (component) => ({
      ...component,
      code: await transformStyle(component.code, { styleMap })
    }))
  );
}