or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

code-style-rules.mdcomponent-lifecycle-rules.mdindex.mdjsx-syntax-rules.mdplugin-configuration.mdprop-validation-rules.mdreact-component-rules.mdsecurity-safety-rules.md
tile.json

code-style-rules.mddocs/

Code Style and Organization Rules

Rules for consistent code formatting, component organization, and style conventions in React applications. These rules ensure maintainable and readable React codebases.

Capabilities

Component Organization Rules

Rules for organizing components and their internal structure.

const organizationRules = {
  /** Enforce component methods order */
  'react/sort-comp': ESLintRule;
  /** Enforce consistent placement for static properties */
  'react/static-property-placement': ESLintRule;
  /** Enforce destructuring assignment for props, state, and context */
  'react/destructuring-assignment': ESLintRule;
  /** Enforce consistent function component definition style */
  'react/function-component-definition': ESLintRule;
};

Usage Examples:

// ✓ Good - Proper component method order
class MyComponent extends React.Component {
  // Static properties first
  static propTypes = {
    name: PropTypes.string
  };
  
  static defaultProps = {
    name: 'Anonymous'
  };
  
  // Constructor
  constructor(props) {
    super(props);
    this.state = { count: 0 };
  }
  
  // Lifecycle methods
  componentDidMount() {
    this.initializeComponent();
  }
  
  componentDidUpdate(prevProps) {
    if (prevProps.name !== this.props.name) {
      this.handleNameChange();
    }
  }
  
  // Event handlers and custom methods
  handleClick = () => {
    this.setState({ count: this.state.count + 1 });
  }
  
  initializeComponent() {
    // Initialization logic
  }
  
  // Render method last
  render() {
    return (
      <div>
        <span>{this.props.name}: {this.state.count}</span>
        <button onClick={this.handleClick}>Increment</button>
      </div>
    );
  }
}

// ✓ Good - Destructuring assignment
const MyComponent = ({ name, age, onAction }) => {
  const [count, setCount] = useState(0);
  
  return (
    <div>
      <span>{name} ({age}): {count}</span>
      <button onClick={() => setCount(count + 1)}>Increment</button>
      <button onClick={onAction}>Action</button>
    </div>
  );
};

// ✗ Bad - No destructuring
const MyComponent = (props) => {
  const [count, setCount] = useState(0);
  
  return (
    <div>
      <span>{props.name} ({props.age}): {count}</span>
      <button onClick={props.onAction}>Action</button>
    </div>
  );
};

JSX Formatting Rules

Rules for consistent JSX element formatting and structure.

const jsxFormattingRules = {
  /** Enforce self-closing when JSX element has no children */
  'react/self-closing-comp': ESLintRule;
  /** Enforce boolean attributes notation in JSX */
  'react/jsx-boolean-value': ESLintRule;
  /** Enforce or forbid the use of curly braces inside JSX props */
  'react/jsx-curly-brace-presence': ESLintRule;
  /** Prevent missing parentheses around multilines JSX */
  'react/jsx-wrap-multilines': ESLintRule;
};

Usage Examples:

// ✓ Good - Self-closing components
<MyComponent />
<input type="text" />
<img src="image.jpg" alt="Description" />

// ✗ Bad - Unnecessary closing tags
<MyComponent></MyComponent>
<input type="text"></input>
<img src="image.jpg" alt="Description"></img>

// ✓ Good - Consistent boolean attribute style
// Explicit style (when configured)
<MyComponent isVisible={true} isActive={false} />

// Shorthand style (when configured)  
<MyComponent isVisible isActive={false} />

// ✗ Bad - Mixed boolean styles
<MyComponent isVisible={true} isActive />

// ✓ Good - Appropriate curly brace usage
<MyComponent 
  title="Static String"
  count={42}
  isActive={isUserActive}
  style={{ color: 'red' }}
/>

// ✗ Bad - Unnecessary curly braces
<MyComponent 
  title={"Static String"}
  count={"42"}
/>

// ✓ Good - Multiline JSX with parentheses
const element = (
  <div className="container">
    <Header title="My App" />
    <Content data={data} />
    <Footer />
  </div>
);

// ✗ Bad - Multiline JSX without parentheses
const element = <div className="container">
  <Header title="My App" />
  <Content data={data} />
  <Footer />
</div>;

Props and Attributes Styling

Rules for consistent prop and attribute formatting.

