Skip to main content

Installation

Install the @tempad-dev/plugins package to get full type support:
npm install -D @tempad-dev/plugins

Basic plugin structure

Every plugin exports an object with a name and a code configuration:
import { definePlugin } from '@tempad-dev/plugins'

export default definePlugin({
  name: 'My Plugin',
  code: {
    // Built-in blocks you can override
    css: { /* configuration */ },
    js: false,  // or hide them entirely
    
    // Custom blocks you can add
    tailwind: { /* configuration */ },
    component: { /* configuration */ }
  }
})
Your plugin file must be a valid ES module and export the plugin object as the default export or plugin named export.

Transform hooks

Plugins provide four hooks for customizing code output:

transform - Main code transformation

Transform the entire style object into a custom format.
import { definePlugin } from '@tempad-dev/plugins'

export default definePlugin({
  name: 'SCSS Converter',
  code: {
    css: {
      title: 'SCSS',
      lang: 'scss',
      transform({ code, style, options }) {
        // code: "background-color: red; color: blue;"
        // style: { "background-color": "red", "color": "blue" }
        // options: { useRem: true, rootFontSize: 16 }
        
        return Object.entries(style)
          .map(([prop, value]) => `  ${prop}: ${value};`)
          .join('\n')
      }
    }
  }
})
Parameters:
  • code - The generated CSS string
  • style - Parsed CSS properties as a key-value object
  • options.useRem - Whether user enabled rem conversion
  • options.rootFontSize - Root font size for rem calculations

transformVariable - Variable conversion

Convert CSS variables to your preferred format.
export default definePlugin({
  name: 'Sass Variables',
  code: {
    css: {
      transformVariable({ code, name, value, options }) {
        // code: "var(--color-primary, #6699cc)"
        // name: "color-primary"
        // value: "#6699cc" (optional)
        
        // Convert to Sass variable
        return `$${name}`
      }
    }
  }
})
Parameters:
  • code - Full var(--token, fallback) CSS snippet
  • name - Variable name without var(--...) wrapper
  • value - Default fallback value (if defined)
  • options - Same as transform hook

transformPx - Pixel value conversion

Customize how pixel values are converted.
export default definePlugin({
  name: 'Custom Scaling',
  code: {
    css: {
      transformPx({ value, options }) {
        // value: 16 (numeric pixel value)
        // options.useRem: true/false
        // options.rootFontSize: 16
        
        if (options.useRem) {
          return `${value / options.rootFontSize}rem`
        }
        
        // Apply 2x scaling for retina
        return `${value * 2}px`
      }
    }
  }
})
Parameters:
  • value - Numeric pixel value
  • options - User preferences for rem conversion

transformComponent - Component code generation

Generate framework-specific component code from Figma instances.
import { definePlugin, h, findChild, type TextNode } from '@tempad-dev/plugins'

export default definePlugin({
  name: 'React Components',
  code: {
    component: {
      title: 'Component',
      lang: 'tsx',
      transformComponent({ component }) {
        // component: DesignComponent (Figma instance)
        // component.properties: { variant: 'primary', size: 'lg' }
        // component.children: [...nested nodes]
        
        const title = findChild<TextNode>(component, { type: 'TEXT' })
        
        return h('Button', 
          { 
            variant: component.properties.variant,
            size: component.properties.size 
          }, 
          [title?.characters || 'Click me']
        )
      }
    }
  }
})
Parameters:
  • component - The design component (Figma instance) being inspected
Return value:
  • DevComponent - Tree built with h() helper
  • string - Raw code string

Working with design nodes

The SDK provides utilities for querying Figma node structures:

Node types

import type {
  DesignNode,      // Union of all node types
  DesignComponent, // Component instance (type: 'INSTANCE')
  TextNode,        // Text node (type: 'TEXT')
  FrameNode,       // Frame node (type: 'FRAME')
  GroupNode,       // Group node (type: 'GROUP')
  VectorNode       // Vector node (type: 'VECTOR')
} from '@tempad-dev/plugins'

Finding nodes

import { 
  findChild,    // First direct child matching query
  findChildren, // All direct children matching query
  findOne,      // First node in tree (depth-first)
  findAll       // All nodes in tree (depth-first)
} from '@tempad-dev/plugins'

// Property-based queries
const title = findChild(component, { type: 'TEXT', name: 'Title' })
const icons = findChildren(toolbar, { type: 'VECTOR' })

