or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

config-loading.mdcore-preset.mddependencies.mdhook-optimization.mdindex.mdreact-preset-and-utilities.md
tile.json

hook-optimization.mddocs/

Hook Optimization

Babel plugin that optimizes React hook array destructuring to object destructuring for better performance and smaller bundle sizes. This plugin transforms array destructuring patterns commonly used with React hooks into more efficient object destructuring patterns.

Capabilities

Hook Optimization Plugin Factory

Creates a Babel plugin that transforms React hook array destructuring patterns.

/**
 * Babel plugin factory for optimizing React hook destructuring
 * @param {object} babel - Babel object with types utility
 * @returns {BabelPlugin} Babel plugin object with visitor pattern
 */
function optimizeHookDestructuring({ types });

interface HookOptimizationOptions {
  /** Only transform built-in React hooks */
  onlyBuiltIns?: boolean;
  /** Libraries that provide hooks (true for React/Preact, or specific library name) */
  lib?: boolean | string;
}

interface BabelPlugin {
  name: string;
  visitor: object;
}

Usage Examples:

// Babel configuration with hook optimization
{
  "plugins": [
    ["./optimize-hook-destructuring", {
      "lib": true,
      "onlyBuiltIns": false
    }]
  ]
}

// Programmatic usage
import babel from "@babel/core";
import optimizeHookDestructuring from "./optimize-hook-destructuring";

const result = babel.transform(code, {
  plugins: [
    [optimizeHookDestructuring, { lib: true }]
  ]
});

Transformation Examples

Basic Hook Transformation

The plugin transforms array destructuring to object destructuring for better performance:

Before transformation:

import { useState } from "react";

const [count, setCount] = useState(0);
const [name, setName] = useState("");

After transformation:

import { useState } from "react";

const { 0: count, 1: setCount } = useState(0);
const { 0: name, 1: setName } = useState("");

Custom Hook Transformation

Works with custom hooks that follow the use* naming pattern:

Before transformation:

import { useCustomState } from "./hooks";

const [value, setValue, reset] = useCustomState(initialValue);

After transformation:

import { useCustomState } from "./hooks";

const { 0: value, 1: setValue, 2: reset } = useCustomState(initialValue);

Built-in Hook Filtering

When onlyBuiltIns: true, only transforms recognized React built-in hooks:

Recognized built-in hooks:

  • useCallback
  • useContext
  • useDebugValue
  • useEffect
  • useImperativeHandle
  • useLayoutEffect
  • useMemo
  • useReducer
  • useRef
  • useState
// Configuration for built-ins only
{
  "plugins": [
    ["./optimize-hook-destructuring", {
      "onlyBuiltIns": true
    }]
  ]
}

Configuration Options

Library Filtering (lib)

Controls which libraries are processed for hook transformations:

// Process React and Preact hooks (default when lib: true)
{
  "lib": true
}

// Process specific library only
{
  "lib": "react"
}

// Process custom hook library
{
  "lib": "my-hooks-library"
}

// No library filtering (process all hook-like functions)
{
  // lib option omitted
}

Library configuration examples:

// React hooks only
import { useState } from "react";
const [count, setCount] = useState(0); // ✅ Transformed

import { useCustom } from "other-lib";
const [value, setValue] = useCustom(); // ❌ Not transformed

// Custom library
{
  "lib": "my-hooks"
}

import { useMyHook } from "my-hooks";
const [data, setData] = useMyHook(); // ✅ Transformed

import { useState } from "react";
const [count, setCount] = useState(0); // ❌ Not transformed

Built-in Hook Filtering (onlyBuiltIns)

Restricts transformations to only React's built-in hooks:

// Transform all hook-like functions (default)
{
  "onlyBuiltIns": false
}

// Transform only React built-in hooks
{
  "onlyBuiltIns": true
}

Built-in filtering examples:

// onlyBuiltIns: false (default)
const [state, setState] = useState(0);        // ✅ Transformed
const [data, setData] = useCustomHook();      // ✅ Transformed

// onlyBuiltIns: true
const [state, setState] = useState(0);        // ✅ Transformed
const [data, setData] = useCustomHook();      // ❌ Not transformed

Pattern Matching

Hook Name Detection

The plugin uses regular expressions to identify hook functions:

Default pattern (all hooks):

const isHook = /^use[A-Z]/;
// Matches: useState, useEffect, useCustomHook, etc.

Built-in hooks pattern:

const isBuiltInHook = /^use(Callback|Context|DebugValue|Effect|ImperativeHandle|LayoutEffect|Memo|Reducer|Ref|State)$/;
// Matches only: useCallback, useContext, useDebugValue, etc.

Import Source Validation

When library filtering is enabled, the plugin validates import sources:

// Valid import for React hooks
import { useState } from "react";
const [count, setCount] = useState(0); // ✅ Processed

// Invalid import source
import { useState } from "other-library";
const [count, setCount] = useState(0); // ❌ Skipped

Performance Benefits

Bundle Size Reduction

Object destructuring can be more efficiently minified than array destructuring:

Array destructuring (before):

const [a, b, c] = hook();
// Minified: const[a,b,c]=hook();

Object destructuring (after):

const {0: a, 1: b, 2: c} = hook();
// Minified: const{0:a,1:b,2:c}=hook();
// Further optimization possible by minifiers

Runtime Performance

Object destructuring can have slight performance advantages in certain JavaScript engines for accessing specific indices.

Integration with Gatsby

The plugin is automatically included in the babel-preset-gatsby configuration:

// Automatic inclusion in Gatsby projects
{
  "plugins": [
    [
      "./optimize-hook-destructuring",
      {
        "lib": true
      }
    ]
  ]
}

Advanced Usage Patterns

Custom Plugin Configuration

You can configure the plugin separately for advanced use cases:

// Custom Babel configuration
{
  "presets": ["babel-preset-gatsby"],
  "plugins": [
    // Additional hook optimization with custom settings
    ["babel-preset-gatsby/optimize-hook-destructuring", {
      "lib": "my-custom-hooks",
      "onlyBuiltIns": false
    }]
  ]
}

Conditional Transformation

The plugin only transforms code that meets all criteria:

  1. Function call is assigned to a variable
  2. Assignment uses array destructuring
  3. Function name matches hook pattern
  4. Import source matches library filter (if specified)
  5. Hook type matches built-in filter (if specified)
// All conditions met - will be transformed
import { useState } from "react";
const [count, setCount] = useState(0);

// Not transformed - not array destructuring
const state = useState(0);

// Not transformed - not a variable assignment
useState(0);

// Not transformed - doesn't match hook pattern
const [data, setData] = fetchData();