const propsStyleRules = {
  /** Enforce props alphabetical sorting */
  'react/jsx-sort-props': ESLintRule;
  /** Disallow multiple spaces between inline JSX props */
  'react/jsx-props-no-multi-spaces': ESLintRule;
  /** Prevent JSX prop spreading */
  'react/jsx-props-no-spreading': ESLintRule;
  /** Disallow JSX props to use spread operator with multiple objects */
  'react/jsx-props-no-spread-multi': ESLintRule;
};

Usage Examples:

// ✓ Good - Props in alphabetical order (when configured)
<MyComponent
  age={25}
  name="John"
  onAction={handleAction}
  role="admin"
/>

// ✗ Bad - Props not alphabetically sorted
<MyComponent
  name="John"
  age={25}
  role="admin"
  onAction={handleAction}
/>

// ✓ Good - Single space between props
<MyComponent prop1="value1" prop2="value2" prop3="value3" />

// ✗ Bad - Multiple spaces between props
<MyComponent prop1="value1"    prop2="value2"   prop3="value3" />

// ✓ Good - Explicit props (when spreading is forbidden)
<MyComponent
  name={user.name}
  email={user.email}
  age={user.age}
/>

// ✗ Bad - Prop spreading (when forbidden)
<MyComponent {...user} />

// ✓ Good - Single spread (when spreading is allowed)
<MyComponent {...commonProps} specificProp="value" />

// ✗ Bad - Multiple spreads
<MyComponent {...props1} {...props2} />

Naming Conventions

Rules for consistent naming patterns in React components.

const namingRules = {
  /** Enforce PascalCase for user-defined JSX components */
  'react/jsx-pascal-case': ESLintRule;
  /** Enforce specific naming pattern for boolean props */
  'react/boolean-prop-naming': ESLintRule;
  /** Enforce event handler naming conventions in JSX */
  'react/jsx-handler-names': ESLintRule;
  /** Prevent missing displayName in React component definition */
  'react/display-name': ESLintRule;
};

Usage Examples:

// ✓ Good - Component names in PascalCase
<UserProfile />
<NavigationBar />
<DataVisualization />

// ✗ Bad - Component names not in PascalCase
<userProfile />
<navigationbar />
<dataVisualization />

// ✓ Good - Boolean props with proper naming
<Modal isOpen hasBackdrop canClose />
<Button isDisabled hasIcon />
<Input isRequired hasError />

// ✗ Bad - Boolean props without proper prefix
<Modal open backdrop close />
<Button disabled icon />
<Input required error />

// ✓ Good - Event handler naming conventions
<Button onClick={handleClick} onHover={handleHover} />
<Input onChange={handleChange} onFocus={handleFocus} />

// ✗ Bad - Event handler naming (when strict conventions enforced)
<Button onClick={click} onHover={hover} />
<Input onChange={change} onFocus={focus} />

// ✓ Good - Component with displayName
const MyComponent = () => <div>Hello</div>;
MyComponent.displayName = 'MyComponent';

export default MyComponent;

File and Import Organization

Rules for organizing imports and file structure.

const fileOrganizationRules = {
  /** Restrict file extensions that may contain JSX */
  'react/jsx-filename-extension': ESLintRule;
  /** Prevent multiple component definition per file */
  'react/no-multi-comp': ESLintRule;
};

Usage Examples:

// ✓ Good - JSX in appropriate file extensions
// UserProfile.jsx
export const UserProfile = ({ user }) => (
  <div>
    <h2>{user.name}</h2>
    <p>{user.email}</p>
  </div>
);

// ✓ Good - One component per file (when rule enforces single component)
// Button.jsx
export const Button = ({ children, onClick }) => (
  <button onClick={onClick}>{children}</button>
);

// ✗ Bad - Multiple components in one file (when single component enforced)
// Components.jsx
export const Button = ({ children }) => <button>{children}</button>;
export const Input = ({ value }) => <input value={value} />;
export const Label = ({ text }) => <label>{text}</label>;

// Configuration for file extensions:
{
  "rules": {
    "react/jsx-filename-extension": [
      "error", 
      { "extensions": [".jsx", ".tsx"] }
    ]
  }
}

Style and CSS Rules

Rules for handling styles and CSS in React components.