// Regular expression queries
const header = findOne(page, { name: /header/i })

// Array matching
const button = findOne(frame, { name: ['Submit', 'Cancel', 'OK'] })

// Predicate functions
const hidden = findAll(component, (node) => !node.visible)

Chained queries

import { queryOne, queryAll } from '@tempad-dev/plugins'

// Find footer, then all buttons inside it
const buttons = queryAll(page, [
  { query: 'children', name: 'Footer' },
  { query: 'all', type: 'INSTANCE', name: /Button/ }
])

// Find first matching node in pipeline
const logo = queryOne(page, [
  { query: 'one', name: /header/i },
  { query: 'child', type: 'VECTOR', name: 'Logo' }
])
Query types:
  • child - First direct child
  • children - All direct children
  • one - First in tree (depth-first)
  • all - All in tree (depth-first)

Building component trees

Use the h() helper to build component trees that TemPad Dev serializes to JSX/Vue:
import { h } from '@tempad-dev/plugins'

// Simple element
h('Button')
// <Button />

// With children string
h('Button', 'Submit')
// <Button>Submit</Button>

// With props
h('Button', { variant: 'primary', size: 'lg' })
// <Button variant="primary" size="lg" />

// With props and children
h('Card', { padding: 'md' }, [
  h('Heading', { level: 2 }, ['Dashboard']),
  h('Text', 'Welcome back')
])
// <Card padding="md">
//   <Heading level={2}>Dashboard</Heading>
//   <Text>Welcome back</Text>
// </Card>

// Nested components
h('Container', { size: 'lg' }, [
  h('Header', [
    h('Logo'),
    h('Nav', [
      h('NavItem', { href: '/' }, ['Home']),
      h('NavItem', { href: '/about' }, ['About'])
    ])
  ])
])

Raw markup output

For advanced cases where you need raw HTML/JSX, use the raw() helper:
import { raw } from '@tempad-dev/plugins'

export default definePlugin({
  name: 'Raw Output',
  code: {
    component: {
      transformComponent({ component }) {
        // Output raw JSX string
        return raw('<Button variant="primary">Click me</Button>')
      }
    }
  }
})

JavaScript variable interpolation

Wrap variable names in \0 characters to convert them into template string interpolation:
transform({ style }) {
  // Return: 'calc(\0spacing\0 + 10px)'
  // Output in JS: `calc(${spacing} + 10px)`
  return `calc(\0spacing\0 + 10px)`
}
This is useful when generating JavaScript code that references variables.

Complete example

Here’s a full plugin that demonstrates multiple hooks:
import { definePlugin, h, findChild, type TextNode } from '@tempad-dev/plugins'

export default definePlugin({
  name: 'Design System Plugin',
  code: {
    // Override CSS output
    css: {
      title: 'Design Tokens',
      lang: 'css',
      transform({ style }) {
        return Object.entries(style)
          .map(([prop, value]) => `${prop}: ${value};`)
          .join('\n')
      },
      transformVariable({ name }) {
        // Convert var(--spacing-md) to token.spacing.md
        return `token.${name.replace(/-/g, '.')}`
      },
      transformPx({ value, options }) {
        // Custom spacing scale
        const scale = [0, 4, 8, 16, 24, 32, 48, 64]
        const closest = scale.reduce((prev, curr) => 
          Math.abs(curr - value) < Math.abs(prev - value) ? curr : prev
        )
        return `spacing-${scale.indexOf(closest)}`
      }
    },
    
    // Add component output
    component: {
      title: 'React',
      lang: 'tsx',
      transformComponent({ component }) {
        const label = findChild<TextNode>(component, { type: 'TEXT' })
        
        return h('Button',
          {
            variant: component.properties.variant || 'default',
            size: component.properties.size || 'md'
          },
          [label?.characters || 'Button']
        )
      }
    },
    
    // Hide JavaScript output
    js: false
  }
})

Type definitions reference

For complete type definitions, see the source code. Key types:
  • Plugin - Main plugin configuration
  • CodeBlockOptions - Configuration for code blocks
  • TransformParams - Parameters for transform hook
  • TransformVariableParams - Parameters for transformVariable hook
  • TransformPxParams - Parameters for transformPx hook
  • TransformComponentParams - Parameters for transformComponent hook
  • DesignNode - Union of all design node types
  • DevComponent - Component tree structure

Next steps

Deploy Your Plugin

Learn how to host and share your plugin