or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

index.mddocs/

@babel/plugin-proposal-class-properties

@babel/plugin-proposal-class-properties is a Babel plugin that transforms static class properties as well as properties declared with the property initializer syntax. This plugin enables modern JavaScript class property syntax to be compiled to older JavaScript environments that don't natively support this syntax.

Package Information

  • Package Name: @babel/plugin-proposal-class-properties
  • Package Type: npm (Babel plugin)
  • Language: TypeScript
  • Installation: npm install --save-dev @babel/plugin-proposal-class-properties

Core Imports

The plugin is designed to be used in Babel configuration files rather than directly imported in code:

// babel.config.js
module.exports = {
  plugins: ["@babel/plugin-proposal-class-properties"]
};
// .babelrc
{
  "plugins": ["@babel/plugin-proposal-class-properties"]
}

For programmatic usage:

const babel = require("@babel/core");
const classPropertiesPlugin = require("@babel/plugin-proposal-class-properties");

const result = babel.transformSync(code, {
  plugins: [classPropertiesPlugin]
});

Basic Usage

This plugin transforms class properties from modern JavaScript syntax to compatible older syntax:

Input (Modern Syntax):

class Example {
  // Instance property with initializer
  message = "Hello World";
  
  // Static property
  static version = "1.0.0";
  
  // Computed property
  ["computed" + "Prop"] = true;
}

Output (Transformed):

class Example {
  constructor() {
    this.message = "Hello World";
    this["computed" + "Prop"] = true;
  }
}

Example.version = "1.0.0";

Capabilities

Default Export

The main plugin export that creates a Babel transformation plugin using the declare helper from @babel/helper-plugin-utils.

/**
 * Default export - Babel plugin function created using declare()
 * @param api - Babel API object with version assertion
 * @param options - Plugin configuration options
 * @returns Babel plugin configuration object created by createClassFeaturePlugin
 */
declare function default(api: BabelAPI, options: Options): BabelPlugin;

interface BabelAPI {
  assertVersion(version: number): void;
}

interface BabelPlugin {
  name: string;
  manipulateOptions: (opts: any, parserOpts: any) => void;
  visitor: object;
}

Options Export

Configuration interface for customizing plugin behavior. This interface is exported as a named export.

/**
 * Configuration options interface - exported as named export
 */
export interface Options {
  /**
   * Enable loose mode transformation for better performance.
   * When true, uses simple property assignment instead of Object.defineProperty.
   * @default false
   */
  loose?: boolean;
}

Usage with options:

// babel.config.js
module.exports = {
  plugins: [
    ["@babel/plugin-proposal-class-properties", { loose: true }]
  ]
};

Loose mode transformation:

Input:

class Example {
  prop = "value";
}

Output (loose: false - default):

class Example {
  constructor() {
    Object.defineProperty(this, "prop", {
      configurable: true,
      enumerable: true,
      writable: true,
      value: "value"
    });
  }
}

Output (loose: true):

class Example {
  constructor() {
    this.prop = "value";
  }
}

Parser Integration

The plugin automatically enables required Babel parser plugins:

/**
 * Parser plugins automatically enabled by this plugin
 */
interface ParserPlugins {
  classProperties: true;
  classPrivateProperties: true;
}

This means you don't need to manually configure the parser when using this plugin.

Transformation Behavior

Instance Properties

Transforms instance properties with initializers to constructor assignments:

// Input
class User {
  name = "Anonymous";
  isActive = false;
}

// Output  
class User {
  constructor() {
    this.name = "Anonymous";
    this.isActive = false;
  }
}

Static Properties

Transforms static properties to assignments after the class declaration:

// Input
class Config {
  static version = "1.0.0";
  static debug = process.env.NODE_ENV === "development"; 
}

// Output
class Config {}

Config.version = "1.0.0";
Config.debug = process.env.NODE_ENV === "development";

Computed Properties

Supports computed property names:

// Input
class Dynamic {
  [Symbol.toStringTag] = "Dynamic";
  ["prop_" + Math.random()] = true;
}

// Output
class Dynamic {
  constructor() {
    this[Symbol.toStringTag] = "Dynamic";
    this["prop_" + Math.random()] = true;
  }
}

Private Properties

When used with private property syntax (requires additional parser configuration):

// Input (with private properties enabled)
class Secure {
  #secret = "hidden";
  publicMethod() {
    return this.#secret;
  }
}

// Output varies based on private properties plugin configuration

Integration with Babel Ecosystem

Preset Compatibility

This plugin is included in:

  • @babel/preset-env (when targeting environments that don't support class properties)
  • @babel/preset-typescript (for TypeScript compilation)

Plugin Dependencies

The plugin uses these internal Babel helpers:

  • @babel/helper-create-class-features-plugin: Core transformation logic
  • @babel/helper-plugin-utils: Plugin declaration utilities

Assumptions Support (Babel 7.13+)

When using Babel assumptions, this plugin respects the setPublicClassFields assumption:

// babel.config.js
module.exports = {
  plugins: ["@babel/plugin-proposal-class-properties"],
  assumptions: {
    "setPublicClassFields": true  // Similar to loose: true
  }
};

Error Handling

The plugin handles several edge cases and error conditions:

  • Super class references: Properly handles property initialization in classes with inheritance
  • Constructor conflicts: Manages existing constructors when adding property initializations
  • Execution order: Ensures proper initialization order for complex property expressions
  • Babel version compatibility: Requires Babel 7.0.0 or higher

Common error patterns to avoid:

// Problematic: Using 'super' in property initializer
class Child extends Parent {
  // This will cause runtime errors in some cases
  prop = super.getValue(); // Avoid this pattern
}

// Better: Initialize in constructor
class Child extends Parent {
  constructor() {
    super();
    this.prop = super.getValue();
  }
}