or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

configuration.mdcore-rules.mdindex.mdjsx-rules.mdquality-rules.md
tile.json

jsx-rules.mddocs/

JSX and Component Rules

Rules specifically for JSX patterns, React compatibility, and component best practices in Qwik.

Capabilities

No React Props

Disallows React-specific className/htmlFor props and suggests Qwik alternatives.

/**
 * Disallows React-specific className/htmlFor props with automatic code fixes
 * Provides fix suggestions to convert to Qwik alternatives (class/for)
 */
noReactProps: Rule;

/**
 * Utility function to check if a name is a DOM element using regex test
 * @param name Element name to check
 * @returns true if the name is a standard lowercase DOM element
 */
export function isDOMElementName(name: string): boolean;

Rule Configuration:

  • Type: problem rule with code fixes
  • Category: JSX
  • Recommended: error level
  • Strict: error level

Usage Example:

// ❌ Invalid: React-specific props
<div className="container" htmlFor="input-id"> // Error: use 'class' and 'for'
  <label htmlFor="name">Name</label>
</div>

// ✅ Valid: Qwik props
<div class="container">
  <label for="name">Name</label>
</div>

JSX Key

Disallows missing key props in iterators and collection literals.

/**
 * Disallows missing key props in iterators/collection literals
 * Ensures proper key attribution for list rendering performance
 */
jsxKey: Rule;

Rule Configuration:

  • Type: problem rule
  • Category: JSX
  • Recommended: warn level
  • Strict: error level

Options Schema:

{
  type: 'object',
  properties: {
    checkFragmentShorthand: {
      type: 'boolean',
      default: false
    },
    checkKeyMustBeforeSpread: {
      type: 'boolean', 
      default: false
    },
    warnOnDuplicates: {
      type: 'boolean',
      default: false
    }
  },
  additionalProperties: false
}

Usage Example:

// ❌ Invalid: missing key props
const items = ['a', 'b', 'c'];
<div>
  {items.map(item => <span>{item}</span>)} // Error: missing key
</div>

// ✅ Valid: proper key props
<div>
  {items.map((item, index) => <span key={index}>{item}</span>)}
</div>

JSX Image

Enforces width and height attributes for img elements to prevent layout shifts.

/**
 * Enforces width and height attributes for img elements
 * Prevents layout shifts by requiring dimensions for performance
 */
jsxImg: Rule;

Rule Configuration:

  • Type: problem rule
  • Category: JSX
  • Recommended: warn level
  • Strict: error level

Usage Example:

// ❌ Invalid: missing dimensions
<img src="/image.jpg" alt="Description" /> // Error: missing width/height

// ✅ Valid: proper dimensions
<img src="/image.jpg" alt="Description" width="300" height="200" />

JSX Anchor

Enforces href attribute for anchor elements for SEO optimization.

/**
 * Enforces href attribute for anchor elements for SEO
 * Ensures proper link semantics for search engine optimization
 */
jsxAtag: Rule;

Rule Configuration:

  • Type: problem rule
  • Category: JSX
  • Recommended: warn level
  • Strict: error level

Usage Example:

// ❌ Invalid: missing href
<a onClick$={() => navigate('/page')}>Link</a> // Error: missing href

// ✅ Valid: proper href attribute
<a href="/page" onClick$={() => navigate('/page')}>Link</a>

JSX No Script URL

Disallows javascript: URLs in JSX attributes for security.

/**
 * Disallows javascript: URLs in JSX attributes
 * Prevents potential security vulnerabilities from inline JavaScript
 */
jsxNoScriptUrl: Rule;

Rule Configuration:

  • Type: problem rule
  • Category: JSX
  • Recommended: warn level
  • Strict: error level

Usage Example:

// ❌ Invalid: javascript: URL
<a href="javascript:alert('xss')">Click</a> // Error: javascript: URL not allowed

// ✅ Valid: proper URL or event handler
<a href="/page" onClick$={() => alert('safe')}>Click</a>

JSX Best Practices

Performance Optimization

Image Loading:

  • Always provide width and height attributes for images
  • Prevents Cumulative Layout Shift (CLS) issues
  • Improves Core Web Vitals scoring

List Rendering:

  • Use unique key props for array items
  • Enables efficient re-rendering and DOM reconciliation
  • Improves application performance with dynamic lists

SEO Optimization

Link Semantics:

  • Always provide href attributes for anchor tags
  • Ensures proper crawling by search engines
  • Maintains accessibility for screen readers and keyboard navigation

Security Considerations

Script URL Prevention:

  • Avoid javascript: URLs in href attributes
  • Prevents potential XSS vulnerabilities
  • Use proper event handlers instead of inline JavaScript

React Migration

Prop Name Conversion: The plugin helps migrate from React by detecting and fixing React-specific prop names:

React PropQwik PropUsage
classNameclassCSS class assignment
htmlForforLabel association

Migration Example:

// React style (invalid in Qwik)
<label className="field-label" htmlFor="username">
  Username
</label>

// Qwik style (valid)
<label class="field-label" for="username">
  Username
</label>

Rule Examples Integration

The JSX rules integrate with the plugin's example system for documentation generation:

// Example type definitions for rule documentation
interface QwikEslintExample {
  code: string;
  codeTitle?: string;
  codeHighlight?: string;
  description?: string;
}

interface QwikEslintExamples {
  [scenario: string]: {
    good?: QwikEslintExample[];
    bad?: QwikEslintExample[];
  };
}

// Available examples (exported from examples.ts)
const noReactPropsExamples: QwikEslintExamples;
const jsxNoScriptUrlExamples: QwikEslintExamples;
const jsxKeyExamples: QwikEslintExamples;
const jsxImgExamples: QwikEslintExamples;

Types

// JSX rule definitions (standardized to TSESLint)
type Rule = TSESLint.RuleModule<any, any>;

// DOM element validation
type DOMElementNames = 'div' | 'span' | 'img' | 'a' | 'label' | 'input' | 'button' | /* ... */;

// JSX attribute types
interface JSXAttribute {
  type: 'JSXAttribute';
  name: JSXIdentifier | JSXNamespacedName;
  value: JSXExpressionContainer | Literal | null;
}

interface JSXIdentifier {
  type: 'JSXIdentifier';
  name: string;
}

// Example system types
interface QwikEslintExample {
  code: string;
  codeTitle?: string;
  codeHighlight?: string;
  description?: string;
}

interface QwikEslintExamples {
  [scenario: string]: {
    good?: QwikEslintExample[];
    bad?: QwikEslintExample[];
  };
}