Handoff is designed to be highly extensible through its powerful hooking architecture. Learn how to tap into the build pipeline at various stages to customize token transformations, generate custom documentation, or integrate with external tools. Empower your team to build a bespoke design system workflow that fits your unique needs.
Handoff's power lies in its extensibility. The hooking architecture allows you to intercept the design-to-code pipeline at critical points—whether you need to modify how tokens are transformed, customize the build process for your components, or run automated validations against your design system.
handoff.config.js file.The pipeline.transformers hook is the most powerful way to "alter the data" produced by Handoff. It allows you to add custom logic that runs after design tokens are extracted from Figma but before they are saved to disk.
A DocumentationObject containing all extracted localStyles (colors, typography, effects) and components.
Generating a flat JSON file specifically for a mobile application or a secondary tool.
example.javascriptjavascript1// handoff.config.js 2module.exports = { 3 pipeline: { 4 transformers: [ 5 { 6 transformer: (options) => ({ 7 name: 'MobileTokenTransformer', 8 transform: (docs) => { 9 const tokens = { 10 colors: docs.localStyles.colors.map(c => ({ name: c.name, hex: c.value })), 11 }; 12 return { 13 design: { 14 'mobile-tokens.json': JSON.stringify(tokens, null, 2) 15 } 16 }; 17 } 18 }), 19 outDir: 'mobile', 20 format: 'json' 21 } 22 ] 23 } 24};
These hooks allow you to intercept and modify the underlying build configurations for Vite and esbuild.
jsBuildConfigOverrides the Vite configuration used for the main JavaScript bundle and component scripts.
InlineConfig (Vite)InlineConfigexample.javascriptjavascript1jsBuildConfig: (config) => { 2 config.define = { ...config.define, 'process.env.MY_VAR': '"value"' }; 3 return config; 4}
cssBuildConfigOverrides the Vite configuration used for Sass/CSS compilation.
InlineConfig (Vite)InlineConfigexample.javascriptjavascript1cssBuildConfig: (config) => { 2 // Add custom PostCSS plugins or Sass options 3 return config; 4}
ssrBuildConfigOverrides the esbuild configuration used to render React components on the server for documentation previews.
BuildOptions (esbuild)BuildOptionsexample.javascriptjavascript1ssrBuildConfig: (config) => { 2 config.external = ['some-heavy-library']; 3 return config; 4}
These hooks control how Handoff interprets component metadata and transitions between different data formats.
getSchemaFromExportsDefines where Handoff should find the property schema in a component's JavaScript exports.
exports (The module exports object)example.javascriptjavascript1getSchemaFromExports: (exports) => { 2 return exports.myCustomSchema || exports.default; 3}
schemaToPropertiesTransforms a raw schema object into Handoff's internal SlotMetadata format. Use this to support custom documentation formats or legacy schemas.
schema (The object returned by getSchemaFromExports){ [propertyName: string]: SlotMetadata }example.javascriptjavascript1schemaToProperties: (schema) => { 2 // Map your custom schema format to Handoff properties 3 return Object.entries(schema).reduce((acc, [key, val]) => ({ 4 ...acc, 5 [key]: { type: 'text', name: key, default: val.default } 6 }), {}); 7}
validateComponentAn asynchronous hook that runs after a component is built. Use this to enforce design system rules or accessibility standards.
component (TransformComponentTokensResult)Promise<Record<string, ValidationResult>>example.javascriptjavascript1validateComponent: async (component) => { 2 const results = {}; 3 4 // Check for minimum property requirements 5 if (!component.properties.label) { 6 results.metadata = { 7 description: 'Component Metadata Check', 8 passed: false, 9 messages: ['All buttons must have a label property.'] 10 }; 11 } 12 13 return results; 14}
Validated results are saved directly into the components.json and are displayed within the Handoff documentation UI.