const styleRules = {
  /** Enforce style prop value to be an object */
  'react/style-prop-object': ESLintRule;
  /** Forbid certain DOM props */
  'react/forbid-dom-props': ESLintRule;
  /** Forbid certain component props */
  'react/forbid-component-props': ESLintRule;
};

Usage Examples:

// ✓ Good - Style prop as object
<div style={{ color: 'red', fontSize: '16px' }}>
  Styled content
</div>

// ✗ Bad - Style prop as string
<div style="color: red; font-size: 16px;">
  Styled content
</div>

// ✓ Good - CSS classes (when inline styles are forbidden)
<div className="styled-content">
  Content with CSS class
</div>

// ✗ Bad - Inline styles (when forbidden)
<div style={{ color: 'red' }}>
  Content with inline style
</div>

// Configuration example:
{
  "rules": {
    "react/forbid-dom-props": ["error", {
      "forbid": ["style"] // Forbid inline styles
    }],
    "react/forbid-component-props": ["error", {
      "forbid": ["style", "className"] // Forbid styling props on custom components
    }]
  }
}

Code Formatting Rules

Rules for general code formatting and whitespace.

const formattingRules = {
  /** Enforce child element spacing */
  'react/jsx-child-element-spacing': ESLintRule;
  /** Require or prevent a new line after jsx elements and expressions */
  'react/jsx-newline': ESLintRule;
  /** Restrict to one expression per line in JSX */
  'react/jsx-one-expression-per-line': ESLintRule;
};

Usage Examples:

// ✓ Good - Proper child element spacing
<div>
  <span>First element</span>
  <span>Second element</span>
</div>

// ✗ Bad - Missing spacing between inline elements
<div>
  <span>First</span><span>Second</span>
</div>

// ✓ Good - Newlines after JSX elements (when configured)
const MyComponent = () => {
  return (
    <div>
      
      <Header />
      
      <Content />
      
      <Footer />
      
    </div>
  );
};

// ✓ Good - One expression per line
<div>
  <span>{user.name}</span>
  <span>{user.email}</span>
  <span>{user.role}</span>
</div>

// ✗ Bad - Multiple expressions on same line
<div>
  <span>{user.name}</span> <span>{user.email}</span>
</div>

Style Rule Configuration

Code style rules offer extensive configuration options:

{
  "rules": {
    "react/sort-comp": ["error", {
      "order": [
        "static-variables",
        "static-methods",
        "instance-variables",
        "lifecycle",
        "everything-else",
        "render"
      ]
    }],
    
    "react/jsx-sort-props": ["error", {
      "callbacksLast": true,
      "shorthandFirst": false,
      "shorthandLast": true,
      "ignoreCase": true,
      "noSortAlphabetically": false,
      "reservedFirst": true
    }],
    
    "react/function-component-definition": ["error", {
      "namedComponents": "arrow-function",
      "unnamedComponents": "arrow-function"
    }],
    
    "react/destructuring-assignment": ["error", "always", {
      "ignoreClassFields": false,
      "destructureInSignature": "always"
    }],
    
    "react/jsx-curly-brace-presence": ["error", {
      "props": "never",
      "children": "never",
      "propElementValues": "always"
    }],
    
    "react/boolean-prop-naming": ["error", {
      "rule": "^(is|has)[A-Z]([A-Za-z0-9]?)+",
      "message": "Boolean props should start with 'is' or 'has'"
    }]
  }
}

Integration with Prettier

When using Prettier alongside ESLint, some formatting rules may conflict:

// .eslintrc.js
module.exports = {
  extends: [
    'plugin:react/recommended',
    'prettier' // Prettier config should come last
  ],
  rules: {
    // Disable rules that conflict with Prettier
    'react/jsx-indent': 'off',
    'react/jsx-indent-props': 'off',
    'react/jsx-closing-bracket-location': 'off',
    'react/jsx-closing-tag-location': 'off',
    'react/jsx-curly-spacing': 'off',
    'react/jsx-equals-spacing': 'off',
    'react/jsx-first-prop-new-line': 'off',
    'react/jsx-max-props-per-line': 'off',
    'react/jsx-one-expression-per-line': 'off',
    'react/jsx-props-no-multi-spaces': 'off',
    'react/jsx-tag-spacing': 'off',
    'react/jsx-wrap-multilines': 'off',
    
    // Keep non-formatting rules
    'react/jsx-sort-props': 'error',
    'react/self-closing-comp': 'error',
    'react/jsx-boolean-value': 'error'
  }
};